diff --git a/code/renderergl2/glsl/calclevels4x_fp.glsl b/code/renderergl2/glsl/calclevels4x_fp.glsl index 0d298b62..8246c4b3 100644 --- a/code/renderergl2/glsl/calclevels4x_fp.glsl +++ b/code/renderergl2/glsl/calclevels4x_fp.glsl @@ -15,7 +15,7 @@ vec3 GetValues(vec2 offset, vec3 current) #ifdef FIRST_PASS #if defined(USE_PBR) - minAvgMax = pow(minAvgMax, vec3(2.2)); + minAvgMax *= minAvgMax; #endif float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001); diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index eb8ba900..6a0a5155 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/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,7 +148,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) } #endif -vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float roughness) +vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness) { #if defined(USE_BURLEY) // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf @@ -171,7 +169,7 @@ vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular) return vec3(v) + specular; } -vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float roughness) +vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness) { // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf float rr = roughness*roughness; @@ -220,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; @@ -232,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; @@ -262,23 +259,17 @@ 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; - 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); - attenuation = 1.0; + 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_PBR) - lightColor = pow(lightColor, vec3(2.2)); - ambientColor = pow(ambientColor, vec3(2.2)); + #if defined(USE_LIGHT_VECTOR) + attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist); + #else + attenuation = 1.0; #endif #if defined(USE_NORMALMAP) @@ -295,21 +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(var_Normal.xyz, var_PrimaryLightDir.xyz), 0.0, 1.0); #if defined(SHADOWMAP_MODULATE) lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; #endif #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); @@ -320,9 +310,9 @@ void main() // Recover any unused light as ambient, in case attenuation is over 4x or // light is below the surface 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); @@ -332,32 +322,30 @@ void main() #else vec4 specular = vec4(1.0); #endif - specular *= u_SpecularScale; #if defined(USE_PBR) - diffuse.rgb = pow(diffuse.rgb, vec3(2.2)); + diffuse.rgb *= diffuse.rgb; #endif - float gloss = specular.a; #if defined(USE_PBR) + // diffuse rgb is base color + // specular red is smoothness + // specular green is metallicness float roughness = 1.0 - specular.r; + specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g); + diffuse.rgb *= 1.0 - specular.g; #else - float roughness = exp2(-3.0 * gloss); - #endif + // diffuse rgb is diffuse + // specular rgb is specular reflectance at normal incidence + // specular alpha is gloss + float roughness = exp2(-3.0 * specular.a); - #if defined(USE_PBR) - // diffuse is actually base color, and green of specular is metallicness - float metallic = specular.g; - - specular.rgb = metallic * diffuse.rgb + vec3(0.04 - 0.04 * metallic); - 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, EH, NH, roughness); + reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness); gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); gl_FragColor.rgb += ambientColor * diffuse.rgb; @@ -371,11 +359,7 @@ 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; - #if defined(USE_PBR) vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w; - #else - vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; - #endif // normalize cubemap based on lowest mip (~diffuse) // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation @@ -383,7 +367,7 @@ void main() //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721)); #if defined(USE_PBR) - cubeLightColor = pow(cubeLightColor, vec3(2.2)); + cubeLightColor *= cubeLightColor; #endif // multiply cubemap values by lighting @@ -404,24 +388,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 = CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness); + reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness); // bit of a hack, with modulated shadowmaps, ignore diffuse #if !defined(SHADOWMAP_MODULATE) - reflectance += CalcDiffuse(diffuse.rgb, EH2, NH2, roughness); + reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness); #endif lightColor = u_PrimaryLightColor; - #if defined(USE_PBR) - lightColor = pow(lightColor, vec3(2.2)); - #endif - #if defined(USE_SHADOWMAP) lightColor *= shadowValue; #endif @@ -433,15 +412,10 @@ void main() #endif #if defined(USE_PBR) - gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2)); + gl_FragColor.rgb = sqrt(gl_FragColor.rgb); #endif #else - lightColor = var_Color.rgb; - - #if defined(USE_LIGHTMAP) - lightColor *= lightmapColor.rgb; - #endif gl_FragColor.rgb = diffuse.rgb * lightColor; diff --git a/code/renderergl2/glsl/lightall_vp.glsl b/code/renderergl2/glsl/lightall_vp.glsl index 59051d7c..783885e9 100644 --- a/code/renderergl2/glsl/lightall_vp.glsl +++ b/code/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/code/renderergl2/glsl/tonemap_fp.glsl b/code/renderergl2/glsl/tonemap_fp.glsl index 5d8841d6..9e24e24a 100644 --- a/code/renderergl2/glsl/tonemap_fp.glsl +++ b/code/renderergl2/glsl/tonemap_fp.glsl @@ -29,7 +29,7 @@ void main() vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color; #if defined(USE_PBR) - color.rgb = pow(color.rgb, vec3(2.2)); + color.rgb *= color.rgb; #endif vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; @@ -47,8 +47,11 @@ void main() color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0); #if defined(USE_PBR) - color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); + 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; } diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index 5e59c80f..ca2a02b6 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -1273,7 +1273,19 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP); GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol); - GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol); + if (r_pbr->integer) + { + vec3_t color; + + color[0] = backEnd.refdef.sunCol[0] * backEnd.refdef.sunCol[0]; + color[1] = backEnd.refdef.sunCol[1] * backEnd.refdef.sunCol[1]; + color[2] = backEnd.refdef.sunCol[2] * backEnd.refdef.sunCol[2]; + GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, color); + } + else + { + GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol); + } GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir); }