OpenGL2: Merge several cvars into r_pbr.

r_glossIsRoughness, r_specularIsMetallic, r_framebufferGamma, r_tonemapGamma, r_materialGamma, r_lightGamma
This commit is contained in:
SmileTheory 2016-02-01 21:37:23 -08:00
parent 41791c662f
commit ad952b9537
11 changed files with 88 additions and 108 deletions

View File

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

View File

@ -276,9 +276,9 @@ void main()
attenuation = 1.0; attenuation = 1.0;
#endif #endif
#if defined(r_lightGamma) #if defined(USE_PBR)
lightColor = pow(lightColor, vec3(r_lightGamma)); lightColor = pow(lightColor, vec3(2.2));
ambientColor = pow(ambientColor, vec3(r_lightGamma)); ambientColor = pow(ambientColor, vec3(2.2));
#endif #endif
#if defined(USE_NORMALMAP) #if defined(USE_NORMALMAP)
@ -319,7 +319,7 @@ 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 = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0); ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0));
#endif #endif
vec3 reflectance; vec3 reflectance;
@ -335,21 +335,18 @@ void main()
specular *= u_SpecularScale; specular *= u_SpecularScale;
#if defined(r_materialGamma) #if defined(USE_PBR)
diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); diffuse.rgb = pow(diffuse.rgb, vec3(2.2));
#if !defined(SPECULAR_IS_METALLIC)
specular.rgb = pow(specular.rgb, vec3(r_materialGamma));
#endif
#endif #endif
float gloss = specular.a; float gloss = specular.a;
#if defined(GLOSS_IS_ROUGHNESS) #if defined(USE_PBR)
float roughness = gloss; float roughness = 1.0 - specular.r;
#else #else
float roughness = exp2(-3.0 * gloss); float roughness = exp2(-3.0 * gloss);
#endif #endif
#if defined(SPECULAR_IS_METALLIC) #if defined(USE_PBR)
// diffuse is actually base color, and green of specular is metallicness // diffuse is actually base color, and green of specular is metallicness
float metallic = specular.g; 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/ // 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(GLOSS_IS_ROUGHNESS) #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 #else
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 - 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); //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, 6.0).rgb, 0.5 / 255.0);
//cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721)); //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721));
#if defined(r_framebufferGamma) #if defined(USE_PBR)
cubeLightColor = pow(cubeLightColor, vec3(r_framebufferGamma)); cubeLightColor = pow(cubeLightColor, vec3(2.2));
#endif #endif
// multiply cubemap values by lighting // multiply cubemap values by lighting
@ -421,8 +418,8 @@ void main()
lightColor = u_PrimaryLightColor; lightColor = u_PrimaryLightColor;
#if defined(r_lightGamma) #if defined(USE_PBR)
lightColor = pow(lightColor, vec3(r_lightGamma)); lightColor = pow(lightColor, vec3(2.2));
#endif #endif
#if defined(USE_SHADOWMAP) #if defined(USE_SHADOWMAP)
@ -434,6 +431,11 @@ void main()
gl_FragColor.rgb += lightColor * reflectance * NL2; gl_FragColor.rgb += lightColor * reflectance * NL2;
#endif #endif
#if defined(USE_PBR)
gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2));
#endif
#else #else
lightColor = var_Color.rgb; lightColor = var_Color.rgb;
@ -441,21 +443,9 @@ void main()
lightColor *= lightmapColor.rgb; lightColor *= lightmapColor.rgb;
#endif #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; gl_FragColor.rgb = diffuse.rgb * lightColor;
#endif #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; gl_FragColor.a = diffuse.a * var_Color.a;
} }

View File

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

View File

@ -141,7 +141,7 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale )
float r, g, b; float r, g, b;
#if defined(USE_OVERBRIGHT) #if defined(USE_OVERBRIGHT)
scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits); scale *= 1 << (r_mapOverBrightBits->integer - tr.overbrightBits);
#endif #endif
r = in[0] * scale; r = in[0] * scale;
@ -2762,7 +2762,7 @@ void R_LoadLightGrid( lump_t *l ) {
if (hdrLightGrid) if (hdrLightGrid)
{ {
#if defined(USE_OVERBRIGHT) #if defined(USE_OVERBRIGHT)
float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits); float lightScale = 1 << (r_mapOverBrightBits->integer - tr.overbrightBits);
#else #else
float lightScale = 1.0f; float lightScale = 1.0f;
#endif #endif

View File

@ -322,17 +322,8 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, cha
Q_strcat(dest, size, Q_strcat(dest, size,
va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale)); va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale));
if (r_materialGamma->value != 1.0f) if (r_pbr->integer)
Q_strcat(dest, size, va("#ifndef r_materialGamma\n#define r_materialGamma %f\n#endif\n", r_materialGamma->value)); Q_strcat(dest, size, "#define USE_PBR\n");
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 (extra) if (extra)
{ {
@ -1009,12 +1000,6 @@ void GLSL_InitGPUShaders(void)
extradefines[0] = '\0'; 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) if (r_dlightMode->integer >= 2)
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");

View File

@ -2858,6 +2858,11 @@ void R_SetColorMappings( void ) {
tr.overbrightBits = 0; 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.identityLight = 1.0f / ( 1 << tr.overbrightBits );
tr.identityLightByte = 255 * tr.identityLight; tr.identityLightByte = 255 * tr.identityLight;

View File

@ -132,11 +132,6 @@ cvar_t *r_forceAutoExposure;
cvar_t *r_forceAutoExposureMin; cvar_t *r_forceAutoExposureMin;
cvar_t *r_forceAutoExposureMax; 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_depthPrepass;
cvar_t *r_ssao; cvar_t *r_ssao;
@ -146,8 +141,7 @@ cvar_t *r_deluxeMapping;
cvar_t *r_parallaxMapping; cvar_t *r_parallaxMapping;
cvar_t *r_cubeMapping; cvar_t *r_cubeMapping;
cvar_t *r_cubemapSize; cvar_t *r_cubemapSize;
cvar_t *r_specularIsMetallic; cvar_t *r_pbr;
cvar_t *r_glossIsRoughness;
cvar_t *r_baseNormalX; cvar_t *r_baseNormalX;
cvar_t *r_baseNormalY; cvar_t *r_baseNormalY;
cvar_t *r_baseParallax; 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_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE ); 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_forceToneMap = ri.Cvar_Get( "r_forceToneMap", "0", CVAR_CHEAT );
r_forceToneMapMin = ri.Cvar_Get( "r_forceToneMapMin", "-8.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 ); 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_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_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE );
r_ssao = ri.Cvar_Get( "r_ssao", "0", CVAR_LATCH | 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_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "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_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH );
r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_pbr = ri.Cvar_Get("r_pbr", "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_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_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 ); r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH );

View File

@ -1776,11 +1776,6 @@ extern cvar_t *r_forceAutoExposureMax;
extern cvar_t *r_cameraExposure; 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_depthPrepass;
extern cvar_t *r_ssao; extern cvar_t *r_ssao;
@ -1790,8 +1785,7 @@ extern cvar_t *r_deluxeMapping;
extern cvar_t *r_parallaxMapping; extern cvar_t *r_parallaxMapping;
extern cvar_t *r_cubeMapping; extern cvar_t *r_cubeMapping;
extern cvar_t *r_cubemapSize; extern cvar_t *r_cubemapSize;
extern cvar_t *r_specularIsMetallic; extern cvar_t *r_pbr;
extern cvar_t *r_glossIsRoughness;
extern cvar_t *r_baseNormalX; extern cvar_t *r_baseNormalX;
extern cvar_t *r_baseNormalY; extern cvar_t *r_baseNormalY;
extern cvar_t *r_baseParallax; extern cvar_t *r_baseParallax;

View File

@ -336,7 +336,7 @@ void RE_BeginScene(const refdef_t *fd)
else else
{ {
#if defined(USE_OVERBRIGHT) #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 #else
float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; float scale = (1 << r_mapOverBrightBits->integer) / 255.0f;
#endif #endif

View File

@ -934,10 +934,19 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name ); ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name );
continue; continue;
} }
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[0] =
stage->specularScale[1] = stage->specularScale[1] =
stage->specularScale[2] = atof( token ); stage->specularScale[2] = atof( token );
} }
}
// //
// specularExponent <value> // specularExponent <value>
// //
@ -954,8 +963,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
exponent = atof( token ); exponent = atof( token );
if (r_glossIsRoughness->integer) if (r_pbr->integer)
stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25); stage->specularScale[0] = 1.0f - powf(2.0f / (exponent + 2.0), 0.25);
else else
{ {
// Change shininess to gloss // Change shininess to gloss
@ -980,8 +989,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
gloss = atof(token); gloss = atof(token);
if (r_glossIsRoughness->integer) if (r_pbr->integer)
stage->specularScale[3] = exp2f(-3.0f * gloss); stage->specularScale[0] = 1.0f - exp2f(-3.0f * gloss);
else else
stage->specularScale[3] = gloss; stage->specularScale[3] = gloss;
} }
@ -1001,8 +1010,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
roughness = atof(token); roughness = atof(token);
if (r_glossIsRoughness->integer) if (r_pbr->integer)
stage->specularScale[3] = roughness; stage->specularScale[0] = 1.0 - roughness;
else else
{ {
if (roughness >= 0.125) if (roughness >= 0.125)
@ -1062,6 +1071,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
} }
// //
// specularScale <rgb> <gloss> // specularScale <rgb> <gloss>
// or specularScale <metallic> <smoothness> with r_pbr 1
// or specularScale <r> <g> <b> // or specularScale <r> <g> <b>
// or specularScale <r> <g> <b> <gloss> // or specularScale <r> <g> <b> <gloss>
// //
@ -1087,11 +1097,20 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
token = COM_ParseExt(text, qfalse); token = COM_ParseExt(text, qfalse);
if ( token[0] == 0 ) if ( token[0] == 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 // two values, rgb then gloss
stage->specularScale[3] = stage->specularScale[1]; stage->specularScale[3] = stage->specularScale[1];
stage->specularScale[1] = stage->specularScale[1] =
stage->specularScale[2] = stage->specularScale[0]; stage->specularScale[2] = stage->specularScale[0];
}
continue; continue;
} }
@ -2857,12 +2876,19 @@ static void InitShader( const char *name, int lightmapIndex ) {
// default normal/specular // default normal/specular
VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f); VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f);
if (r_pbr->integer)
{
stages[i].specularScale[0] = r_baseGloss->value;
}
else
{
stages[i].specularScale[0] = stages[i].specularScale[0] =
stages[i].specularScale[1] = stages[i].specularScale[1] =
stages[i].specularScale[2] = r_baseSpecular->value; stages[i].specularScale[2] = r_baseSpecular->value;
stages[i].specularScale[3] = r_baseGloss->value; stages[i].specularScale[3] = r_baseGloss->value;
} }
} }
}
/* /*
========================= =========================

View File

@ -222,6 +222,12 @@ Cvars for advanced material usage:
0.05 - Standard depth. (default) 0.05 - Standard depth. (default)
0.1 - Looks broken. 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: Cvars for image interpolation and generation:
* `r_imageUpsample` - Use interpolation to artifically increase * `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. * `r_shadowCascadeZBias` - Z-bias for shadow cascade frustums.
-256 - Default. -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: Cvars that have broken bits:
* `r_dlightMode` - Change how dynamic lights look. * `r_dlightMode` - Change how dynamic lights look.