summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles2/shaders/scene.glsl75
-rw-r--r--drivers/gles3/shaders/scene.glsl7
2 files changed, 56 insertions, 26 deletions
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index b1a668cc07..f84f3367f8 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -934,6 +934,7 @@ varying highp float dp_clip;
// E. Heitz, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", J. Comp. Graph. Tech. 3 (2) (2014).
// Eqns 71-72 and 85-86 (see also Eqns 43 and 80).
+/*
float G_GGX_2cos(float cos_theta_m, float alpha) {
// Schlick's approximation
// C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994)
@@ -946,6 +947,15 @@ float G_GGX_2cos(float cos_theta_m, float alpha) {
// float sin2 = (1.0 - cos2);
// return 1.0 / (cos_theta_m + sqrt(cos2 + alpha * alpha * sin2));
}
+*/
+
+// This approximates G_GGX_2cos(cos_theta_l, alpha) * G_GGX_2cos(cos_theta_v, alpha)
+// See Filament docs, Specular G section.
+float V_GGX(float cos_theta_l, float cos_theta_v, float alpha) {
+ float v = cos_theta_l * (cos_theta_v * (1.0 - alpha) + alpha);
+ float l = cos_theta_v * (cos_theta_l * (1.0 - alpha) + alpha);
+ return 0.5 / (v + l);
+}
float D_GGX(float cos_theta_m, float alpha) {
float alpha2 = alpha * alpha;
@@ -953,6 +963,7 @@ float D_GGX(float cos_theta_m, float alpha) {
return alpha2 / (M_PI * d * d);
}
+/*
float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
float cos2 = cos_theta_m * cos_theta_m;
float sin2 = (1.0 - cos2);
@@ -960,14 +971,30 @@ float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, fl
float s_y = alpha_y * sin_phi;
return 1.0 / max(cos_theta_m + sqrt(cos2 + (s_x * s_x + s_y * s_y) * sin2), 0.001);
}
+*/
-float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
- float cos2 = cos_theta_m * cos_theta_m;
+// This approximates G_GGX_anisotropic_2cos(cos_theta_l, ...) * G_GGX_anisotropic_2cos(cos_theta_v, ...)
+// See Filament docs, Anisotropic specular BRDF section.
+float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) {
+ float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV));
+ float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL));
+ return 0.5 / (Lambda_V + Lambda_L);
+}
+
+float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi, float NdotH) {
+ float alpha2 = alpha_x * alpha_y;
+ highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * NdotH);
+ highp float v2 = dot(v, v);
+ float w2 = alpha2 / v2;
+ float D = alpha2 * w2 * w2 * (1.0 / M_PI);
+ return D;
+
+ /* float cos2 = cos_theta_m * cos_theta_m;
float sin2 = (1.0 - cos2);
float r_x = cos_phi / alpha_x;
float r_y = sin_phi / alpha_y;
float d = cos2 + sin2 * (r_x * r_x + r_y * r_y);
- return 1.0 / max(M_PI * alpha_x * alpha_y * d * d, 0.001);
+ return 1.0 / max(M_PI * alpha_x * alpha_y * d * d, 0.001); */
}
float SchlickFresnel(float u) {
@@ -1113,7 +1140,11 @@ LIGHT_SHADER_CODE
if (roughness > 0.0) {
- // D
+#if defined(SPECULAR_SCHLICK_GGX)
+ vec3 specular_brdf_NL = vec3(0.0);
+#else
+ float specular_brdf_NL = 0.0;
+#endif
#if defined(SPECULAR_BLINN)
@@ -1125,7 +1156,7 @@ LIGHT_SHADER_CODE
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
float blinn = pow(cNdotH, shininess);
blinn *= (shininess + 8.0) / (8.0 * 3.141592654);
- float specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75);
+ specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75);
#elif defined(SPECULAR_PHONG)
@@ -1134,7 +1165,7 @@ LIGHT_SHADER_CODE
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
float phong = pow(cRdotV, shininess);
phong *= (shininess + 8.0) / (8.0 * 3.141592654);
- float specular_brdf_NL = (phong) / max(4.0 * cNdotV * cNdotL, 0.75);
+ specular_brdf_NL = (phong) / max(4.0 * cNdotV * cNdotL, 0.75);
#elif defined(SPECULAR_TOON)
@@ -1142,11 +1173,10 @@ LIGHT_SHADER_CODE
float RdotV = dot(R, V);
float mid = 1.0 - roughness;
mid *= mid;
- float specular_brdf_NL = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid;
+ specular_brdf_NL = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid;
#elif defined(SPECULAR_DISABLED)
// none..
- float specular_brdf_NL = 0.0;
#elif defined(SPECULAR_SCHLICK_GGX)
// shlick+ggx as default
@@ -1156,28 +1186,28 @@ LIGHT_SHADER_CODE
float cLdotH = max(dot(L, H), 0.0);
#if defined(LIGHT_USE_ANISOTROPY)
-
+ float alpha = roughness * roughness;
float aspect = sqrt(1.0 - anisotropy * 0.9);
- float rx = roughness / aspect;
- float ry = roughness * aspect;
- float ax = rx * rx;
- float ay = ry * ry;
- float XdotH = dot(T, H);
- float YdotH = dot(B, H);
- float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH);
- float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
+ float ax = alpha / aspect;
+ float ay = alpha * aspect;
+ //float XdotH = dot(T, H);
+ //float YdotH = dot(B, H);
+ float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH, cNdotH);
+ //float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
+ float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL))
#else
float alpha = roughness * roughness;
float D = D_GGX(cNdotH, alpha);
- float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
+ //float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
+ float G = V_GGX(cNdotL, cNdotV, alpha);
#endif
// F
vec3 f0 = F0(metallic, specular, diffuse_color);
float cLdotH5 = SchlickFresnel(cLdotH);
vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);
- vec3 specular_brdf_NL = cNdotL * D * F * G;
+ specular_brdf_NL = cNdotL * D * F * G;
#endif
@@ -1196,11 +1226,12 @@ LIGHT_SHADER_CODE
#endif
float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss));
float Fr = mix(.04, 1.0, cLdotH5);
- float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25);
+ //float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25);
+ float Gr = V_GGX(cNdotL, cNdotV, 0.25);
- float specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
+ float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
- specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
+ specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
}
#endif
}
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index a94558a58a..598bd3465e 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -1070,11 +1070,10 @@ LIGHT_SHADER_CODE
#if defined(LIGHT_USE_ANISOTROPY)
+ float alpha = roughness * roughness;
float aspect = sqrt(1.0 - anisotropy * 0.9);
- float rx = roughness / aspect;
- float ry = roughness * aspect;
- float ax = rx * rx;
- float ay = ry * ry;
+ float ax = alpha / aspect;
+ float ay = alpha * aspect;
float XdotH = dot(T, H);
float YdotH = dot(B, H);
float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH);