@@ -62,42 +62,6 @@ layout(location = 16) uniform float uMetallic;
6262layout (location = 17 ) uniform sampler2D uFms;
6363#endif
6464
65- //---------------------------------------------------------------------------------------
66- vec3 specularPBR (
67- ShadeInput inputs,
68- vec3 specColor,
69- float roughness,
70- float metallic,
71- float ndl
72- )
73- {
74- vec3 halfV = normalize (inputs.eye + uLightDir);
75- float ndh = max (1e-8 ,dot (inputs.normal, halfV));
76-
77- float F = fresnelSchlick (inputs.ndv);
78- float NDF = GGX_NDF (ndh, roughness);
79- float G = GeometrySmithGGX (vec2 (inputs.ndv, ndl), roughness);
80- float specBRDF = F*G*NDF / 4.0 ;
81-
82- return mix (specColor, vec3 (1.0 ), specBRDF);
83- }
84-
85- //---------------------------------------------------------------------------------------
86- vec3 directLightPBR (
87- ShadeInput inputs,
88- vec3 diffColor,
89- vec3 specColor,
90- float roughness,
91- float metallic
92- )
93- {
94- float ndl = max (0.0 ,dot (inputs.normal,uLightDir));
95- vec3 diffuse = diffColor * ((1.0 -metallic) * INV_PI);
96- vec3 specular = specularPBR (inputs, specColor, roughness, metallic, ndl);
97-
98- //return (specular) * ndl * uLightColor;
99- return (diffuse + specular) * ndl * uLightColor;
100- }
10165
10266//---------------------------------------------------------------------------------------
10367const vec2 invAtan = vec2 (0.1591 , 0.3183 );
@@ -174,13 +138,13 @@ vec3 specularIBL(
174138 vec3 specColor,
175139 float roughness,
176140 float occlusion,
177- float ndv)
141+ float ndv,
142+ vec3 Fmsfms)
178143{
179144 vec3 radiance = vec3 (0.0 );
180145 float glossiness = 1.0 - roughness;
181146 vec3 fmsA = vec3 (0.592665 , -1.47034 , 1.47196 );
182- float r3 = roughness*roughness*roughness;
183- float fmsAvg = fmsA.x*r3 / (1 +fmsA.y*roughness+fmsA.z*roughness*roughness);
147+ float alpha = roughness*roughness;
184148
185149 for (int i=0 ; i<nbSamples; ++i)
186150 {
@@ -193,19 +157,15 @@ vec3 specularIBL(
193157 float vdh = max (1e-8 , dot (vectors.eye, Hn));
194158 float ndh = max (1e-8 , dot (vectors.normal, Hn));
195159 float lodS = roughness < 0.01 ? 0.0 : computeLOD (Ln, probabilityGGX (ndh, vdh, roughness));
196- #ifdef sampler2D_uEnvironment
160+ #if defined ( sampler2D_uEnvironment) && ! defined (Furnace)
197161 vec3 env = textureLod (uEnvironment, sampleSpherical (Ln), lodS ).xyz;
198162#else
199163 vec3 env = gradient3d (Ln);
200164#endif
201- float emsV = textureLod (uFms, vec2 (ndv, roughness), 0 ).x;
202- float emsL = textureLod (uFms, vec2 (ndl, roughness), 0 ).x;
203- float fms = 0.0 ;
204- fms = emsV*emsL/fmsAvg;
205-
206- radiance += env * fresnel (vdh,specColor) *
207- (cook_torrance_contrib (vdh, ndh, ndl, ndv, roughness)
208- + fms);
165+
166+ radiance += env * (fresnel (vdh,specColor) *
167+ cook_torrance_contrib (vdh, ndh, ndl, ndv, roughness)
168+ + Fmsfms);
209169 }
210170 // Remove occlusions on shiny reflections
211171 radiance *= mix (occlusion, 1.0 , glossiness * glossiness) / float (nbSamples);
@@ -216,7 +176,7 @@ vec3 specularIBL(
216176//---------------------------------------------------------------------------------------
217177vec3 diffuseIBL (ShadeInput inputs, vec3 diffColor, float occlusion)
218178{
219- #ifdef sampler2D_uIrradiance
179+ #if defined ( sampler2D_uIrradiance) && ! defined (Furnace)
220180 return diffColor * textureLod (uIrradiance, sampleSpherical (inputs.normal), 0.0 ).xyz * occlusion;
221181#else
222182 return diffColor * gradient3d (inputs.normal) * occlusion;
@@ -226,34 +186,6 @@ vec3 diffuseIBL(ShadeInput inputs, vec3 diffColor, float occlusion)
226186}
227187
228188//---------------------------------------------------------------------------------------
229- vec3 indirectLightPBR (
230- ShadeInput inputs,
231- vec3 diffColor,
232- vec3 specColor,
233- float roughness,
234- float occlusion
235- //float shadow
236- )
237- {
238- LocalVectors vectors;
239- vectors.eye = inputs.eye;
240- #ifdef VTX_TANGENT_SPACE
241- vectors.tangent = inputs.tangent;
242- vectors.bitangent = inputs.bitangent;
243- #else
244- // Construct a local orthonormal base
245- vec3 tangent = inputs.normal.zxy;
246- tangent = tangent - dot (tangent, inputs.normal) * inputs.normal;
247- vectors.tangent = normalize (tangent);
248- vectors.bitangent = cross (inputs.normal, vectors.tangent);
249- #endif
250- vectors.normal = inputs.normal;
251- vec3 specular = specularIBL (vectors, specColor, roughness, occlusion, inputs.ndv);// * shadow;
252- vec3 diffuse = diffuseIBL (inputs, diffColor, occlusion);
253-
254- return specular + diffuse;
255- }
256-
257189vec4 getBaseColor ()
258190{
259191#if defined (sampler2D_uBaseColorMap) && defined (vec4_uBaseColor)
@@ -262,6 +194,7 @@ vec4 getBaseColor()
262194#else
263195 #if defined (sampler2D_uBaseColorMap)
264196 vec4 baseColor = texture (uBaseColorMap, vTexCoord);
197+ baseColor = vec4 (pow (baseColor.r, 2.2 ), pow (baseColor.g, 2.2 ), pow (baseColor.b, 2.2 ), baseColor.a);
265198 #else
266199 #if defined (vec4_uBaseColor)
267200 vec4 baseColor = uBaseColor;
@@ -280,7 +213,7 @@ vec4 shadeSurface(ShadeInput inputs)
280213
281214#ifdef sampler2D_uPhysics
282215 vec3 physics = texture (uPhysics, vTexCoord).xyz;
283- float roughness = max ( 0.01 , physics.g) ;
216+ float roughness = physics.g;
284217 float metallic = physics.b;
285218 float occlusion = 1.0 ;//physics.r;
286219#else
@@ -292,7 +225,7 @@ vec4 shadeSurface(ShadeInput inputs)
292225 #if defined (float_uMetallic)
293226 float metallic = uMetallic;
294227 #else
295- float metallic = 0.1 ;
228+ float metallic = 1.0 ;
296229 #endif
297230 float occlusion = 1.0 ;
298231#endif
@@ -311,7 +244,6 @@ vec4 shadeSurface(ShadeInput inputs)
311244
312245#ifdef Furnace
313246 occlusion = 1.0 ;
314- baseColor = vec4 (1.0 );
315247 shadowMask = 1.0 ;
316248#endif
317249 if (baseColor.a < 0.5 )
@@ -336,8 +268,7 @@ vec4 shadeSurface(ShadeInput inputs)
336268 float ndh = max (1e-8 , dot (inputs.normal, h));
337269 float ndh2 = ndh*ndh;
338270 float ggxDen = (ndh2 * (a2-1 ) + 1 );
339- // Missing 1/pi because it's applied at the end to both diffuse and specular
340- float ggx = a2 / (ggxDen*ggxDen);
271+ float ggx = a2 * INV_PI / (ggxDen*ggxDen);
341272
342273 float ndl = max (0.0 , -dot (uLightDir, inputs.normal));
343274
@@ -348,51 +279,54 @@ vec4 shadeSurface(ShadeInput inputs)
348279
349280 float sbrdf = ggx / g2; // Pure mirror brdf
350281 float emsV = textureLod (uFms, vec2 (inputs.ndv, roughness), 0 ).x;
351- //emsV = texture(uFms, vec2(inputs.ndv, roughness)).x;
352282 float emsL = textureLod (uFms, vec2 (ndl, roughness), 0 ).x;
353- //emsL = texture(uFms, vec2(ndl, roughness)).x;
354283 vec3 fmsA = vec3 (0.592665 , -1.47034 , 1.47196 );
355284 float r3 = alpha*roughness;
356- float fmsAvg = fmsA.x*r3 / (1 +fmsA.y*roughness+fmsA.z*alpha);
357- //float fms = roughness;
358- float fms = emsV*emsL/fmsAvg;
359- vec3 specular = Fs * (sbrdf + fms); // complete specular brdf
285+ float OneMinEavg = (roughness == 0 ) ? 0.0 : fmsA.x*r3 / (1 +fmsA.y*roughness+fmsA.z*alpha);
286+ float Eavg = 1 -OneMinEavg;
287+ float fms = emsV*emsL/max (0.01 , OneMinEavg);
288+ fms = 0.0 ;
289+ vec3 Favg = (13 +8 *F0)/42 ;
290+ vec3 Fms = Favg*Favg*Eavg / (1 -Favg*OneMinEavg);
291+ vec3 directSpecular = Fs * sbrdf;// + Fms * fms; // complete specular brdf
292+ //directSpecular = vec3(0.0);
360293
361294 // Single bounce diffuse
362295 vec3 albedo = baseColor.xyz * (1 -metallic);
363- //vec3 Kd = (vec3(1.0) - fresnel(ndl, F0)) * INV_PI; // Approximate fresnel with reflectance of perfectly smooth surface
364- // Single bounce diffuse with analytical solution
365- // Missing 1/pi because it's applied at the end to both diffuse and specular, and should be premultiplied in emissive
366- float ff = 1.05 * (1 -pow (1 -inputs.ndv,5 )); // Fresnel radiance correction
367- //vec3 smoothTerm = ff * (1-pow(1-ndl, 5))*(1-F0);
368- // Multiple bounce diffuse (WIP)
369- //float facing = 0.5 - 0.5*dot(uLightDir, inputs.eye);
370- //float roughTerm = facing*(0.9-0.4*facing)*(0.5+ndh)/ndh;
371- // float smoothTerm = 1.05*(1-pow(1-ndl, 5))*(1-pow(1-inputs.ndv,5));
372- //vec3 single = mix(smoothTerm, vec3(roughTerm), alpha);
373- //float multi = 0.1159*alpha;
374- // vec3 diffuse = albedo * (single + albedo * multi);
375- vec3 diffuse = albedo * ff;
376-
377- vec3 indirect = indirectLightPBR (
378- inputs,
379- albedo,
380- F0,
381- roughness,
382- occlusion
383- );
384-
385- // Complete brdf
386- vec3 direct = uLightColor * (specular + diffuse) * ndl;
387- //indirect = vec3(0.0);
388-
296+ float ff = 1.05 * INV_PI * (1 -pow (1 -inputs.ndv,5 )); // Fresnel radiance correction
389297#if defined (sampler2D_uEmissive) && !defined (Furnace)
390298 vec3 emissive = texture (uEmissive, vTexCoord).xyz;
391- vec3 color = indirect + (shadowMask * direct)* INV_PI + ff * emissive;
299+ vec3 directDiffuse = (uLightColor * albedo +emissive) * ff;
300+ #else
301+ vec3 directDiffuse = uLightColor * albedo * ff;
302+ #endif
303+
304+ // -------- Indirect
305+ LocalVectors vectors;
306+ vectors.eye = inputs.eye;
307+ #ifdef VTX_TANGENT_SPACE
308+ vectors.tangent = inputs.tangent;
309+ vectors.bitangent = inputs.bitangent;
392310#else
393- vec3 color = indirect + (shadowMask * direct) * INV_PI;
311+ // Construct a local orthonormal base
312+ vec3 tangent = inputs.normal.zxy;
313+ tangent = tangent - dot (tangent, inputs.normal) * inputs.normal;
314+ vectors.tangent = normalize (tangent);
315+ vectors.bitangent = cross (inputs.normal, vectors.tangent);
394316#endif
395- //color = diffuse;
317+ vectors.normal = inputs.normal;
318+ vec3 indirectSpecular = specularIBL (vectors, F0, max (0.001 ,roughness), occlusion, inputs.ndv, Fms*fms);
319+ vec3 indirectDiffuse = diffuseIBL (inputs, albedo, occlusion);
320+
321+ vec3 indirect = indirectSpecular + indirectDiffuse;
322+
323+ #ifdef Furnace
324+ ndl = 0.0 ;
325+ #endif
326+ vec3 diffuse = directDiffuse * shadowMask * ndl + indirectDiffuse;
327+ vec3 specular = (0.0 *uLightColor * directSpecular * ndl + indirectSpecular);
328+
329+ vec3 color = diffuse + specular;
396330 return vec4 (color, baseColor.a);
397331}
398332
0 commit comments