From ad952b9537ab8d465c5b5006feb29975ad57f74b Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 1 Feb 2016 21:37:23 -0800 Subject: [PATCH] OpenGL2: Merge several cvars into r_pbr. r_glossIsRoughness, r_specularIsMetallic, r_framebufferGamma, r_tonemapGamma, r_materialGamma, r_lightGamma --- code/renderergl2/glsl/calclevels4x_fp.glsl | 4 +- code/renderergl2/glsl/lightall_fp.glsl | 48 +++++++---------- code/renderergl2/glsl/tonemap_fp.glsl | 8 +-- code/renderergl2/tr_bsp.c | 4 +- code/renderergl2/tr_glsl.c | 19 +------ code/renderergl2/tr_image.c | 5 ++ code/renderergl2/tr_init.c | 18 ++----- code/renderergl2/tr_local.h | 8 +-- code/renderergl2/tr_scene.c | 2 +- code/renderergl2/tr_shader.c | 60 ++++++++++++++++------ opengl2-readme.md | 20 +++----- 11 files changed, 88 insertions(+), 108 deletions(-) diff --git a/code/renderergl2/glsl/calclevels4x_fp.glsl b/code/renderergl2/glsl/calclevels4x_fp.glsl index 1de59e9f..0d298b62 100644 --- a/code/renderergl2/glsl/calclevels4x_fp.glsl +++ b/code/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 = pow(minAvgMax, vec3(2.2)); #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 b8f3985f..eb8ba900 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -276,9 +276,9 @@ void main() attenuation = 1.0; #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - ambientColor = pow(ambientColor, vec3(r_lightGamma)); + #if defined(USE_PBR) + lightColor = pow(lightColor, vec3(2.2)); + ambientColor = pow(ambientColor, vec3(2.2)); #endif #if defined(USE_NORMALMAP) @@ -319,7 +319,7 @@ 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)); #endif vec3 reflectance; @@ -335,21 +335,18 @@ void main() specular *= u_SpecularScale; - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - #if !defined(SPECULAR_IS_METALLIC) - specular.rgb = pow(specular.rgb, vec3(r_materialGamma)); - #endif + #if defined(USE_PBR) + diffuse.rgb = pow(diffuse.rgb, vec3(2.2)); #endif float gloss = specular.a; - #if defined(GLOSS_IS_ROUGHNESS) - float roughness = gloss; + #if defined(USE_PBR) + float roughness = 1.0 - specular.r; #else float roughness = exp2(-3.0 * gloss); #endif - #if defined(SPECULAR_IS_METALLIC) + #if defined(USE_PBR) // diffuse is actually base color, and green of specular is metallicness float metallic = specular.g; @@ -374,7 +371,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(GLOSS_IS_ROUGHNESS) + #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; @@ -385,8 +382,8 @@ void main() //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 = pow(cubeLightColor, vec3(2.2)); #endif // multiply cubemap values by lighting @@ -421,8 +418,8 @@ void main() lightColor = u_PrimaryLightColor; - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); + #if defined(USE_PBR) + lightColor = pow(lightColor, vec3(2.2)); #endif #if defined(USE_SHADOWMAP) @@ -434,6 +431,11 @@ void main() gl_FragColor.rgb += lightColor * reflectance * NL2; #endif + + #if defined(USE_PBR) + gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2)); + #endif + #else lightColor = var_Color.rgb; @@ -441,21 +443,9 @@ void main() lightColor *= lightmapColor.rgb; #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - #endif - - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - #endif - 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/code/renderergl2/glsl/tonemap_fp.glsl b/code/renderergl2/glsl/tonemap_fp.glsl index 1368c5bd..5d8841d6 100644 --- a/code/renderergl2/glsl/tonemap_fp.glsl +++ b/code/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 = pow(color.rgb, vec3(2.2)); #endif vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; @@ -46,8 +46,8 @@ 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 = pow(color.rgb, vec3(1.0 / 2.2)); #endif gl_FragColor = color; diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index 6c4cbe21..ed7ece72 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -141,7 +141,7 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale ) float r, g, b; #if defined(USE_OVERBRIGHT) - scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits); + scale *= 1 << (r_mapOverBrightBits->integer - tr.overbrightBits); #endif r = in[0] * scale; @@ -2762,7 +2762,7 @@ void R_LoadLightGrid( lump_t *l ) { if (hdrLightGrid) { #if defined(USE_OVERBRIGHT) - float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits); + float lightScale = 1 << (r_mapOverBrightBits->integer - tr.overbrightBits); #else float lightScale = 1.0f; #endif diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index eaa7c8f5..f8637a66 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -322,17 +322,8 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, cha Q_strcat(dest, size, va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale)); - if (r_materialGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_materialGamma\n#define r_materialGamma %f\n#endif\n", r_materialGamma->value)); - - if (r_lightGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_lightGamma\n#define r_lightGamma %f\n#endif\n", r_lightGamma->value)); - - if (r_framebufferGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_framebufferGamma\n#define r_framebufferGamma %f\n#endif\n", r_framebufferGamma->value)); - - if (r_tonemapGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_tonemapGamma\n#define r_tonemapGamma %f\n#endif\n", r_tonemapGamma->value)); + if (r_pbr->integer) + Q_strcat(dest, size, "#define USE_PBR\n"); if (extra) { @@ -1009,12 +1000,6 @@ void GLSL_InitGPUShaders(void) extradefines[0] = '\0'; - 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/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index e508b15d..69ddba19 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -2858,6 +2858,11 @@ void R_SetColorMappings( void ) { tr.overbrightBits = 0; } + // don't allow more overbright bits than map overbright bits + if ( tr.overbrightBits > r_mapOverBrightBits->integer ) { + tr.overbrightBits = r_mapOverBrightBits->integer; + } + tr.identityLight = 1.0f / ( 1 << tr.overbrightBits ); tr.identityLightByte = 255 * tr.identityLight; diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index 3f387232..282ce926 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -132,11 +132,6 @@ cvar_t *r_forceAutoExposure; cvar_t *r_forceAutoExposureMin; cvar_t *r_forceAutoExposureMax; -cvar_t *r_materialGamma; -cvar_t *r_lightGamma; -cvar_t *r_framebufferGamma; -cvar_t *r_tonemapGamma; - cvar_t *r_depthPrepass; cvar_t *r_ssao; @@ -146,8 +141,7 @@ cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; cvar_t *r_cubemapSize; -cvar_t *r_specularIsMetallic; -cvar_t *r_glossIsRoughness; +cvar_t *r_pbr; cvar_t *r_baseNormalX; cvar_t *r_baseNormalY; cvar_t *r_baseParallax; @@ -1213,7 +1207,7 @@ void R_Register( void ) r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE ); - r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH ); + r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE ); r_forceToneMap = ri.Cvar_Get( "r_forceToneMap", "0", CVAR_CHEAT ); r_forceToneMapMin = ri.Cvar_Get( "r_forceToneMapMin", "-8.0", CVAR_CHEAT ); r_forceToneMapAvg = ri.Cvar_Get( "r_forceToneMapAvg", "-2.0", CVAR_CHEAT ); @@ -1226,11 +1220,6 @@ void R_Register( void ) r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT ); - r_materialGamma = ri.Cvar_Get( "r_materialGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_lightGamma = ri.Cvar_Get( "r_lightGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_framebufferGamma = ri.Cvar_Get( "r_framebufferGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_tonemapGamma = ri.Cvar_Get( "r_tonemapGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE ); r_ssao = ri.Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE ); @@ -1240,8 +1229,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_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", 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_pbr = ri.Cvar_Get("r_pbr", "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/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index c66171f5..17b13749 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1776,11 +1776,6 @@ extern cvar_t *r_forceAutoExposureMax; extern cvar_t *r_cameraExposure; -extern cvar_t *r_materialGamma; -extern cvar_t *r_lightGamma; -extern cvar_t *r_framebufferGamma; -extern cvar_t *r_tonemapGamma; - extern cvar_t *r_depthPrepass; extern cvar_t *r_ssao; @@ -1790,8 +1785,7 @@ extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; extern cvar_t *r_cubemapSize; -extern cvar_t *r_specularIsMetallic; -extern cvar_t *r_glossIsRoughness; +extern cvar_t *r_pbr; extern cvar_t *r_baseNormalX; extern cvar_t *r_baseNormalY; extern cvar_t *r_baseParallax; diff --git a/code/renderergl2/tr_scene.c b/code/renderergl2/tr_scene.c index bd85944d..11ef0e89 100644 --- a/code/renderergl2/tr_scene.c +++ b/code/renderergl2/tr_scene.c @@ -336,7 +336,7 @@ void RE_BeginScene(const refdef_t *fd) else { #if defined(USE_OVERBRIGHT) - float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8); + float scale = (1 << (r_mapOverBrightBits->integer - tr.overbrightBits)) / 255.0f;; #else float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; #endif diff --git a/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index 5e664f4f..0ef90211 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -934,9 +934,18 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name ); continue; } - stage->specularScale[0] = - stage->specularScale[1] = - stage->specularScale[2] = atof( token ); + + if (r_pbr->integer) + { + // interpret specularReflectance < 0.5 as nonmetal + stage->specularScale[1] = (atof(token) < 0.5f) ? 0.0f : 1.0f; + } + else + { + stage->specularScale[0] = + stage->specularScale[1] = + stage->specularScale[2] = atof( token ); + } } // // specularExponent @@ -954,8 +963,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) exponent = atof( token ); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25); + if (r_pbr->integer) + stage->specularScale[0] = 1.0f - powf(2.0f / (exponent + 2.0), 0.25); else { // Change shininess to gloss @@ -980,8 +989,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) gloss = atof(token); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = exp2f(-3.0f * gloss); + if (r_pbr->integer) + stage->specularScale[0] = 1.0f - exp2f(-3.0f * gloss); else stage->specularScale[3] = gloss; } @@ -1001,8 +1010,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) roughness = atof(token); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = roughness; + if (r_pbr->integer) + stage->specularScale[0] = 1.0 - roughness; else { if (roughness >= 0.125) @@ -1062,6 +1071,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) } // // specularScale + // or specularScale with r_pbr 1 // or specularScale // or specularScale // @@ -1088,10 +1098,19 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) token = COM_ParseExt(text, qfalse); if ( token[0] == 0 ) { - // two values, rgb then gloss - stage->specularScale[3] = stage->specularScale[1]; - stage->specularScale[1] = - stage->specularScale[2] = stage->specularScale[0]; + if (r_pbr->integer) + { + // two values, metallic then smoothness + float smoothness = stage->specularScale[1]; + stage->specularScale[1] = (stage->specularScale[0] < 0.5f) ? 0.0f : 1.0f; + stage->specularScale[0] = smoothness; + } + { + // two values, rgb then gloss + stage->specularScale[3] = stage->specularScale[1]; + stage->specularScale[1] = + stage->specularScale[2] = stage->specularScale[0]; + } continue; } @@ -2857,10 +2876,17 @@ static void InitShader( const char *name, int lightmapIndex ) { // default normal/specular VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f); - stages[i].specularScale[0] = - stages[i].specularScale[1] = - stages[i].specularScale[2] = r_baseSpecular->value; - stages[i].specularScale[3] = r_baseGloss->value; + if (r_pbr->integer) + { + stages[i].specularScale[0] = r_baseGloss->value; + } + else + { + stages[i].specularScale[0] = + stages[i].specularScale[1] = + stages[i].specularScale[2] = r_baseSpecular->value; + stages[i].specularScale[3] = r_baseGloss->value; + } } } diff --git a/opengl2-readme.md b/opengl2-readme.md index e0efd58c..d2757d4b 100644 --- a/opengl2-readme.md +++ b/opengl2-readme.md @@ -222,6 +222,12 @@ Cvars for advanced material usage: 0.05 - Standard depth. (default) 0.1 - Looks broken. +* `r_pbr` - Enable physically based rendering. + Experimental, will not look correct without + assets meant for it. + 0 - No. (default) + 1 - Yes. + Cvars for image interpolation and generation: * `r_imageUpsample` - Use interpolation to artifically increase @@ -339,20 +345,6 @@ Cvars that you probably don't care about or shouldn't mess with: * `r_shadowCascadeZBias` - Z-bias for shadow cascade frustums. -256 - Default. -* `r_materialGamma` - Gamma level for material textures. - (diffuse, specular) - 1.0 - Quake 3, fastest. (default) - -* `r_lightGamma` - Gamma level for light. - (lightmap, lightgrid, vertex lights) - 1.0 - Quake 3, fastest. (default) - -* `r_framebufferGamma` - Gamma level for framebuffers. - 1.0 - Quake 3, fastest. (default) - -* `r_tonemapGamma` - Gamma applied after tonemapping. - 1.0 - Quake 3, fastest. (default) - Cvars that have broken bits: * `r_dlightMode` - Change how dynamic lights look.