summaryrefslogtreecommitdiff
path: root/drivers/gles3/shaders/scene.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/shaders/scene.glsl')
-rw-r--r--drivers/gles3/shaders/scene.glsl29
1 files changed, 16 insertions, 13 deletions
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index b6fb69a2aa..41d5ef5bc9 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -1,5 +1,6 @@
[vertex]
+#define M_PI 3.14159265359
/*
from VisualServer:
@@ -166,7 +167,7 @@ out vec4 specular_light_interp;
void light_compute(vec3 N, vec3 L,vec3 V, vec3 light_color,float roughness,inout vec3 diffuse, inout vec3 specular) {
float dotNL = max(dot(N,L), 0.0 );
- diffuse += dotNL * light_color;
+ diffuse += dotNL * light_color / M_PI;
if (roughness > 0.0) {
@@ -589,7 +590,7 @@ vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) {
norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25);
// we need to lie the derivatives (normg) and assume that DP side is always the same
- // to get proper texure filtering
+ // to get proper texture filtering
vec2 normg=norm.xy;
if (norm.z>0.0) {
norm.y=0.5-norm.y+0.5;
@@ -920,6 +921,7 @@ LIGHT_SHADER_CODE
#elif defined(DIFFUSE_OREN_NAYAR)
{
+ // see http://mimosa-pudica.net/improved-oren-nayar.html
float LdotV = dot(L, V);
float NdotL = dot(L, N);
float NdotV = dot(N, V);
@@ -928,10 +930,10 @@ LIGHT_SHADER_CODE
float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
float sigma2 = roughness * roughness;
- vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33));
+ vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) );
float B = 0.45 * sigma2 / (sigma2 + 0.09);
- light_amount = max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
+ light_amount = dotNL * (A + vec3(B) * s / t) / M_PI;
}
#elif defined(DIFFUSE_TOON)
@@ -951,7 +953,7 @@ LIGHT_SHADER_CODE
float FD90 = 0.5 + 2.0 * LoH * LoH * roughness;
float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(NoV);
float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(NoL);
- light_amount = ( (1.0 / M_PI) * FdV * FdL );
+ light_amount = ( (1.0 / M_PI) * FdV * FdL ) * NoL;
/*
float energyBias = mix(roughness, 0.0, 0.5);
float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
@@ -964,11 +966,11 @@ LIGHT_SHADER_CODE
}
#else
//lambert
- light_amount = dotNL;
+ light_amount = dotNL / M_PI;
#endif
#if defined(TRANSMISSION_USED)
- diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission) * attenuation;
+ diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(M_PI),transmission) * attenuation;
#else
diffuse += light_color * diffuse_color * light_amount * attenuation;
#endif
@@ -1943,18 +1945,19 @@ FRAGMENT_SHADER_CODE
//simplify for toon, as
specular_light *= specular * metallic * albedo * 2.0;
#else
- //brdf approximation (Lazarov 2013)
- float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
- vec3 dielectric = vec3(0.034) * specular * 2.0;
//energy conservation
- vec3 f0 = mix(dielectric, albedo, metallic);
+ vec3 dielectric = vec3(0.034) * specular * 2.0;
+ vec3 specular_color = mix(dielectric, albedo, metallic);
+ // Environment brdf approximation (Lazarov 2013)
+ // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04);
vec4 r = roughness * c0 + c1;
+ float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
float a004 = min( r.x * r.x, exp2( -9.28 * ndotv ) ) * r.x + r.y;
- vec2 brdf = vec2( -1.04, 1.04 ) * a004 + r.zw;
+ vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
- specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
+ specular_light *= AB.x * specular_color + AB.y;
#endif
}