diff options
-rw-r--r-- | src/renderergl2/glsl/lightall_fp.glsl | 44 | ||||
-rw-r--r-- | src/renderergl2/tr_glsl.c | 3 | ||||
-rw-r--r-- | src/renderergl2/tr_init.c | 2 | ||||
-rw-r--r-- | src/renderergl2/tr_local.h | 1 | ||||
-rw-r--r-- | src/renderergl2/tr_shade.c | 3 | ||||
-rw-r--r-- | src/renderergl2/tr_shader.c | 49 |
6 files changed, 76 insertions, 26 deletions
diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index c0d2bc80..6c8977e1 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -150,11 +150,11 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) } #endif -vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float r) +vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float roughness) { #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 * r; + float fd90 = -0.5 + EH * EH * roughness; float burley = 1.0 + fd90 * 0.04 / NH; burley *= burley; return diffuseAlbedo * burley; @@ -163,21 +163,21 @@ vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float r) #endif } -vec3 EnvironmentBRDF(float r, float NE, vec3 specular) +vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular) { // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf - float v = 1.0 - max(r, NE); + 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 r) +vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float roughness) { // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf - float rr = r*r; + float rr = roughness*roughness; float rrrr = rr*rr; float d = (NH * NH) * (rrrr - 1.0) + 1.0; - float v = (EH * EH) * (r + 0.5); + float v = (EH * EH) * (roughness + 0.5); return specular * (rrrr / (4.0 * d * d * v)); } @@ -276,6 +276,11 @@ void main() attenuation = 1.0; #endif + #if defined(r_lightGamma) + lightColor = pow(lightColor, vec3(r_lightGamma)); + ambientColor = pow(ambientColor, vec3(r_lightGamma)); + #endif + #if defined(USE_NORMALMAP) #if defined(SWIZZLE_NORMALMAP) N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5); @@ -304,11 +309,6 @@ void main() #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) ambientColor = lightColor; float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); @@ -343,7 +343,11 @@ void main() #endif float gloss = specular.a; - float r = exp2(-3.0 * gloss); + #if defined(GLOSS_IS_ROUGHNESS) + float roughness = gloss; + #else + float roughness = exp2(-3.0 * gloss); + #endif #if defined(SPECULAR_IS_METALLIC) // diffuse is actually base color, and green of specular is metallicness @@ -356,20 +360,20 @@ void main() diffuse.rgb *= vec3(1.0) - specular.rgb; #endif - reflectance = CalcDiffuse(diffuse.rgb, EH, NH, r); + reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness); #if defined(USE_SHADOWMAP) && defined(SHADOWMAP_MODULATE) // bit of a hack, with modulated shadowmaps, add specular to sunlight H = normalize(var_PrimaryLightDir.xyz + E); EH = clamp(dot(E, H), 0.0, 1.0); NH = clamp(dot(N, H), 0.0, 1.0); - reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, r); + reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, roughness); #endif gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb); #if defined(USE_CUBEMAP) - reflectance = EnvironmentBRDF(r, NE, specular.rgb); + reflectance = EnvironmentBRDF(roughness, NE, specular.rgb); vec3 R = reflect(E, N); @@ -377,7 +381,11 @@ 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(GLOSS_IS_ROUGHNESS) + vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 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 @@ -411,8 +419,8 @@ void main() EH2 = clamp(dot(E, H2), 0.0, 1.0); NH2 = clamp(dot(N, H2), 0.0, 1.0); - reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, r); - reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, r); + reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, roughness); + reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness); lightColor = u_PrimaryLightColor * var_Color.rgb; diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index 3fcb9350..8ce3a4e7 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -1025,6 +1025,9 @@ void GLSL_InitGPUShaders(void) if (r_specularIsMetallic->value) Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n"); + if (r_glossIsRoughness->value) + Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n"); + if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index a5d4c465..2828270e 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -142,6 +142,7 @@ cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; cvar_t *r_specularIsMetallic; +cvar_t *r_glossIsRoughness; cvar_t *r_baseNormalX; cvar_t *r_baseNormalY; cvar_t *r_baseParallax; @@ -1141,6 +1142,7 @@ void R_Register( void ) r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index a38cf7fc..f69aec19 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1788,6 +1788,7 @@ extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; extern cvar_t *r_specularIsMetallic; +extern cvar_t *r_glossIsRoughness; extern cvar_t *r_baseNormalX; extern cvar_t *r_baseNormalY; extern cvar_t *r_baseParallax; diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index e7a73842..f0a6d34b 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -450,11 +450,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR) || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR); - qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL); - #if defined(USE_OVERBRIGHT) float exactLight = 1.0f; #else + qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL); float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer); #endif diff --git a/src/renderergl2/tr_shader.c b/src/renderergl2/tr_shader.c index 98e8776e..b4a120ca 100644 --- a/src/renderergl2/tr_shader.c +++ b/src/renderergl2/tr_shader.c @@ -955,17 +955,23 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) exponent = atof( token ); - // Change shininess to gloss - // FIXME: assumes max exponent of 8192 and min of 1, must change here if altered in lightall_fp.glsl - exponent = CLAMP(exponent, 1.0, 8192.0); - - stage->specularScale[3] = log(exponent) / log(8192.0); + if (r_glossIsRoughness->integer) + stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25); + else + { + // Change shininess to gloss + // Assumes max exponent of 8190 and min of 0, must change here if altered in lightall_fp.glsl + exponent = CLAMP(exponent, 0.0f, 8190.0f); + stage->specularScale[3] = (log2f(exponent + 2.0f) - 1.0f) / 12.0f; + } } // // gloss <value> // else if (!Q_stricmp(token, "gloss")) { + float gloss; + token = COM_ParseExt(text, qfalse); if ( token[0] == 0 ) { @@ -973,7 +979,38 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) continue; } - stage->specularScale[3] = atof( token ); + gloss = atof(token); + + if (r_glossIsRoughness->integer) + stage->specularScale[3] = exp2f(-3.0f * gloss); + else + stage->specularScale[3] = gloss; + } + // + // roughness <value> + // + else if (!Q_stricmp(token, "roughness")) + { + float roughness; + + token = COM_ParseExt(text, qfalse); + if (token[0] == 0) + { + ri.Printf(PRINT_WARNING, "WARNING: missing parameter for roughness in shader '%s'\n", shader.name); + continue; + } + + roughness = atof(token); + + if (r_glossIsRoughness->integer) + stage->specularScale[3] = roughness; + else + { + if (roughness >= 0.125) + stage->specularScale[3] = log2f(1.0f / roughness) / 3.0f; + else + stage->specularScale[3] = 1.0f; + } } // // parallaxDepth <value> |