OpenGL2: Shader optimization, and add dither to tonemap.

This commit is contained in:
SmileTheory 2016-02-17 20:06:18 -08:00
parent d11cfc88d5
commit a331637745
5 changed files with 76 additions and 74 deletions

View file

@ -15,7 +15,7 @@ vec3 GetValues(vec2 offset, vec3 current)
#ifdef FIRST_PASS #ifdef FIRST_PASS
#if defined(USE_PBR) #if defined(USE_PBR)
minAvgMax = pow(minAvgMax, vec3(2.2)); minAvgMax *= minAvgMax;
#endif #endif
float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001); float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001);

View file

@ -29,11 +29,6 @@ uniform samplerCube u_CubeMap;
uniform vec4 u_EnableTextures; uniform vec4 u_EnableTextures;
#endif #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) #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
uniform vec3 u_PrimaryLightColor; uniform vec3 u_PrimaryLightColor;
uniform vec3 u_PrimaryLightAmbient; uniform vec3 u_PrimaryLightAmbient;
@ -53,6 +48,9 @@ uniform vec4 u_CubeMapInfo;
varying vec4 var_TexCoords; varying vec4 var_TexCoords;
varying vec4 var_Color; 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_LIGHT) && !defined(USE_FAST_LIGHT))
#if defined(USE_VERT_TANGENT_SPACE) #if defined(USE_VERT_TANGENT_SPACE)
@ -150,7 +148,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)
} }
#endif #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) #if defined(USE_BURLEY)
// modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf // 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; 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 // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
float rr = roughness*roughness; float rr = roughness*roughness;
@ -220,7 +218,7 @@ mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv )
void main() void main()
{ {
vec3 viewDir, lightColor, ambientColor; vec3 viewDir, lightColor, ambientColor, reflectance;
vec3 L, N, E, H; vec3 L, N, E, H;
float NL, NH, NE, EH, attenuation; float NL, NH, NE, EH, attenuation;
@ -232,21 +230,20 @@ void main()
mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy); mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy);
viewDir = var_ViewDir; viewDir = var_ViewDir;
#endif #endif
E = normalize(viewDir); 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 #endif
lightColor = var_Color.rgb;
#if defined(USE_LIGHTMAP) #if defined(USE_LIGHTMAP)
vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw); vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw);
#if defined(RGBM_LIGHTMAP) #if defined(RGBM_LIGHTMAP)
lightmapColor.rgb *= lightmapColor.a; lightmapColor.rgb *= lightmapColor.a;
#endif #endif
#if defined(USE_PBR) && !defined(USE_FAST_LIGHT)
lightmapColor.rgb *= lightmapColor.rgb;
#endif
lightColor *= lightmapColor.rgb;
#endif #endif
vec2 texCoords = var_TexCoords.xy; vec2 texCoords = var_TexCoords.xy;
@ -262,23 +259,17 @@ void main()
vec4 diffuse = texture2D(u_DiffuseMap, texCoords); vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
#if defined(USE_LIGHTMAP) L = var_LightDir.xyz;
lightColor = lightmapColor.rgb * var_Color.rgb; #if defined(USE_DELUXEMAP)
ambientColor = vec3(0.0); L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
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;
#endif #endif
float sqrLightDist = dot(L, L);
L /= sqrt(sqrLightDist);
#if defined(USE_PBR) #if defined(USE_LIGHT_VECTOR)
lightColor = pow(lightColor, vec3(2.2)); attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
ambientColor = pow(ambientColor, vec3(2.2)); #else
attenuation = 1.0;
#endif #endif
#if defined(USE_NORMALMAP) #if defined(USE_NORMALMAP)
@ -295,21 +286,20 @@ void main()
#endif #endif
N = normalize(N); N = normalize(N);
L /= sqrt(sqrLightDist);
#if defined(USE_SHADOWMAP) #if defined(USE_SHADOWMAP)
vec2 shadowTex = gl_FragCoord.xy * r_FBufScale; vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
float shadowValue = texture2D(u_ShadowMap, shadowTex).r; float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
// surfaces not facing the light are always shadowed // 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) #if defined(SHADOWMAP_MODULATE)
lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
#endif #endif
#endif #endif
#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX) #if !defined(USE_LIGHT_VECTOR)
ambientColor = lightColor; ambientColor = lightColor;
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); 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 // Recover any unused light as ambient, in case attenuation is over 4x or
// light is below the surface // light is below the surface
ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0)); ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0));
#else
ambientColor = var_ColorAmbient.rgb;
#endif #endif
vec3 reflectance;
NL = clamp(dot(N, L), 0.0, 1.0); NL = clamp(dot(N, L), 0.0, 1.0);
NE = clamp(dot(N, E), 0.0, 1.0); NE = clamp(dot(N, E), 0.0, 1.0);
@ -332,32 +322,30 @@ void main()
#else #else
vec4 specular = vec4(1.0); vec4 specular = vec4(1.0);
#endif #endif
specular *= u_SpecularScale; specular *= u_SpecularScale;
#if defined(USE_PBR) #if defined(USE_PBR)
diffuse.rgb = pow(diffuse.rgb, vec3(2.2)); diffuse.rgb *= diffuse.rgb;
#endif #endif
float gloss = specular.a;
#if defined(USE_PBR) #if defined(USE_PBR)
// diffuse rgb is base color
// specular red is smoothness
// specular green is metallicness
float roughness = 1.0 - specular.r; 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 #else
float roughness = exp2(-3.0 * gloss); // diffuse rgb is diffuse
#endif // 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 // adjust diffuse by specular reflectance, to maintain energy conservation
diffuse.rgb *= vec3(1.0) - specular.rgb; diffuse.rgb *= vec3(1.0) - specular.rgb;
#endif #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 = lightColor * reflectance * (attenuation * NL);
gl_FragColor.rgb += ambientColor * diffuse.rgb; 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/ // 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 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; 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) // normalize cubemap based on lowest mip (~diffuse)
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation // 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)); //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721));
#if defined(USE_PBR) #if defined(USE_PBR)
cubeLightColor = pow(cubeLightColor, vec3(2.2)); cubeLightColor *= cubeLightColor;
#endif #endif
// multiply cubemap values by lighting // multiply cubemap values by lighting
@ -404,24 +388,19 @@ void main()
//L2 /= sqrt(sqrLightDist); //L2 /= sqrt(sqrLightDist);
NL2 = clamp(dot(N, L2), 0.0, 1.0); NL2 = clamp(dot(N, L2), 0.0, 1.0);
H2 = normalize(L2 + E); H2 = normalize(L2 + E);
EH2 = clamp(dot(E, H2), 0.0, 1.0); EH2 = clamp(dot(E, H2), 0.0, 1.0);
NH2 = clamp(dot(N, 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 // bit of a hack, with modulated shadowmaps, ignore diffuse
#if !defined(SHADOWMAP_MODULATE) #if !defined(SHADOWMAP_MODULATE)
reflectance += CalcDiffuse(diffuse.rgb, EH2, NH2, roughness); reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness);
#endif #endif
lightColor = u_PrimaryLightColor; lightColor = u_PrimaryLightColor;
#if defined(USE_PBR)
lightColor = pow(lightColor, vec3(2.2));
#endif
#if defined(USE_SHADOWMAP) #if defined(USE_SHADOWMAP)
lightColor *= shadowValue; lightColor *= shadowValue;
#endif #endif
@ -433,15 +412,10 @@ void main()
#endif #endif
#if defined(USE_PBR) #if defined(USE_PBR)
gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2)); gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
#endif #endif
#else #else
lightColor = var_Color.rgb;
#if defined(USE_LIGHTMAP)
lightColor *= lightmapColor.rgb;
#endif
gl_FragColor.rgb = diffuse.rgb * lightColor; gl_FragColor.rgb = diffuse.rgb * lightColor;

View file

@ -57,10 +57,8 @@ uniform float u_VertexLerp;
#if defined(USE_LIGHT_VECTOR) #if defined(USE_LIGHT_VECTOR)
uniform vec4 u_LightOrigin; uniform vec4 u_LightOrigin;
uniform float u_LightRadius; uniform float u_LightRadius;
#if defined(USE_FAST_LIGHT)
uniform vec3 u_DirectedLight; uniform vec3 u_DirectedLight;
uniform vec3 u_AmbientLight; uniform vec3 u_AmbientLight;
#endif
#endif #endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
@ -71,6 +69,9 @@ uniform float u_PrimaryLightRadius;
varying vec4 var_TexCoords; varying vec4 var_TexCoords;
varying vec4 var_Color; 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_LIGHT) && !defined(USE_FAST_LIGHT)
#if defined(USE_VERT_TANGENT_SPACE) #if defined(USE_VERT_TANGENT_SPACE)
@ -208,12 +209,24 @@ void main()
var_Color = u_VertColor * attr_Color + u_BaseColor; 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 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 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; 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 #endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)

View file

@ -29,7 +29,7 @@ void main()
vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color; vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color;
#if defined(USE_PBR) #if defined(USE_PBR)
color.rgb = pow(color.rgb, vec3(2.2)); color.rgb *= color.rgb;
#endif #endif
vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; 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); color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0);
#if defined(USE_PBR) #if defined(USE_PBR)
color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); color.rgb = sqrt(color.rgb);
#endif #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; gl_FragColor = color;
} }

View file

@ -1273,7 +1273,19 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
{ {
GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP); GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol); 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); GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir);
} }