Tatooine
cook_torrance_brdf_shader.h
Go to the documentation of this file.
1#ifndef TATOOINE_RENDERING_INTERACTIVE_COOK_TORRANCE_BRDF_SHADER_H
2#define TATOOINE_RENDERING_INTERACTIVE_COOK_TORRANCE_BRDF_SHADER_H
3//==============================================================================
5//==============================================================================
7//==============================================================================
10 static constexpr std::string_view vertex_shader_source =
11 "#version 330 core\n"
12 "in vec3 position; // input vertex position from mesh\n"
13 "in vec3 normal; // input vertex normal from mesh\n"
14 "in float scalar; // scalar per vertex\n"
15 "\n"
16 "uniform mat4 view_matrix; //camera look at matrix\n"
17 "uniform mat4 projection_matrix; //camera projection matrix\n"
18 "uniform mat4 model_matrix; // mesh transformation\n"
19 "uniform mat4 normal_matrix; // transposed inverse of model_matrix\n"
20 "\n"
21 "out vec3 wfn; // output fragment normal of vertex in world space\n"
22 "out vec3 view_vert_pos; // output 3D position in view space\n"
23 "out float interp_scalar;\n"
24 "\n"
25 "void main(){\n"
26 " wfn = (view_matrix * normal_matrix * vec4(normal, 0)).xyz;\n"
27 " vec4 view_vert_pos4 = view_matrix * model_matrix * vec4(position, 1.0);\n"
28 " view_vert_pos = vec3(view_vert_pos4) / view_vert_pos4.w;\n"
29 " interp_scalar = scalar;\n"
30 " gl_Position = projection_matrix * view_vert_pos4;\n"
31 "}\n";
32 //============================================================================
33 static constexpr std::string_view fragment_shader_source =
34 "#version 330 core\n"
35 "out vec4 out_color;\n"
36 "\n"
37 "in vec3 wfn; // fragment normal of pixel in world space (interpolated)\n"
38 "in vec3 view_vert_pos; // fragment vertex position in view space\n"
39 " // (interpolated)\n"
40 "in float interp_scalar;\n"
41 "\n"
42 "uniform int lighting_enabled;\n"
43 "uniform vec3 solid_base_color; // albedo for dielectrics or F0 for\n"
44 " // metals\n"
45 "uniform float roughness;\n"
46 "uniform float metallic; // metallic parameter, 0.0 for dielectrics,\n"
47 " // 1.0 for metals\n"
48 "uniform float reflectance; // Fresnel reflectance for dielectrics in\n"
49 " // the range [0.0, 1.0]\n"
50 "uniform vec4 light_color; // color of light\n"
51 "uniform float irradi_perp; // irradiance in perpendicular direction\n"
52 "uniform sampler1D color_scale;\n"
53 "uniform float min_scalar;\n"
54 "uniform float max_scalar;\n"
55 "uniform int invert_scale;\n"
56 "uniform int use_solid_base_color;\n"
57 "\n"
58 "vec3 rgb2lin(vec3 rgb) { // sRGB to linear approximation\n"
59 " return pow(rgb, vec3(2.2));\n"
60 "}\n"
61 "\n"
62 "vec3 lin2rgb(vec3 lin) { // linear to sRGB approximation\n"
63 " return pow(lin, vec3(1.0 / 2.2));\n"
64 "}\n"
65 "\n"
66 "#define RECIPROCAL_PI 0.3183098861837907\n"
67 "#define RECIPROCAL_2PI 0.15915494309189535\n"
68 "\n"
69 "float roughness_to_shininess( const in float roughness ) {\n"
70 " return pow(1000.0, 1.0-roughness);\n"
71 "}\n"
72 "\n"
73 "vec3 fresnel_schlick(float cos_theta, vec3 F0) {\n"
74 " return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0);\n"
75 "}\n"
76 "\n"
77 "float fresnel_schlick90(float cos_theta, float F0, float F90) {\n"
78 " return F0 + (F90 - F0) * pow(1.0 - cos_theta, 5.0);\n"
79 "} \n"
80 "\n"
81 "float D_GGX(float NoH, float roughness) {\n"
82 " float alpha = roughness * roughness;\n"
83 " float alpha2 = alpha * alpha;\n"
84 " float NoH2 = NoH * NoH;\n"
85 " float b = (NoH2 * (alpha2 - 1.0) + 1.0);\n"
86 " return alpha2 * RECIPROCAL_PI / (b * b);\n"
87 "}\n"
88 "\n"
89 "float G1_GGX_Schlick(float NoV, float roughness) {\n"
90 " float alpha = roughness * roughness;\n"
91 " float k = alpha / 2.0;\n"
92 " return max(NoV, 0.001) / (NoV * (1.0 - k) + k);\n"
93 "}\n"
94 "\n"
95 "float G_Smith(float NoV, float NoL, float roughness) {\n"
96 " return G1_GGX_Schlick(NoL, roughness) *\n"
97 " G1_GGX_Schlick(NoV, roughness);\n"
98 "}\n"
99 "\n"
100 "float disney_diffuse_factor(float NoV, float NoL,\n"
101 " float VoH, float roughness) {\n"
102 " float alpha = roughness * roughness;\n"
103 " float F90 = 0.5 + 2.0 * alpha * VoH * VoH;\n"
104 " float F_in = fresnel_schlick90(NoL, 1.0, F90);\n"
105 " float F_out = fresnel_schlick90(NoV, 1.0, F90);\n"
106 " return F_in * F_out;\n"
107 "}\n"
108 "\n"
109 "vec3 brdf_microfacet(in vec3 L, in vec3 V, in vec3 N,\n"
110 " in float metallic, in float roughness,\n"
111 " in vec3 base_color, in float reflectance) {\n"
112 " vec3 H = normalize(V + L);\n"
113 " \n"
114 " float NoV = clamp(dot(N, V), 0.0, 1.0);\n"
115 " float NoL = clamp(abs(dot(N, L)), 0.0, 1.0);\n"
116 " float NoH = clamp(dot(N, H), 0.0, 1.0);\n"
117 " float VoH = clamp(dot(V, H), 0.0, 1.0);\n"
118 " \n"
119 " vec3 f0 = vec3(0.16 * (reflectance * reflectance));\n"
120 " f0 = mix(f0, base_color, metallic);\n"
121 " \n"
122 " vec3 F = fresnel_schlick(VoH, f0);\n"
123 " float D = D_GGX(NoH, roughness);\n"
124 " float G = G_Smith(NoV, NoL, roughness);\n"
125 " \n"
126 " vec3 spec = (F * D * G) / (4.0 * max(NoV, 0.001) * max(NoL, 0.001));\n"
127 " \n"
128 " vec3 rhoD = base_color;\n"
129 " \n"
130 " // optionally\n"
131 " rhoD *= vec3(1.0) - F;\n"
132 " //rhoD *= disney_diffuse_factor(NoV, NoL, VoH, roughness);\n"
133 " \n"
134 " rhoD *= (1.0 - metallic);\n"
135 " \n"
136 " vec3 diff = rhoD * RECIPROCAL_PI;\n"
137 " \n"
138 " return diff + spec;\n"
139 "}\n"
140 "\n"
141 "void main() {\n"
142 " vec3 base_color = vec3(0,0,0);\n"
143 " if (use_solid_base_color == 1) {\n"
144 " base_color = solid_base_color;\n"
145 " } else {\n"
146 " if (isnan(interp_scalar)) {\n"
147 " base_color = vec3(1,0,0);\n"
148 " } else {\n"
149 " float norm_scalar = clamp((interp_scalar - min_scalar) / (max_scalar - min_scalar), 0, 1);\n"
150 " if (invert_scale == 1) {\n"
151 " norm_scalar = 1 - norm_scalar;\n"
152 " }\n"
153 " base_color = texture(color_scale, norm_scalar).rgb;\n"
154 " }\n"
155 " }\n"
156 " if (lighting_enabled == 0) {\n"
157 " out_color.rgb = base_color;\n"
158 " return;\n"
159 " }"
160 " vec3 light_dir = normalize(- view_vert_pos); // towards light\n"
161 " vec3 view_dir = normalize(-view_vert_pos);\n"
162 " vec3 n = normalize(wfn);\n"
163 " \n"
164 " //vec3 radiance = rgb2lin(emission.rgb);\n"
165 " vec3 radiance = rgb2lin(vec3(0,0,0));\n"
166 " \n"
167 " //float irradiance = max(dot(light_dir, n), 0) * irradi_perp; \n"
168 " float irradiance = abs(dot(light_dir, n)) * irradi_perp; \n"
169 " if(irradiance > 0.0) { // if receives light\n"
170 " vec3 brdf = brdf_microfacet(light_dir, view_dir, n, metallic,\n"
171 " roughness, base_color, reflectance);\n"
172 " // irradiance contribution from directional light\n"
173 " radiance += brdf * irradiance * light_color.rgb;\n"
174 " }\n"
175 "\n"
176 " out_color.rgb = lin2rgb(radiance);\n"
177 " out_color.a = 1.0;\n"
178 "}\n";
179 //============================================================================
181 add_stage<gl::vertexshader>(gl::shadersource{vertex_shader_source});
182 add_stage<gl::fragmentshader>(gl::shadersource{fragment_shader_source});
183 create();
188 set_reflectance(0.5);
189 set_roughness(0.5);
190 set_metallic(0);
192 set_irradi_perp(10);
193 set_uniform("color_scale", 0);
194 set_min(0);
195 set_max(1);
196 invert_scale(false);
197 enable_lighting(true);
198 }
199
200 public:
201 //--------------------------------------------------------------------------
202 static auto get() -> auto& {
203 static auto s = this_type{};
204 return s;
205 }
206 auto set_view_matrix(Mat4<GLfloat> const& V) -> void {
207 set_uniform("view_matrix", V);
208 }
209 auto set_projection_matrix(Mat4<GLfloat> const& P) -> void {
210 set_uniform("projection_matrix", P);
211 }
212 auto set_model_matrix(Mat4<GLfloat> const& M) -> void {
213 set_uniform("model_matrix", M);
214 set_uniform("normal_matrix", Mat4<GLfloat>(transposed(*inv(M))));
215 }
216 auto set_solid_base_color(Vec3<GLfloat> const& b) -> void {
217 set_uniform("solid_base_color", b);
218 }
219 auto set_roughness(GLfloat const r) -> void { set_uniform("roughness", r); }
220 auto set_metallic(GLfloat const m) -> void { set_uniform("metallic", m); }
221 auto set_reflectance(GLfloat const r) -> void {
222 set_uniform("reflectance", r);
223 }
224 auto set_light_color(Vec4<GLfloat> const& l) -> void {
225 set_uniform("light_color", l);
226 }
227 auto set_irradi_perp(GLfloat const i) -> void {
228 set_uniform("irradi_perp", i);
229 }
230 //--------------------------------------------------------------------------
231 auto set_min(GLfloat const min) -> void { set_uniform("min_scalar", min); }
232 auto set_max(GLfloat const max) -> void { set_uniform("max_scalar", max); }
233 //--------------------------------------------------------------------------
234 auto invert_scale(bool const invert) -> void {
235 set_uniform("invert_scale", invert ? 1 : 0);
236 }
237 //--------------------------------------------------------------------------
238 auto use_solid_base_color(bool const use) -> void {
239 set_uniform("use_solid_base_color", use ? 1 : 0);
240 }
241 //--------------------------------------------------------------------------
242 auto enable_lighting(bool const en) -> void {
243 set_uniform("lighting_enabled", en ? 1 : 0);
244 }
245};
246//==============================================================================
247} // namespace tatooine::rendering::interactive
248//==============================================================================
249#endif
Definition: shader.h:24
DLL_API void set_uniform(const std::string &, GLfloat)
DLL_API void create()
Definition: interactive.h:15
constexpr auto inv(diag_static_tensor< Tensor, N, N > const &A) -> std::optional< diag_static_tensor< vec< tatooine::value_type< Tensor >, N >, N, N > >
Definition: diag_tensor.h:109
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
auto transposed(dynamic_tensor auto &&t)
Definition: transposed_tensor.h:170
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
Definition: shadersource.h:8
Definition: mat.h:14
Definition: cook_torrance_brdf_shader.h:8
auto set_roughness(GLfloat const r) -> void
Definition: cook_torrance_brdf_shader.h:219
auto set_irradi_perp(GLfloat const i) -> void
Definition: cook_torrance_brdf_shader.h:227
auto invert_scale(bool const invert) -> void
Definition: cook_torrance_brdf_shader.h:234
auto set_projection_matrix(Mat4< GLfloat > const &P) -> void
Definition: cook_torrance_brdf_shader.h:209
static auto get() -> auto &
Definition: cook_torrance_brdf_shader.h:202
auto set_metallic(GLfloat const m) -> void
Definition: cook_torrance_brdf_shader.h:220
auto set_view_matrix(Mat4< GLfloat > const &V) -> void
Definition: cook_torrance_brdf_shader.h:206
auto set_max(GLfloat const max) -> void
Definition: cook_torrance_brdf_shader.h:232
auto set_reflectance(GLfloat const r) -> void
Definition: cook_torrance_brdf_shader.h:221
auto use_solid_base_color(bool const use) -> void
Definition: cook_torrance_brdf_shader.h:238
static constexpr std::string_view fragment_shader_source
Definition: cook_torrance_brdf_shader.h:33
auto set_solid_base_color(Vec3< GLfloat > const &b) -> void
Definition: cook_torrance_brdf_shader.h:216
auto set_min(GLfloat const min) -> void
Definition: cook_torrance_brdf_shader.h:231
cook_torrance_brdf_shader()
Definition: cook_torrance_brdf_shader.h:180
auto set_model_matrix(Mat4< GLfloat > const &M) -> void
Definition: cook_torrance_brdf_shader.h:212
static constexpr std::string_view vertex_shader_source
Definition: cook_torrance_brdf_shader.h:10
auto set_light_color(Vec4< GLfloat > const &l) -> void
Definition: cook_torrance_brdf_shader.h:224
auto enable_lighting(bool const en) -> void
Definition: cook_torrance_brdf_shader.h:242
Definition: vec.h:12