summaryrefslogtreecommitdiff
path: root/src/renderergl2/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderergl2/glsl')
-rw-r--r--src/renderergl2/glsl/calclevels4x_fp.glsl4
-rw-r--r--src/renderergl2/glsl/depthblur_fp.glsl76
-rw-r--r--src/renderergl2/glsl/depthblur_vp.glsl6
-rw-r--r--src/renderergl2/glsl/lightall_fp.glsl342
-rw-r--r--src/renderergl2/glsl/lightall_vp.glsl21
-rw-r--r--src/renderergl2/glsl/ssao_fp.glsl54
-rw-r--r--src/renderergl2/glsl/tonemap_fp.glsl11
7 files changed, 192 insertions, 322 deletions
diff --git a/src/renderergl2/glsl/calclevels4x_fp.glsl b/src/renderergl2/glsl/calclevels4x_fp.glsl
index 1de59e9f..8246c4b3 100644
--- a/src/renderergl2/glsl/calclevels4x_fp.glsl
+++ b/src/renderergl2/glsl/calclevels4x_fp.glsl
@@ -14,8 +14,8 @@ vec3 GetValues(vec2 offset, vec3 current)
#ifdef FIRST_PASS
- #if defined(r_framebufferGamma)
- minAvgMax = pow(minAvgMax, vec3(r_framebufferGamma));
+ #if defined(USE_PBR)
+ minAvgMax *= minAvgMax;
#endif
float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001);
diff --git a/src/renderergl2/glsl/depthblur_fp.glsl b/src/renderergl2/glsl/depthblur_fp.glsl
index 93895b4e..d71b3487 100644
--- a/src/renderergl2/glsl/depthblur_fp.glsl
+++ b/src/renderergl2/glsl/depthblur_fp.glsl
@@ -1,58 +1,82 @@
uniform sampler2D u_ScreenImageMap;
uniform sampler2D u_ScreenDepthMap;
-uniform vec4 u_ViewInfo; // zfar / znear, zfar
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
varying vec2 var_ScreenTex;
+//float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06);
//float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033);
float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044);
//float gauss[3] = float[3](0.60, 0.19, 0.0066);
-#define GAUSS_SIZE 4
+#define BLUR_SIZE 4
+
+#if !defined(USE_DEPTH)
+//#define USE_GAUSS
+#endif
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
- float sampleZDivW = texture2D(depthMap, tex).r;
- return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
-vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar)
+vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale)
{
- float scale = 1.0 / 256.0;
+
+#if defined(USE_DEPTH)
+ float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear);
+ vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
+ scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0);
+#endif
#if defined(USE_HORIZONTAL_BLUR)
- vec2 direction = vec2(1.0, 0.0) * scale;
+ vec2 direction = vec2(scale.x * 2.0, 0.0);
+ vec2 nudge = vec2(0.0, scale.y * 0.5);
#else // if defined(USE_VERTICAL_BLUR)
- vec2 direction = vec2(0.0, 1.0) * scale;
+ vec2 direction = vec2(0.0, scale.y * 2.0);
+ vec2 nudge = vec2(-scale.x * 0.5, 0.0);
#endif
-
- float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
- vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
-
+
+#if defined(USE_GAUSS)
vec4 result = texture2D(imageMap, tex) * gauss[0];
float total = gauss[0];
+#else
+ vec4 result = texture2D(imageMap, tex);
+ float total = 1.0;
+#endif
+ float zLimit = 5.0 / zFar;
int i, j;
for (i = 0; i < 2; i++)
{
- for (j = 1; j < GAUSS_SIZE; j++)
+ for (j = 1; j < BLUR_SIZE; j++)
{
- vec2 offset = direction * j;
- float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
- float depthExpected = depthCenter + dot(centerSlope, offset);
- if(abs(depthSample - depthExpected) < 5.0)
- {
- result += texture2D(imageMap, tex + offset) * gauss[j];
- total += gauss[j];
- }
+ vec2 offset = direction * (float(j) - 0.25) + nudge;
+#if defined(USE_DEPTH)
+ float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
+ float depthExpected = depthCenter + dot(slope, offset);
+ float useSample = float(abs(depthSample - depthExpected) < zLimit);
+#else
+ float useSample = 1.0;
+#endif
+#if defined(USE_GAUSS)
+ result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
+ total += gauss[j] * useSample;
+#else
+ result += texture2D(imageMap, tex + offset) * useSample;
+ total += useSample;
+#endif
+ nudge = -nudge;
}
-
+
direction = -direction;
- }
-
+ nudge = -nudge;
+ }
+
return result / total;
}
void main()
-{
- gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
+{
+ gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw);
}
diff --git a/src/renderergl2/glsl/depthblur_vp.glsl b/src/renderergl2/glsl/depthblur_vp.glsl
index 9c46a79f..9c47660c 100644
--- a/src/renderergl2/glsl/depthblur_vp.glsl
+++ b/src/renderergl2/glsl/depthblur_vp.glsl
@@ -1,12 +1,16 @@
attribute vec4 attr_Position;
attribute vec4 attr_TexCoord0;
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
+
varying vec2 var_ScreenTex;
void main()
{
gl_Position = attr_Position;
- var_ScreenTex = attr_TexCoord0.xy;
+ vec2 wh = vec2(1.0) / u_ViewInfo.zw - vec2(1.0);
+ var_ScreenTex = (floor(attr_TexCoord0.xy * wh) + vec2(0.5)) * u_ViewInfo.zw;
+
//vec2 screenCoords = gl_Position.xy / gl_Position.w;
//var_ScreenTex = screenCoords * 0.5 + 0.5;
}
diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl
index d1182781..64cae3fa 100644
--- a/src/renderergl2/glsl/lightall_fp.glsl
+++ b/src/renderergl2/glsl/lightall_fp.glsl
@@ -29,11 +29,6 @@ uniform samplerCube u_CubeMap;
uniform vec4 u_EnableTextures;
#endif
-#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
-uniform vec3 u_DirectedLight;
-uniform vec3 u_AmbientLight;
-#endif
-
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
uniform vec3 u_PrimaryLightColor;
uniform vec3 u_PrimaryLightAmbient;
@@ -53,6 +48,9 @@ uniform vec4 u_CubeMapInfo;
varying vec4 var_TexCoords;
varying vec4 var_Color;
+#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
+varying vec4 var_ColorAmbient;
+#endif
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
#if defined(USE_VERT_TANGENT_SPACE)
@@ -150,156 +148,35 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)
}
#endif
-vec3 CalcDiffuse(vec3 diffuseAlbedo, vec3 N, vec3 L, vec3 E, float NE, float NL, float shininess)
+vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
{
- #if defined(USE_OREN_NAYAR) || defined(USE_TRIACE_OREN_NAYAR)
- float gamma = dot(E, L) - NE * NL;
- float B = 2.22222 + 0.1 * shininess;
-
- #if defined(USE_OREN_NAYAR)
- float A = 1.0 - 1.0 / (2.0 + 0.33 * shininess);
- gamma = clamp(gamma, 0.0, 1.0);
- #endif
-
- #if defined(USE_TRIACE_OREN_NAYAR)
- float A = 1.0 - 1.0 / (2.0 + 0.65 * shininess);
-
- if (gamma >= 0.0)
- #endif
- {
- B = max(B * max(NL, NE), EPSILON);
- }
-
- return diffuseAlbedo * (A + gamma / B);
- #else
- return diffuseAlbedo;
- #endif
-}
-
-vec3 EnvironmentBRDF(float gloss, float NE, vec3 specular)
-{
- #if 1
- // from http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
- vec4 t = vec4( 1.0/0.96, 0.475, (0.0275 - 0.25 * 0.04)/0.96,0.25 ) * gloss;
- t += vec4( 0.0, 0.0, (0.015 - 0.75 * 0.04)/0.96,0.75 );
- float a0 = t.x * min( t.y, exp2( -9.28 * NE ) ) + t.z;
- float a1 = t.w;
- return clamp( a0 + specular * ( a1 - a0 ), 0.0, 1.0 );
- #elif 0
- // from http://seblagarde.wordpress.com/2011/08/17/hello-world/
- return specular + CalcFresnel(NE) * clamp(vec3(gloss) - specular, 0.0, 1.0);
- #else
- // from http://advances.realtimerendering.com/s2011/Lazarov-Physically-Based-Lighting-in-Black-Ops%20%28Siggraph%202011%20Advances%20in%20Real-Time%20Rendering%20Course%29.pptx
- return mix(specular.rgb, vec3(1.0), CalcFresnel(NE) / (4.0 - 3.0 * gloss));
- #endif
-}
-
-float CalcBlinn(float NH, float shininess)
-{
-#if defined(USE_BLINN) || defined(USE_BLINN_FRESNEL)
- // Normalized Blinn-Phong
- float norm = shininess * 0.125 + 1.0;
-#elif defined(USE_MCAULEY)
- // Cook-Torrance as done by Stephen McAuley
- // http://blog.selfshadow.com/publications/s2012-shading-course/mcauley/s2012_pbs_farcry3_notes_v2.pdf
- float norm = shininess * 0.25 + 0.125;
-#elif defined(USE_GOTANDA)
- // Neumann-Neumann as done by Yoshiharu Gotanda
- // http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf
- float norm = shininess * 0.124858 + 0.269182;
-#elif defined(USE_LAZAROV)
- // Cook-Torrance as done by Dimitar Lazarov
- // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
- float norm = shininess * 0.125 + 0.25;
-#else
- float norm = 1.0;
-#endif
-
-#if 0
- // from http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/
- float a = shininess + 0.775;
- return norm * exp(a * NH - a);
+#if defined(USE_BURLEY)
+ // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
+ float fd90 = -0.5 + EH * EH * roughness;
+ float burley = 1.0 + fd90 * 0.04 / NH;
+ burley *= burley;
+ return diffuseAlbedo * burley;
#else
- return norm * pow(NH, shininess);
-#endif
-}
-
-float CalcGGX(float NH, float gloss)
-{
- // from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
- float a_sq = exp2(gloss * -13.0 + 1.0);
- float d = ((NH * NH) * (a_sq - 1.0) + 1.0);
- return a_sq / (d * d);
-}
-
-float CalcFresnel(float EH)
-{
-#if 1
- // From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
- // not accurate, but fast
- return exp2(-10.0 * EH);
-#elif 0
- // From http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/
- return exp2((-5.55473 * EH - 6.98316) * EH);
-#elif 0
- float blend = 1.0 - EH;
- float blend2 = blend * blend;
- blend *= blend2 * blend2;
-
- return blend;
-#else
- return pow(1.0 - EH, 5.0);
+ return diffuseAlbedo;
#endif
}
-float CalcVisibility(float NH, float NL, float NE, float EH, float gloss)
+vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular)
{
-#if defined(USE_GOTANDA)
- // Neumann-Neumann as done by Yoshiharu Gotanda
- // http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf
- return 1.0 / max(max(NL, NE), EPSILON);
-#elif defined(USE_LAZAROV)
- // Cook-Torrance as done by Dimitar Lazarov
- // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
- float k = min(1.0, gloss + 0.545);
- return 1.0 / (k * (EH * EH - 1.0) + 1.0);
-#elif defined(USE_GGX)
- float roughness = exp2(gloss * -6.5);
-
- // Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
- // NL, NE in numerator factored out from cook-torrance
- float k = roughness + 1.0;
- k *= k * 0.125;
-
- float k2 = 1.0 - k;
-
- float invGeo1 = NL * k2 + k;
- float invGeo2 = NE * k2 + k;
-
- return 1.0 / (invGeo1 * invGeo2);
-#else
- return 1.0;
-#endif
+ // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
+ float v = 1.0 - max(roughness, NE);
+ v *= v * v;
+ return vec3(v) + specular;
}
-
-vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float gloss, float shininess)
+vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness)
{
-#if defined(USE_GGX)
- float distrib = CalcGGX(NH, gloss);
-#else
- float distrib = CalcBlinn(NH, shininess);
-#endif
-
-#if defined(USE_BLINN)
- vec3 fSpecular = specular;
-#else
- vec3 fSpecular = mix(specular, vec3(1.0), CalcFresnel(EH));
-#endif
-
- float vis = CalcVisibility(NH, NL, NE, EH, gloss);
-
- return fSpecular * (distrib * vis);
+ // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
+ float rr = roughness*roughness;
+ float rrrr = rr*rr;
+ float d = (NH * NH) * (rrrr - 1.0) + 1.0;
+ float v = (EH * EH) * (roughness + 0.5);
+ return specular * (rrrr / (4.0 * d * d * v));
}
@@ -341,7 +218,7 @@ mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv )
void main()
{
- vec3 viewDir, lightColor, ambientColor;
+ vec3 viewDir, lightColor, ambientColor, reflectance;
vec3 L, N, E, H;
float NL, NH, NE, EH, attenuation;
@@ -353,21 +230,20 @@ void main()
mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy);
viewDir = var_ViewDir;
#endif
-
E = normalize(viewDir);
-
- L = var_LightDir.xyz;
- #if defined(USE_DELUXEMAP)
- L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
- #endif
- float sqrLightDist = dot(L, L);
#endif
+ lightColor = var_Color.rgb;
+
#if defined(USE_LIGHTMAP)
vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw);
#if defined(RGBM_LIGHTMAP)
lightmapColor.rgb *= lightmapColor.a;
#endif
+ #if defined(USE_PBR) && !defined(USE_FAST_LIGHT)
+ lightmapColor.rgb *= lightmapColor.rgb;
+ #endif
+ lightColor *= lightmapColor.rgb;
#endif
vec2 texCoords = var_TexCoords.xy;
@@ -383,17 +259,16 @@ void main()
vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
- #if defined(USE_LIGHTMAP)
- lightColor = lightmapColor.rgb * var_Color.rgb;
- ambientColor = vec3(0.0);
- attenuation = 1.0;
- #elif defined(USE_LIGHT_VECTOR)
- lightColor = u_DirectedLight * var_Color.rgb;
- ambientColor = u_AmbientLight * var_Color.rgb;
+ L = var_LightDir.xyz;
+ #if defined(USE_DELUXEMAP)
+ L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
+ #endif
+ float sqrLightDist = dot(L, L);
+ L /= sqrt(sqrLightDist);
+
+ #if defined(USE_LIGHT_VECTOR)
attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
- #elif defined(USE_LIGHT_VERTEX)
- lightColor = var_Color.rgb;
- ambientColor = vec3(0.0);
+ #else
attenuation = 1.0;
#endif
@@ -411,33 +286,20 @@ void main()
#endif
N = normalize(N);
- L /= sqrt(sqrLightDist);
#if defined(USE_SHADOWMAP)
vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
// surfaces not facing the light are always shadowed
- shadowValue *= float(dot(var_Normal.xyz, var_PrimaryLightDir.xyz) > 0.0);
+ shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0);
#if defined(SHADOWMAP_MODULATE)
- //vec3 shadowColor = min(u_PrimaryLightAmbient, lightColor);
- vec3 shadowColor = u_PrimaryLightAmbient * lightColor;
-
- #if 0
- // Only shadow when the world light is parallel to the primary light
- shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir.xyz), 0.0, 1.0);
- #endif
- lightColor = mix(shadowColor, lightColor, shadowValue);
+ lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
#endif
#endif
- #if defined(r_lightGamma)
- lightColor = pow(lightColor, vec3(r_lightGamma));
- ambientColor = pow(ambientColor, vec3(r_lightGamma));
- #endif
-
- #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
+ #if !defined(USE_LIGHT_VECTOR)
ambientColor = lightColor;
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
@@ -447,10 +309,10 @@ void main()
// Recover any unused light as ambient, in case attenuation is over 4x or
// light is below the surface
- ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0);
+ ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0));
+ #else
+ ambientColor = var_ColorAmbient.rgb;
#endif
-
- vec3 reflectance;
NL = clamp(dot(N, L), 0.0, 1.0);
NE = clamp(dot(N, E), 0.0, 1.0);
@@ -460,70 +322,47 @@ void main()
#else
vec4 specular = vec4(1.0);
#endif
-
specular *= u_SpecularScale;
- #if defined(r_materialGamma)
- diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma));
- specular.rgb = pow(specular.rgb, vec3(r_materialGamma));
+ #if defined(USE_PBR)
+ diffuse.rgb *= diffuse.rgb;
#endif
+ #if defined(USE_PBR)
+ // diffuse rgb is base color
+ // specular red is gloss
+ // specular green is metallicness
+ float gloss = specular.r;
+ float metal = specular.g;
+ specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal);
+ diffuse.rgb *= 1.0 - metal;
+ #else
+ // diffuse rgb is diffuse
+ // specular rgb is specular reflectance at normal incidence
+ // specular alpha is gloss
float gloss = specular.a;
- float shininess = exp2(gloss * 13.0);
-
- #if defined(SPECULAR_IS_METALLIC)
- // diffuse is actually base color, and red of specular is metallicness
- float metallic = specular.r;
- specular.rgb = (0.96 * metallic) * diffuse.rgb + vec3(0.04);
- diffuse.rgb *= 1.0 - metallic;
- #else
// adjust diffuse by specular reflectance, to maintain energy conservation
diffuse.rgb *= vec3(1.0) - specular.rgb;
#endif
- reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess);
-
- #if defined(r_deluxeSpecular) || defined(USE_LIGHT_VECTOR)
- float adjGloss = gloss;
- float adjShininess = shininess;
-
- #if !defined(USE_LIGHT_VECTOR)
- adjGloss *= r_deluxeSpecular;
- adjShininess = exp2(adjGloss * 13.0);
- #endif
-
- H = normalize(L + E);
-
- EH = clamp(dot(E, H), 0.0, 1.0);
- NH = clamp(dot(N, H), 0.0, 1.0);
-
- #if !defined(USE_LIGHT_VECTOR)
- reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess) * r_deluxeSpecular;
- #else
- reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess);
- #endif
+ #if defined(GLOSS_IS_GLOSS)
+ float roughness = exp2(-3.0 * gloss);
+ #elif defined(GLOSS_IS_SMOOTHNESS)
+ float roughness = 1.0 - gloss;
+ #elif defined(GLOSS_IS_ROUGHNESS)
+ float roughness = gloss;
+ #elif defined(GLOSS_IS_SHININESS)
+ float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25);
#endif
- gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
-
-#if 0
- vec3 aSpecular = EnvironmentBRDF(gloss, NE, specular.rgb);
-
- // do ambient as two hemisphere lights, one straight up one straight down
- float hemiDiffuseUp = N.z * 0.5 + 0.5;
- float hemiDiffuseDown = 1.0 - hemiDiffuseUp;
- float hemiSpecularUp = mix(hemiDiffuseUp, float(N.z >= 0.0), gloss);
- float hemiSpecularDown = 1.0 - hemiSpecularUp;
+ reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness);
- gl_FragColor.rgb += ambientColor * 0.75 * (diffuse.rgb * hemiDiffuseUp + aSpecular * hemiSpecularUp);
- gl_FragColor.rgb += ambientColor * 0.25 * (diffuse.rgb * hemiDiffuseDown + aSpecular * hemiSpecularDown);
-#else
- gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb);
-#endif
+ gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
+ gl_FragColor.rgb += ambientColor * diffuse.rgb;
#if defined(USE_CUBEMAP)
- reflectance = EnvironmentBRDF(gloss, NE, specular.rgb);
+ reflectance = EnvironmentBRDF(roughness, NE, specular.rgb);
vec3 R = reflect(E, N);
@@ -531,15 +370,15 @@ void main()
// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
- vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w;
+ vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w;
// normalize cubemap based on lowest mip (~diffuse)
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
//vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, 6.0).rgb, 0.5 / 255.0);
//cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721));
- #if defined(r_framebufferGamma)
- cubeLightColor = pow(cubeLightColor, vec3(r_framebufferGamma));
+ #if defined(USE_PBR)
+ cubeLightColor *= cubeLightColor;
#endif
// multiply cubemap values by lighting
@@ -549,7 +388,7 @@ void main()
gl_FragColor.rgb += cubeLightColor * reflectance;
#endif
- #if defined(USE_PRIMARY_LIGHT)
+ #if defined(USE_PRIMARY_LIGHT) || defined(SHADOWMAP_MODULATE)
vec3 L2, H2;
float NL2, EH2, NH2;
@@ -560,20 +399,19 @@ void main()
//L2 /= sqrt(sqrLightDist);
NL2 = clamp(dot(N, L2), 0.0, 1.0);
-
H2 = normalize(L2 + E);
EH2 = clamp(dot(E, H2), 0.0, 1.0);
NH2 = clamp(dot(N, H2), 0.0, 1.0);
- reflectance = CalcDiffuse(diffuse.rgb, N, L2, E, NE, NL2, shininess);
- reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, gloss, shininess);
-
- lightColor = u_PrimaryLightColor * var_Color.rgb;
+ reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness);
- #if defined(r_lightGamma)
- lightColor = pow(lightColor, vec3(r_lightGamma));
+ // bit of a hack, with modulated shadowmaps, ignore diffuse
+ #if !defined(SHADOWMAP_MODULATE)
+ reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness);
#endif
+ lightColor = u_PrimaryLightColor;
+
#if defined(USE_SHADOWMAP)
lightColor *= shadowValue;
#endif
@@ -583,28 +421,16 @@ void main()
gl_FragColor.rgb += lightColor * reflectance * NL2;
#endif
-#else
- lightColor = var_Color.rgb;
-
- #if defined(USE_LIGHTMAP)
- lightColor *= lightmapColor.rgb;
- #endif
- #if defined(r_lightGamma)
- lightColor = pow(lightColor, vec3(r_lightGamma));
+ #if defined(USE_PBR)
+ gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
#endif
- #if defined(r_materialGamma)
- diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma));
- #endif
+#else
gl_FragColor.rgb = diffuse.rgb * lightColor;
#endif
-#if defined(r_framebufferGamma)
- gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / r_framebufferGamma));
-#endif
-
gl_FragColor.a = diffuse.a * var_Color.a;
}
diff --git a/src/renderergl2/glsl/lightall_vp.glsl b/src/renderergl2/glsl/lightall_vp.glsl
index 59051d7c..783885e9 100644
--- a/src/renderergl2/glsl/lightall_vp.glsl
+++ b/src/renderergl2/glsl/lightall_vp.glsl
@@ -57,10 +57,8 @@ uniform float u_VertexLerp;
#if defined(USE_LIGHT_VECTOR)
uniform vec4 u_LightOrigin;
uniform float u_LightRadius;
- #if defined(USE_FAST_LIGHT)
uniform vec3 u_DirectedLight;
uniform vec3 u_AmbientLight;
- #endif
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
@@ -71,6 +69,9 @@ uniform float u_PrimaryLightRadius;
varying vec4 var_TexCoords;
varying vec4 var_Color;
+#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
+varying vec4 var_ColorAmbient;
+#endif
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
#if defined(USE_VERT_TANGENT_SPACE)
@@ -208,12 +209,24 @@ void main()
var_Color = u_VertColor * attr_Color + u_BaseColor;
-#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)
+#if defined(USE_LIGHT_VECTOR)
+ #if defined(USE_FAST_LIGHT)
float sqrLightDist = dot(L, L);
- float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
+ float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight;
+ #else
+ var_ColorAmbient.rgb = u_AmbientLight * var_Color.rgb;
+ var_Color.rgb *= u_DirectedLight;
+ #if defined(USE_PBR)
+ var_ColorAmbient.rgb *= var_ColorAmbient.rgb;
+ #endif
+ #endif
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) && defined(USE_PBR)
+ var_Color.rgb *= var_Color.rgb;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
diff --git a/src/renderergl2/glsl/ssao_fp.glsl b/src/renderergl2/glsl/ssao_fp.glsl
index 6263284c..93f61859 100644
--- a/src/renderergl2/glsl/ssao_fp.glsl
+++ b/src/renderergl2/glsl/ssao_fp.glsl
@@ -1,6 +1,6 @@
uniform sampler2D u_ScreenDepthMap;
-uniform vec4 u_ViewInfo; // zfar / znear, zfar
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
varying vec2 var_ScreenTex;
@@ -11,6 +11,7 @@ vec2(0.5784913, -0.002528916), vec2(0.192888, 0.4064181),
vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
vec2(0.7320465, 0.6317794)
);
+#define NUM_SAMPLES 3
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
@@ -39,48 +40,47 @@ mat2 randomRotation( const vec2 p )
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
- float sampleZDivW = texture2D(depthMap, tex).r;
- return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
-float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar)
+float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale)
{
float result = 0;
- float sampleZ = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
+ float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
+ float scaleZ = zFarDivZNear * sampleZ;
- vec2 expectedSlope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
-
- if (length(expectedSlope) > 5000.0)
+ vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
+
+ if (length(slope) * zFar > 5000.0)
return 1.0;
-
- vec2 offsetScale = vec2(3.0 / sampleZ);
-
+
+ vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
+
mat2 rmat = randomRotation(tex);
-
+
+ float invZFar = 1.0 / zFar;
+ float zLimit = 20.0 * invZFar;
int i;
- for (i = 0; i < 3; i++)
+ for (i = 0; i < NUM_SAMPLES; i++)
{
vec2 offset = rmat * poissonDisc[i] * offsetScale;
- float sampleZ2 = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
-
- if (abs(sampleZ - sampleZ2) > 20.0)
- result += 1.0;
- else
- {
- float expectedZ = sampleZ + dot(expectedSlope, offset);
- result += step(expectedZ - 1.0, sampleZ2);
- }
+ float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ;
+
+ bool s1 = abs(sampleDiff) > zLimit;
+ bool s2 = sampleDiff + invZFar > dot(slope, offset);
+ result += float(s1 || s2);
}
-
- result *= 0.33333;
-
+
+ result *= 1.0 / float(NUM_SAMPLES);
+
return result;
}
void main()
{
- float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
-
+ float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz);
+
gl_FragColor = vec4(vec3(result), 1.0);
}
diff --git a/src/renderergl2/glsl/tonemap_fp.glsl b/src/renderergl2/glsl/tonemap_fp.glsl
index 1368c5bd..9e24e24a 100644
--- a/src/renderergl2/glsl/tonemap_fp.glsl
+++ b/src/renderergl2/glsl/tonemap_fp.glsl
@@ -28,8 +28,8 @@ void main()
{
vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color;
-#if defined(r_framebufferGamma)
- color.rgb = pow(color.rgb, vec3(r_framebufferGamma));
+#if defined(USE_PBR)
+ color.rgb *= color.rgb;
#endif
vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb;
@@ -46,9 +46,12 @@ void main()
color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0);
-#if defined(r_tonemapGamma)
- color.rgb = pow(color.rgb, vec3(1.0 / r_tonemapGamma));
+#if defined(USE_PBR)
+ color.rgb = sqrt(color.rgb);
#endif
+ // add a bit of dither to reduce banding
+ color.rgb += vec3(1.0/510.0 * mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) - 1.0/1020.0);
+
gl_FragColor = color;
}