diff options
Diffstat (limited to 'src/renderergl2/glsl')
-rw-r--r-- | src/renderergl2/glsl/calclevels4x_fp.glsl | 4 | ||||
-rw-r--r-- | src/renderergl2/glsl/depthblur_fp.glsl | 76 | ||||
-rw-r--r-- | src/renderergl2/glsl/depthblur_vp.glsl | 6 | ||||
-rw-r--r-- | src/renderergl2/glsl/lightall_fp.glsl | 342 | ||||
-rw-r--r-- | src/renderergl2/glsl/lightall_vp.glsl | 21 | ||||
-rw-r--r-- | src/renderergl2/glsl/ssao_fp.glsl | 54 | ||||
-rw-r--r-- | src/renderergl2/glsl/tonemap_fp.glsl | 11 |
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; } |