This is an automated email from the git hooks/post-receive script. smcv pushed a commit to annotated tag 1.42d in repository iortcw.
commit c53c848ee929715025155d5fdf6947510cb04be8 Author: m4n4t4...@gmail.com <m4n4t4...@gmail.com@e65d2741-a53d-b2dc-ae96-bb75fa5e4c4a> Date: Wed Apr 16 18:47:26 2014 +0000 All: Rend2: Remove sRGB support, replace with gamma cvars --- MP/code/rend2/glsl/calclevels4x_fp.glsl | 9 ++- MP/code/rend2/glsl/lightall_fp.glsl | 113 +++++++++++++++++----------- MP/code/rend2/glsl/lightall_vp.glsl | 8 -- MP/code/rend2/glsl/tonemap_fp.glsl | 9 +++ MP/code/rend2/tr_extensions.c | 46 ------------ MP/code/rend2/tr_glsl.c | 12 +++ MP/code/rend2/tr_image.c | 128 +++++++------------------------- MP/code/rend2/tr_init.c | 10 ++- MP/code/rend2/tr_local.h | 9 +-- MP/code/rend2/tr_main.c | 2 +- MP/code/rend2/tr_shader.c | 15 ---- MP/rend2-readme.txt | 84 +++++++++++++++++++-- SP/code/rend2/glsl/calclevels4x_fp.glsl | 9 ++- SP/code/rend2/glsl/lightall_fp.glsl | 113 +++++++++++++++++----------- SP/code/rend2/glsl/lightall_vp.glsl | 8 -- SP/code/rend2/glsl/tonemap_fp.glsl | 9 +++ SP/code/rend2/tr_extensions.c | 46 ------------ SP/code/rend2/tr_glsl.c | 12 +++ SP/code/rend2/tr_image.c | 128 +++++++------------------------- SP/code/rend2/tr_init.c | 10 ++- SP/code/rend2/tr_local.h | 9 +-- SP/code/rend2/tr_main.c | 2 +- SP/code/rend2/tr_shader.c | 15 ---- SP/rend2-readme.txt | 84 +++++++++++++++++++-- 24 files changed, 432 insertions(+), 458 deletions(-) diff --git a/MP/code/rend2/glsl/calclevels4x_fp.glsl b/MP/code/rend2/glsl/calclevels4x_fp.glsl index c8cf06c..1de59e9 100644 --- a/MP/code/rend2/glsl/calclevels4x_fp.glsl +++ b/MP/code/rend2/glsl/calclevels4x_fp.glsl @@ -9,10 +9,15 @@ const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0.299, 0.5 vec3 GetValues(vec2 offset, vec3 current) { - vec3 minAvgMax; - vec2 tc = var_TexCoords + u_InvTexRes * offset; minAvgMax = texture2D(u_TextureMap, tc).rgb; + vec2 tc = var_TexCoords + u_InvTexRes * offset; + vec3 minAvgMax = texture2D(u_TextureMap, tc).rgb; #ifdef FIRST_PASS + + #if defined(r_framebufferGamma) + minAvgMax = pow(minAvgMax, vec3(r_framebufferGamma)); + #endif + float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001); float loglumi = clamp(log2(lumi), -10.0, 10.0); minAvgMax = vec3(loglumi * 0.05 + 0.5); diff --git a/MP/code/rend2/glsl/lightall_fp.glsl b/MP/code/rend2/glsl/lightall_fp.glsl index 0f50a03..7c62d66 100644 --- a/MP/code/rend2/glsl/lightall_fp.glsl +++ b/MP/code/rend2/glsl/lightall_fp.glsl @@ -65,10 +65,6 @@ varying vec3 var_ViewDir; #endif #endif -#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) -varying vec3 var_LightColor; -#endif - #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) varying vec4 var_LightDir; #endif @@ -329,9 +325,9 @@ mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv ) void main() { - vec3 viewDir; + vec3 viewDir, lightColor, ambientColor; vec3 L, N, E, H; - float NL, NH, NE, EH; + float NL, NH, NE, EH, attenuation; #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) #if defined(USE_VERT_TANGENT_SPACE) @@ -352,16 +348,10 @@ void main() #endif #if defined(USE_LIGHTMAP) - vec4 lightSample = texture2D(u_LightMap, var_TexCoords.zw); - vec3 lightColor = lightSample.rgb; + vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw); #if defined(RGBM_LIGHTMAP) - lightColor *= lightSample.a; + lightmapColor.rgb *= lightmapColor.a; #endif -#elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) - vec3 lightColor = u_DirectedLight * CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist); - vec3 ambientColor = u_AmbientLight; -#elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - vec3 lightColor = var_LightColor; #endif vec2 texCoords = var_TexCoords.xy; @@ -375,12 +365,22 @@ void main() #endif vec4 diffuse = texture2D(u_DiffuseMap, texCoords); -#if defined(USE_GAMMA2_TEXTURES) - diffuse.rgb *= diffuse.rgb; -#endif - #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; + #endif + #if defined(USE_NORMALMAP) #if defined(SWIZZLE_NORMALMAP) N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5); @@ -416,8 +416,13 @@ 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) - vec3 ambientColor = lightColor; + ambientColor = lightColor; float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); // Scale the incoming light to compensate for the baked-in light angle @@ -426,7 +431,7 @@ void main() // Recover any unused light as ambient, in case attenuation is over 4x or // light is below the surface - ambientColor -= lightColor * surfNL; + ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0); #endif vec3 reflectance; @@ -436,15 +441,17 @@ void main() #if defined(USE_SPECULARMAP) vec4 specular = texture2D(u_SpecularMap, texCoords); - #if defined(USE_GAMMA2_TEXTURES) - specular.rgb *= specular.rgb; - #endif #else vec4 specular = vec4(1.0); #endif specular *= u_SpecularScale; + #if defined(r_materialGamma) + diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); + specular.rgb = pow(specular.rgb, vec3(r_materialGamma)); + #endif + float gloss = specular.a; float shininess = exp2(gloss * 13.0); @@ -482,7 +489,7 @@ void main() #endif #endif - gl_FragColor.rgb = lightColor * reflectance * NL; + gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); #if 0 vec3 aSpecular = EnvironmentBRDF(gloss, NE, specular.rgb); @@ -506,19 +513,23 @@ void main() // parallax corrected cubemap (cheaper trick) // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ - R += u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; + vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; - vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 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; - #if defined(USE_LIGHTMAP) - cubeLightColor *= lightSample.rgb; - #elif defined (USE_LIGHT_VERTEX) - cubeLightColor *= var_LightColor; - #else - cubeLightColor *= lightColor * NL + ambientColor; - #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 + //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)); + #endif + + // multiply cubemap values by lighting + // not technically correct, but helps make reflections look less unnatural + //cubeLightColor *= lightColor * (attenuation * NL) + ambientColor; - //gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb * u_EnableTextures.w; gl_FragColor.rgb += cubeLightColor * reflectance; #endif @@ -541,25 +552,43 @@ void main() reflectance = CalcDiffuse(diffuse.rgb, N, L2, E, NE, NL2, shininess); reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, gloss, shininess); - lightColor = u_PrimaryLightColor; + lightColor = u_PrimaryLightColor * var_Color.rgb; - // enable when point lights are supported as primary lights - //lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist); + #if defined(r_lightGamma) + lightColor = pow(lightColor, vec3(r_lightGamma)); + #endif #if defined(USE_SHADOWMAP) lightColor *= shadowValue; #endif + // enable when point lights are supported as primary lights + //lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist); + gl_FragColor.rgb += lightColor * reflectance * NL2; #endif - - gl_FragColor.a = diffuse.a; #else - gl_FragColor = diffuse; + lightColor = var_Color.rgb; + #if defined(USE_LIGHTMAP) - gl_FragColor.rgb *= lightColor; + 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 *= var_Color; + gl_FragColor.a = diffuse.a * var_Color.a; } diff --git a/MP/code/rend2/glsl/lightall_vp.glsl b/MP/code/rend2/glsl/lightall_vp.glsl index 2e1c899..b9e839d 100644 --- a/MP/code/rend2/glsl/lightall_vp.glsl +++ b/MP/code/rend2/glsl/lightall_vp.glsl @@ -83,10 +83,6 @@ varying vec3 var_ViewDir; #endif #endif -#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) -varying vec3 var_LightColor; -#endif - #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) varying vec4 var_LightDir; #endif @@ -216,10 +212,6 @@ void main() #endif var_Color = u_VertColor * attr_Color + u_BaseColor; -#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - var_LightColor = var_Color.rgb; - var_Color.rgb = vec3(1.0); -#endif #if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT) float sqrLightDist = dot(L, L); diff --git a/MP/code/rend2/glsl/tonemap_fp.glsl b/MP/code/rend2/glsl/tonemap_fp.glsl index 9b18de8..4c914ac 100644 --- a/MP/code/rend2/glsl/tonemap_fp.glsl +++ b/MP/code/rend2/glsl/tonemap_fp.glsl @@ -32,6 +32,11 @@ vec3 FilmicTonemap(vec3 x) void main() { vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color; + + #if defined(r_framebufferGamma) + color.rgb = pow(color.rgb, vec3(r_framebufferGamma)); + #endif + vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; vec3 logMinAvgMaxLum = clamp(minAvgMax * 20.0 - 10.0, -u_AutoExposureMinMax.y, -u_AutoExposureMinMax.x); @@ -44,5 +49,9 @@ void main() vec3 fWhite = 1.0 / FilmicTonemap(vec3(u_ToneMinAvgMaxLinear.z - u_ToneMinAvgMaxLinear.x)); color.rgb = FilmicTonemap(color.rgb) * fWhite; + #if defined(r_tonemapGamma) + color.rgb = pow(color.rgb, vec3(1.0 / r_tonemapGamma)); + #endif + gl_FragColor = clamp(color, 0.0, 1.0); } diff --git a/MP/code/rend2/tr_extensions.c b/MP/code/rend2/tr_extensions.c index 3d65369..10a1cb3 100644 --- a/MP/code/rend2/tr_extensions.c +++ b/MP/code/rend2/tr_extensions.c @@ -593,52 +593,6 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } - // GL_EXT_texture_sRGB - extension = "GL_EXT_texture_sRGB"; - glRefConfig.textureSrgb = qfalse; - if (GLimp_HaveExtension(extension)) - { - if (r_srgb->integer) - glRefConfig.textureSrgb = qtrue; - - ri.Printf(PRINT_ALL, result[glRefConfig.textureSrgb], extension); - } - else - { - ri.Printf(PRINT_ALL, result[2], extension); - } - - // GL_EXT_framebuffer_sRGB - extension = "GL_EXT_framebuffer_sRGB"; - glRefConfig.framebufferSrgb = qfalse; - if (GLimp_HaveExtension(extension)) - { - if (r_srgb->integer) - glRefConfig.framebufferSrgb = qtrue; - - ri.Printf(PRINT_ALL, result[glRefConfig.framebufferSrgb], extension); - } - else - { - ri.Printf(PRINT_ALL, result[2], extension); - } - - // GL_EXT_texture_sRGB_decode - extension = "GL_EXT_texture_sRGB_decode"; - glRefConfig.textureSrgbDecode = qfalse; - if (GLimp_HaveExtension(extension)) - { - if (r_srgb->integer) - glRefConfig.textureSrgbDecode = qtrue; - - ri.Printf(PRINT_ALL, result[glRefConfig.textureSrgbDecode], extension); - } - else - { - ri.Printf(PRINT_ALL, result[2], extension); - } - - glRefConfig.textureCompression = TCR_NONE; // GL_EXT_texture_compression_latc diff --git a/MP/code/rend2/tr_glsl.c b/MP/code/rend2/tr_glsl.c index 29a3e21..a206d29 100644 --- a/MP/code/rend2/tr_glsl.c +++ b/MP/code/rend2/tr_glsl.c @@ -321,6 +321,18 @@ 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 (extra) { Q_strcat(dest, size, extra); diff --git a/MP/code/rend2/tr_image.c b/MP/code/rend2/tr_image.c index e46fa86..47e28f3 100644 --- a/MP/code/rend2/tr_image.c +++ b/MP/code/rend2/tr_image.c @@ -1445,6 +1445,7 @@ Operates in place, quartering the size of the texture Proper linear filter ================ */ +#if 0 static void R_MipMap2( byte *in, int inWidth, int inHeight ) { int i, j, k; byte *outpix; @@ -1492,6 +1493,7 @@ static void R_MipMap2( byte *in, int inWidth, int inHeight ) { memcpy( in, temp, outWidth * outHeight * 4 ); ri.Hunk_FreeTempMemory( temp ); } +#endif static void R_MipMapsRGB( byte *in, int inWidth, int inHeight) { @@ -1541,6 +1543,7 @@ R_MipMap Operates in place, quartering the size of the texture ================ */ +#if 0 static void R_MipMap( byte *in, int width, int height ) { int i, j; byte *out; @@ -1580,6 +1583,7 @@ static void R_MipMap( byte *in, int width, int height ) { } } } +#endif static void R_MipMapLuminanceAlpha (const byte *in, byte *out, int width, int height) { @@ -2064,61 +2068,6 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light } } } - - if (glRefConfig.textureSrgb && (flags & IMGFLAG_SRGB)) - { - switch(internalFormat) - { - case GL_RGB: - internalFormat = GL_SRGB_EXT; - break; - - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - internalFormat = GL_SRGB8_EXT; - break; - - case GL_RGBA: - internalFormat = GL_SRGB_ALPHA_EXT; - break; - - case GL_RGBA4: - case GL_RGBA8: - internalFormat = GL_SRGB8_ALPHA8_EXT; - break; - - case GL_LUMINANCE: - internalFormat = GL_SLUMINANCE_EXT; - break; - - case GL_LUMINANCE8: - case GL_LUMINANCE16: - internalFormat = GL_SLUMINANCE8_EXT; - break; - - case GL_LUMINANCE_ALPHA: - internalFormat = GL_SLUMINANCE_ALPHA_EXT; - break; - - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE16_ALPHA16: - internalFormat = GL_SLUMINANCE8_ALPHA8_EXT; - break; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; - break; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - break; - - case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB; - break; - } - } } return internalFormat; @@ -2173,13 +2122,9 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei R_MipMapNormalHeight( data, data, width, height, qtrue); } } - else if (flags & IMGFLAG_SRGB) - { - R_MipMapsRGB( data, width, height ); - } else { - R_MipMap( data, width, height ); + R_MipMapsRGB( data, width, height ); } } @@ -2269,26 +2214,6 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag } } - // Convert to RGB if sRGB textures aren't supported in hardware - if (!glRefConfig.textureSrgb && (flags & IMGFLAG_SRGB)) - { - byte *in = data; - int c = width * height; - while (c--) - { - for (i = 0; i < 3; i++) - { - float x = ByteToFloat(in[i]); - x = sRGBtoRGB(x); - in[i] = FloatToByte(x); - } - in += 4; - } - - // FIXME: Probably should mark the image as non-sRGB as well - flags &= ~IMGFLAG_SRGB; - } - // normals are always swizzled if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) { @@ -2327,13 +2252,20 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag // use the normal mip-mapping function to go down from here while ( width > scaled_width || height > scaled_height ) { - if (flags & IMGFLAG_SRGB) + if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) { - R_MipMapsRGB( (byte *)data, width, height ); + if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) + { + R_MipMapLuminanceAlpha( data, data, width, height ); + } + else + { + R_MipMapNormalHeight( data, data, width, height, qtrue); + } } else { - R_MipMap( (byte *)data, width, height ); + R_MipMapsRGB( data, width, height ); } width >>= 1; @@ -2629,13 +2561,20 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h // use the normal mip-mapping function to go down from here while ( width > scaled_width || height > scaled_height ) { - if (image->flags & IMGFLAG_SRGB) + if (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT) { - R_MipMapsRGB( (byte *)data, width, height ); + if (image->internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) + { + R_MipMapLuminanceAlpha( data, data, width, height ); + } + else + { + R_MipMapNormalHeight( data, data, width, height, qtrue); + } } else { - R_MipMap( (byte *)data, width, height ); + R_MipMapsRGB( data, width, height ); } width >>= 1; @@ -2827,7 +2766,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) int normalWidth, normalHeight; imgFlags_t normalFlags; - normalFlags = (flags & ~(IMGFLAG_GENNORMALMAP | IMGFLAG_SRGB)) | IMGFLAG_NOLIGHTSCALE; + normalFlags = (flags & ~IMGFLAG_GENNORMALMAP) | IMGFLAG_NOLIGHTSCALE; COM_StripExtension(name, normalName, MAX_QPATH); Q_strcat(normalName, MAX_QPATH, "_n"); @@ -3274,21 +3213,10 @@ void R_SetColorMappings( void ) { g = r_gamma->value; for ( i = 0; i < 256; i++ ) { - int i2; - - if (r_srgb->integer) - { - i2 = 255 * RGBtosRGB(i/255.0f) + 0.5f; - } - else - { - i2 = i; - } - if ( g == 1 ) { - inf = i2; + inf = i; } else { - inf = 255 * pow ( i2/255.0f, 1.0f / g ) + 0.5f; + inf = 255 * pow ( i/255.0f, 1.0f / g ) + 0.5f; } if ( inf < 0 ) { diff --git a/MP/code/rend2/tr_init.c b/MP/code/rend2/tr_init.c index 30e7ebd..0660d9c 100644 --- a/MP/code/rend2/tr_init.c +++ b/MP/code/rend2/tr_init.c @@ -145,7 +145,10 @@ cvar_t *r_forceAutoExposure; cvar_t *r_forceAutoExposureMin; cvar_t *r_forceAutoExposureMax; -cvar_t *r_srgb; +cvar_t *r_materialGamma; +cvar_t *r_lightGamma; +cvar_t *r_framebufferGamma; +cvar_t *r_tonemapGamma; cvar_t *r_depthPrepass; cvar_t *r_ssao; @@ -1296,7 +1299,10 @@ void R_Register( void ) { r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT ); - r_srgb = ri.Cvar_Get( "r_srgb", "0", CVAR_ARCHIVE | CVAR_LATCH ); + 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 ); diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h index f7f49f0..0e93fb8 100644 --- a/MP/code/rend2/tr_local.h +++ b/MP/code/rend2/tr_local.h @@ -1547,10 +1547,6 @@ typedef struct { qboolean framebufferMultisample; qboolean framebufferBlit; - qboolean textureSrgb; - qboolean framebufferSrgb; - qboolean textureSrgbDecode; - qboolean depthClamp; qboolean seamlessCubeMap; @@ -1982,7 +1978,10 @@ extern cvar_t *r_forceAutoExposureMax; extern cvar_t *r_cameraExposure; -extern cvar_t *r_srgb; +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; diff --git a/MP/code/rend2/tr_main.c b/MP/code/rend2/tr_main.c index 72763b0..f473875 100644 --- a/MP/code/rend2/tr_main.c +++ b/MP/code/rend2/tr_main.c @@ -3141,7 +3141,7 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) { vec3_t ambient, directed, lightDir; R_LightForPoint(tr.refdef.vieworg, ambient, directed, lightDir); - tr.refdef.colorScale = 766.0f / (directed[0] + directed[1] + directed[2] + 1.0f); + tr.refdef.colorScale = 1.0f; //766.0f / (directed[0] + directed[1] + directed[2] + 1.0f); // only print message for first side if (directed[0] + directed[1] + directed[2] == 0 && cubemapSide == 0) { diff --git a/MP/code/rend2/tr_shader.c b/MP/code/rend2/tr_shader.c index bc1a0b6..6e2cc16 100644 --- a/MP/code/rend2/tr_shader.c +++ b/MP/code/rend2/tr_shader.c @@ -671,9 +671,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { { if (r_genNormalMaps->integer) flags |= IMGFLAG_GENNORMALMAP; - - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; } stage->bundle[0].image[0] = R_FindImageFile( token, type, flags ); @@ -715,9 +712,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { { if (r_genNormalMaps->integer) flags |= IMGFLAG_GENNORMALMAP; - - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; } @@ -756,9 +750,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { if (!shader.noPicMip) flags |= IMGFLAG_PICMIP; - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; - stage->bundle[0].image[num] = R_FindImageFile( token, IMGTYPE_COLORALPHA, flags ); if ( !stage->bundle[0].image[num] ) { ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name ); @@ -1441,9 +1432,6 @@ static void ParseSkyParms( char **text ) { int i; imgFlags_t imgFlags = IMGFLAG_MIPMAP | IMGFLAG_PICMIP; - if (r_srgb->integer) - imgFlags |= IMGFLAG_SRGB; - // outerbox token = COM_ParseExt( text, qfalse ); if ( token[0] == 0 ) { @@ -3391,9 +3379,6 @@ shader_t *R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImag flags = IMGFLAG_NONE; - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; - if (mipRawImage) { flags |= IMGFLAG_MIPMAP | IMGFLAG_PICMIP; diff --git a/MP/rend2-readme.txt b/MP/rend2-readme.txt index 761756a..8293077 100644 --- a/MP/rend2-readme.txt +++ b/MP/rend2-readme.txt @@ -18,7 +18,7 @@ compatibility with existing RTCW mods. - Texture upsampling. - Advanced materials support. - Advanced shading and specular methods. - - sRGB support. + - Separate material/light/framebuffer/tonemap gamma. - LATC and BPTC texture compression support. - Screen-space ambient occlusion. @@ -163,13 +163,6 @@ Cvars for HDR and tonemapping: 2.0 - Normal. (default) 3.0 - Brighter. - r_srgb - Treat all input textures as sRGB, and do - final rendering in a sRGB framebuffer. Only - required if assets were created with it in - mind. - 0 - No. (default) - 1 - Yes. - Cvars for advanced material usage: r_normalMapping - Enable normal mapping for materials that support it, and also specify advanced @@ -317,6 +310,29 @@ Cvars for the sunlight and cascaded shadow maps: 2048 - 2048x2048, extreme. 4096 - 4096x4096, indistinguishable from 2048. + +Cvars for adjusting gamma values: + r_materialGamma - Gamma level for material textures. + (diffuse, specular) + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. + + r_lightGamma - Gamma level for light. + (lightmap, lightgrid, vertex lights) + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. + + r_framebufferGamma - Gamma level for framebuffers. + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. + + r_tonemapGamma - Gamma applied after tonemapping. + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. Cvars that you probably don't care about or shouldn't mess with: r_mergeMultidraws - Optimize number of calls to @@ -600,6 +616,58 @@ adjust the effect before settling on fixed settings. ------------------------------------------------------------------------------- + MATERIAL/LIGHT/FRAMEBUFFER/TONEMAP GAMMA +------------------------------------------------------------------------------- + +This adds four cvars, r_materialGamma, r_lightGamma, r_framebufferGamma, and +r_tonemapGamma. These adjust the gamma levels of their corresponding texture +or color, allowing for more realistic lighting and shading. + +These settings are fastest: + + r_materialGamma 1 + r_lightGamma 1 + r_framebufferGamma 1 + r_tonemapGamma 1 + +This is the same as Quake 3 behaviour, where colors are not adjusted for gamma +until presentation to the screen. + +These settings are more accurate: + + r_materialGamma 2 + r_lightGamma 2 + r_framebufferGamma 2 + r_tonemapGamma 2 + +This converts diffuse/specular from gamma 2 space to linear space +(r_materialGamma 2), converts light values similarly (r_lightGamma 2), +converts those to the gamma 2 of the framebuffer (r_framebufferGamma 2), and +converts to a monitor gamma of 2 after tonemapping (r_tonemapGamma 2). + +These settings are the most accurate: + + r_materialGamma 2.2 + r_lightGamma 2.2 + r_framebufferGamma 2.2 + r_tonemapGamma 2.2 + +This is the same as the previous, except using a more correct gamma of 2.2, +which approximates sRGB. + +The only issue with these last two examples are that dlights aren't added +linearly, since they are still performed as a straight add to a non-linear +framebuffer. To fix this, these settings are possible: + + r_materialGamma 2.2 + r_lightGamma 2.2 + r_framebufferGamma 1.0 + r_tonemapGamma 2.2 + +But these cause UI draws to have the wrong gamma, as these are rendered after +tonemapping. I recommend the use of the second or third set of settings. + +------------------------------------------------------------------------------- THANKS ------------------------------------------------------------------------------- diff --git a/SP/code/rend2/glsl/calclevels4x_fp.glsl b/SP/code/rend2/glsl/calclevels4x_fp.glsl index c8cf06c..1de59e9 100644 --- a/SP/code/rend2/glsl/calclevels4x_fp.glsl +++ b/SP/code/rend2/glsl/calclevels4x_fp.glsl @@ -9,10 +9,15 @@ const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0.299, 0.5 vec3 GetValues(vec2 offset, vec3 current) { - vec3 minAvgMax; - vec2 tc = var_TexCoords + u_InvTexRes * offset; minAvgMax = texture2D(u_TextureMap, tc).rgb; + vec2 tc = var_TexCoords + u_InvTexRes * offset; + vec3 minAvgMax = texture2D(u_TextureMap, tc).rgb; #ifdef FIRST_PASS + + #if defined(r_framebufferGamma) + minAvgMax = pow(minAvgMax, vec3(r_framebufferGamma)); + #endif + float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001); float loglumi = clamp(log2(lumi), -10.0, 10.0); minAvgMax = vec3(loglumi * 0.05 + 0.5); diff --git a/SP/code/rend2/glsl/lightall_fp.glsl b/SP/code/rend2/glsl/lightall_fp.glsl index 0f50a03..7c62d66 100644 --- a/SP/code/rend2/glsl/lightall_fp.glsl +++ b/SP/code/rend2/glsl/lightall_fp.glsl @@ -65,10 +65,6 @@ varying vec3 var_ViewDir; #endif #endif -#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) -varying vec3 var_LightColor; -#endif - #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) varying vec4 var_LightDir; #endif @@ -329,9 +325,9 @@ mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv ) void main() { - vec3 viewDir; + vec3 viewDir, lightColor, ambientColor; vec3 L, N, E, H; - float NL, NH, NE, EH; + float NL, NH, NE, EH, attenuation; #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) #if defined(USE_VERT_TANGENT_SPACE) @@ -352,16 +348,10 @@ void main() #endif #if defined(USE_LIGHTMAP) - vec4 lightSample = texture2D(u_LightMap, var_TexCoords.zw); - vec3 lightColor = lightSample.rgb; + vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw); #if defined(RGBM_LIGHTMAP) - lightColor *= lightSample.a; + lightmapColor.rgb *= lightmapColor.a; #endif -#elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) - vec3 lightColor = u_DirectedLight * CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist); - vec3 ambientColor = u_AmbientLight; -#elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - vec3 lightColor = var_LightColor; #endif vec2 texCoords = var_TexCoords.xy; @@ -375,12 +365,22 @@ void main() #endif vec4 diffuse = texture2D(u_DiffuseMap, texCoords); -#if defined(USE_GAMMA2_TEXTURES) - diffuse.rgb *= diffuse.rgb; -#endif - #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; + #endif + #if defined(USE_NORMALMAP) #if defined(SWIZZLE_NORMALMAP) N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5); @@ -416,8 +416,13 @@ 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) - vec3 ambientColor = lightColor; + ambientColor = lightColor; float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); // Scale the incoming light to compensate for the baked-in light angle @@ -426,7 +431,7 @@ void main() // Recover any unused light as ambient, in case attenuation is over 4x or // light is below the surface - ambientColor -= lightColor * surfNL; + ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0); #endif vec3 reflectance; @@ -436,15 +441,17 @@ void main() #if defined(USE_SPECULARMAP) vec4 specular = texture2D(u_SpecularMap, texCoords); - #if defined(USE_GAMMA2_TEXTURES) - specular.rgb *= specular.rgb; - #endif #else vec4 specular = vec4(1.0); #endif specular *= u_SpecularScale; + #if defined(r_materialGamma) + diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); + specular.rgb = pow(specular.rgb, vec3(r_materialGamma)); + #endif + float gloss = specular.a; float shininess = exp2(gloss * 13.0); @@ -482,7 +489,7 @@ void main() #endif #endif - gl_FragColor.rgb = lightColor * reflectance * NL; + gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); #if 0 vec3 aSpecular = EnvironmentBRDF(gloss, NE, specular.rgb); @@ -506,19 +513,23 @@ void main() // parallax corrected cubemap (cheaper trick) // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ - R += u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; + vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; - vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 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; - #if defined(USE_LIGHTMAP) - cubeLightColor *= lightSample.rgb; - #elif defined (USE_LIGHT_VERTEX) - cubeLightColor *= var_LightColor; - #else - cubeLightColor *= lightColor * NL + ambientColor; - #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 + //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)); + #endif + + // multiply cubemap values by lighting + // not technically correct, but helps make reflections look less unnatural + //cubeLightColor *= lightColor * (attenuation * NL) + ambientColor; - //gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb * u_EnableTextures.w; gl_FragColor.rgb += cubeLightColor * reflectance; #endif @@ -541,25 +552,43 @@ void main() reflectance = CalcDiffuse(diffuse.rgb, N, L2, E, NE, NL2, shininess); reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, gloss, shininess); - lightColor = u_PrimaryLightColor; + lightColor = u_PrimaryLightColor * var_Color.rgb; - // enable when point lights are supported as primary lights - //lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist); + #if defined(r_lightGamma) + lightColor = pow(lightColor, vec3(r_lightGamma)); + #endif #if defined(USE_SHADOWMAP) lightColor *= shadowValue; #endif + // enable when point lights are supported as primary lights + //lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist); + gl_FragColor.rgb += lightColor * reflectance * NL2; #endif - - gl_FragColor.a = diffuse.a; #else - gl_FragColor = diffuse; + lightColor = var_Color.rgb; + #if defined(USE_LIGHTMAP) - gl_FragColor.rgb *= lightColor; + 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 *= var_Color; + gl_FragColor.a = diffuse.a * var_Color.a; } diff --git a/SP/code/rend2/glsl/lightall_vp.glsl b/SP/code/rend2/glsl/lightall_vp.glsl index 2e1c899..b9e839d 100644 --- a/SP/code/rend2/glsl/lightall_vp.glsl +++ b/SP/code/rend2/glsl/lightall_vp.glsl @@ -83,10 +83,6 @@ varying vec3 var_ViewDir; #endif #endif -#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) -varying vec3 var_LightColor; -#endif - #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) varying vec4 var_LightDir; #endif @@ -216,10 +212,6 @@ void main() #endif var_Color = u_VertColor * attr_Color + u_BaseColor; -#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - var_LightColor = var_Color.rgb; - var_Color.rgb = vec3(1.0); -#endif #if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT) float sqrLightDist = dot(L, L); diff --git a/SP/code/rend2/glsl/tonemap_fp.glsl b/SP/code/rend2/glsl/tonemap_fp.glsl index 9b18de8..4c914ac 100644 --- a/SP/code/rend2/glsl/tonemap_fp.glsl +++ b/SP/code/rend2/glsl/tonemap_fp.glsl @@ -32,6 +32,11 @@ vec3 FilmicTonemap(vec3 x) void main() { vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color; + + #if defined(r_framebufferGamma) + color.rgb = pow(color.rgb, vec3(r_framebufferGamma)); + #endif + vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; vec3 logMinAvgMaxLum = clamp(minAvgMax * 20.0 - 10.0, -u_AutoExposureMinMax.y, -u_AutoExposureMinMax.x); @@ -44,5 +49,9 @@ void main() vec3 fWhite = 1.0 / FilmicTonemap(vec3(u_ToneMinAvgMaxLinear.z - u_ToneMinAvgMaxLinear.x)); color.rgb = FilmicTonemap(color.rgb) * fWhite; + #if defined(r_tonemapGamma) + color.rgb = pow(color.rgb, vec3(1.0 / r_tonemapGamma)); + #endif + gl_FragColor = clamp(color, 0.0, 1.0); } diff --git a/SP/code/rend2/tr_extensions.c b/SP/code/rend2/tr_extensions.c index 3d65369..10a1cb3 100644 --- a/SP/code/rend2/tr_extensions.c +++ b/SP/code/rend2/tr_extensions.c @@ -593,52 +593,6 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } - // GL_EXT_texture_sRGB - extension = "GL_EXT_texture_sRGB"; - glRefConfig.textureSrgb = qfalse; - if (GLimp_HaveExtension(extension)) - { - if (r_srgb->integer) - glRefConfig.textureSrgb = qtrue; - - ri.Printf(PRINT_ALL, result[glRefConfig.textureSrgb], extension); - } - else - { - ri.Printf(PRINT_ALL, result[2], extension); - } - - // GL_EXT_framebuffer_sRGB - extension = "GL_EXT_framebuffer_sRGB"; - glRefConfig.framebufferSrgb = qfalse; - if (GLimp_HaveExtension(extension)) - { - if (r_srgb->integer) - glRefConfig.framebufferSrgb = qtrue; - - ri.Printf(PRINT_ALL, result[glRefConfig.framebufferSrgb], extension); - } - else - { - ri.Printf(PRINT_ALL, result[2], extension); - } - - // GL_EXT_texture_sRGB_decode - extension = "GL_EXT_texture_sRGB_decode"; - glRefConfig.textureSrgbDecode = qfalse; - if (GLimp_HaveExtension(extension)) - { - if (r_srgb->integer) - glRefConfig.textureSrgbDecode = qtrue; - - ri.Printf(PRINT_ALL, result[glRefConfig.textureSrgbDecode], extension); - } - else - { - ri.Printf(PRINT_ALL, result[2], extension); - } - - glRefConfig.textureCompression = TCR_NONE; // GL_EXT_texture_compression_latc diff --git a/SP/code/rend2/tr_glsl.c b/SP/code/rend2/tr_glsl.c index 29a3e21..a206d29 100644 --- a/SP/code/rend2/tr_glsl.c +++ b/SP/code/rend2/tr_glsl.c @@ -321,6 +321,18 @@ 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 (extra) { Q_strcat(dest, size, extra); diff --git a/SP/code/rend2/tr_image.c b/SP/code/rend2/tr_image.c index c4e5df0..87c79d5 100644 --- a/SP/code/rend2/tr_image.c +++ b/SP/code/rend2/tr_image.c @@ -1434,6 +1434,7 @@ Operates in place, quartering the size of the texture Proper linear filter ================ */ +#if 0 static void R_MipMap2( byte *in, int inWidth, int inHeight ) { int i, j, k; byte *outpix; @@ -1481,6 +1482,7 @@ static void R_MipMap2( byte *in, int inWidth, int inHeight ) { memcpy( in, temp, outWidth * outHeight * 4 ); ri.Hunk_FreeTempMemory( temp ); } +#endif static void R_MipMapsRGB( byte *in, int inWidth, int inHeight) { @@ -1530,6 +1532,7 @@ R_MipMap Operates in place, quartering the size of the texture ================ */ +#if 0 static void R_MipMap( byte *in, int width, int height ) { int i, j; byte *out; @@ -1569,6 +1572,7 @@ static void R_MipMap( byte *in, int width, int height ) { } } } +#endif static void R_MipMapLuminanceAlpha (const byte *in, byte *out, int width, int height) { @@ -2052,61 +2056,6 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light } } } - - if (glRefConfig.textureSrgb && (flags & IMGFLAG_SRGB)) - { - switch(internalFormat) - { - case GL_RGB: - internalFormat = GL_SRGB_EXT; - break; - - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - internalFormat = GL_SRGB8_EXT; - break; - - case GL_RGBA: - internalFormat = GL_SRGB_ALPHA_EXT; - break; - - case GL_RGBA4: - case GL_RGBA8: - internalFormat = GL_SRGB8_ALPHA8_EXT; - break; - - case GL_LUMINANCE: - internalFormat = GL_SLUMINANCE_EXT; - break; - - case GL_LUMINANCE8: - case GL_LUMINANCE16: - internalFormat = GL_SLUMINANCE8_EXT; - break; - - case GL_LUMINANCE_ALPHA: - internalFormat = GL_SLUMINANCE_ALPHA_EXT; - break; - - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE16_ALPHA16: - internalFormat = GL_SLUMINANCE8_ALPHA8_EXT; - break; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; - break; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - break; - - case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB; - break; - } - } } return internalFormat; @@ -2161,13 +2110,9 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei R_MipMapNormalHeight( data, data, width, height, qtrue); } } - else if (flags & IMGFLAG_SRGB) - { - R_MipMapsRGB( data, width, height ); - } else { - R_MipMap( data, width, height ); + R_MipMapsRGB( data, width, height ); } } @@ -2257,26 +2202,6 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag } } - // Convert to RGB if sRGB textures aren't supported in hardware - if (!glRefConfig.textureSrgb && (flags & IMGFLAG_SRGB)) - { - byte *in = data; - int c = width * height; - while (c--) - { - for (i = 0; i < 3; i++) - { - float x = ByteToFloat(in[i]); - x = sRGBtoRGB(x); - in[i] = FloatToByte(x); - } - in += 4; - } - - // FIXME: Probably should mark the image as non-sRGB as well - flags &= ~IMGFLAG_SRGB; - } - // normals are always swizzled if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) { @@ -2315,13 +2240,20 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag // use the normal mip-mapping function to go down from here while ( width > scaled_width || height > scaled_height ) { - if (flags & IMGFLAG_SRGB) + if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) { - R_MipMapsRGB( (byte *)data, width, height ); + if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) + { + R_MipMapLuminanceAlpha( data, data, width, height ); + } + else + { + R_MipMapNormalHeight( data, data, width, height, qtrue); + } } else { - R_MipMap( (byte *)data, width, height ); + R_MipMapsRGB( data, width, height ); } width >>= 1; @@ -2628,13 +2560,20 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h // use the normal mip-mapping function to go down from here while ( width > scaled_width || height > scaled_height ) { - if (image->flags & IMGFLAG_SRGB) + if (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT) { - R_MipMapsRGB( (byte *)data, width, height ); + if (image->internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) + { + R_MipMapLuminanceAlpha( data, data, width, height ); + } + else + { + R_MipMapNormalHeight( data, data, width, height, qtrue); + } } else { - R_MipMap( (byte *)data, width, height ); + R_MipMapsRGB( data, width, height ); } width >>= 1; @@ -2832,7 +2771,7 @@ image_t *R_FindImageFileExt( const char *name, imgType_t type, imgFlags_t flags, int normalWidth, normalHeight; imgFlags_t normalFlags; - normalFlags = (flags & ~(IMGFLAG_GENNORMALMAP | IMGFLAG_SRGB)) | IMGFLAG_NOLIGHTSCALE; + normalFlags = (flags & ~IMGFLAG_GENNORMALMAP) | IMGFLAG_NOLIGHTSCALE; COM_StripExtension(name, normalName, MAX_QPATH); Q_strcat(normalName, MAX_QPATH, "_n"); @@ -3285,21 +3224,10 @@ void R_SetColorMappings( void ) { g = r_gamma->value; for ( i = 0; i < 256; i++ ) { - int i2; - - if (r_srgb->integer) - { - i2 = 255 * RGBtosRGB(i/255.0f) + 0.5f; - } - else - { - i2 = i; - } - if ( g == 1 ) { - inf = i2; + inf = i; } else { - inf = 255 * pow( i2 / 255.0f, 1.0f / g ) + 0.5f; + inf = 255 * pow( i/255.0f, 1.0f / g ) + 0.5f; } if ( inf < 0 ) { diff --git a/SP/code/rend2/tr_init.c b/SP/code/rend2/tr_init.c index 625bd39..6b55866 100644 --- a/SP/code/rend2/tr_init.c +++ b/SP/code/rend2/tr_init.c @@ -151,7 +151,10 @@ cvar_t *r_forceAutoExposure; cvar_t *r_forceAutoExposureMin; cvar_t *r_forceAutoExposureMax; -cvar_t *r_srgb; +cvar_t *r_materialGamma; +cvar_t *r_lightGamma; +cvar_t *r_framebufferGamma; +cvar_t *r_tonemapGamma; cvar_t *r_depthPrepass; cvar_t *r_ssao; @@ -1320,7 +1323,10 @@ void R_Register( void ) { r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT ); - r_srgb = ri.Cvar_Get( "r_srgb", "0", CVAR_ARCHIVE | CVAR_LATCH ); + 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 ); diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h index c1e743d..9493f17 100644 --- a/SP/code/rend2/tr_local.h +++ b/SP/code/rend2/tr_local.h @@ -1560,10 +1560,6 @@ typedef struct { qboolean framebufferMultisample; qboolean framebufferBlit; - qboolean textureSrgb; - qboolean framebufferSrgb; - qboolean textureSrgbDecode; - qboolean depthClamp; qboolean seamlessCubeMap; @@ -2001,7 +1997,10 @@ extern cvar_t *r_forceAutoExposureMax; extern cvar_t *r_cameraExposure; -extern cvar_t *r_srgb; +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; diff --git a/SP/code/rend2/tr_main.c b/SP/code/rend2/tr_main.c index 7fdee90..8b01b4a 100644 --- a/SP/code/rend2/tr_main.c +++ b/SP/code/rend2/tr_main.c @@ -3189,7 +3189,7 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) { vec3_t ambient, directed, lightDir; R_LightForPoint(tr.refdef.vieworg, ambient, directed, lightDir); - tr.refdef.colorScale = 766.0f / (directed[0] + directed[1] + directed[2] + 1.0f); + tr.refdef.colorScale = 1.0f; //766.0f / (directed[0] + directed[1] + directed[2] + 1.0f); // only print message for first side if (directed[0] + directed[1] + directed[2] == 0 && cubemapSide == 0) { diff --git a/SP/code/rend2/tr_shader.c b/SP/code/rend2/tr_shader.c index 41430d8..4dea754 100644 --- a/SP/code/rend2/tr_shader.c +++ b/SP/code/rend2/tr_shader.c @@ -671,9 +671,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { { if (r_genNormalMaps->integer) flags |= IMGFLAG_GENNORMALMAP; - - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; } stage->bundle[0].image[0] = R_FindImageFileExt( token, type, flags, shader.characterMip ); @@ -714,9 +711,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { { if (r_genNormalMaps->integer) flags |= IMGFLAG_GENNORMALMAP; - - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; } stage->bundle[0].image[0] = R_FindImageFileExt( token, type, flags, shader.characterMip ); @@ -754,9 +748,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { if (!shader.noPicMip) flags |= IMGFLAG_PICMIP; - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; - stage->bundle[0].image[num] = R_FindImageFileExt( token, IMGTYPE_COLORALPHA, flags, shader.characterMip ); if ( !stage->bundle[0].image[num] ) { ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFileExt could not find '%s' in shader '%s'\n", token, shader.name ); @@ -1441,9 +1432,6 @@ static void ParseSkyParms( char **text ) { int i; imgFlags_t imgFlags = IMGFLAG_MIPMAP | IMGFLAG_PICMIP; - if (r_srgb->integer) - imgFlags |= IMGFLAG_SRGB; - // outerbox token = COM_ParseExt( text, qfalse ); if ( token[0] == 0 ) { @@ -3442,9 +3430,6 @@ shader_t *R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImag flags = IMGFLAG_NONE; - if (r_srgb->integer) - flags |= IMGFLAG_SRGB; - if (mipRawImage) { flags |= IMGFLAG_MIPMAP | IMGFLAG_PICMIP; diff --git a/SP/rend2-readme.txt b/SP/rend2-readme.txt index 25ce65d..ba92660 100644 --- a/SP/rend2-readme.txt +++ b/SP/rend2-readme.txt @@ -18,7 +18,7 @@ compatibility with existing RTCW mods. - Texture upsampling. - Advanced materials support. - Advanced shading and specular methods. - - sRGB support. + - Separate material/light/framebuffer/tonemap gamma. - LATC and BPTC texture compression support. - Screen-space ambient occlusion. @@ -163,13 +163,6 @@ Cvars for HDR and tonemapping: 2.0 - Normal. (default) 3.0 - Brighter. - r_srgb - Treat all input textures as sRGB, and do - final rendering in a sRGB framebuffer. Only - required if assets were created with it in - mind. - 0 - No. (default) - 1 - Yes. - Cvars for advanced material usage: r_normalMapping - Enable normal mapping for materials that support it, and also specify advanced @@ -318,6 +311,29 @@ Cvars for the sunlight and cascaded shadow maps: 4096 - 4096x4096, indistinguishable from 2048. +Cvars for adjusting gamma values: + r_materialGamma - Gamma level for material textures. + (diffuse, specular) + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. + + r_lightGamma - Gamma level for light. + (lightmap, lightgrid, vertex lights) + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. + + r_framebufferGamma - Gamma level for framebuffers. + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. + + r_tonemapGamma - Gamma applied after tonemapping. + 1.0 - Quake 3, fastest. (default) + 2.0 - More accurate, slower. + 2.2 - Most accurate, slowest. + Cvars that you probably don't care about or shouldn't mess with: r_mergeMultidraws - Optimize number of calls to glMultiDrawElements(). @@ -600,6 +616,58 @@ adjust the effect before settling on fixed settings. ------------------------------------------------------------------------------- + MATERIAL/LIGHT/FRAMEBUFFER/TONEMAP GAMMA +------------------------------------------------------------------------------- + +This adds four cvars, r_materialGamma, r_lightGamma, r_framebufferGamma, and +r_tonemapGamma. These adjust the gamma levels of their corresponding texture +or color, allowing for more realistic lighting and shading. + +These settings are fastest: + + r_materialGamma 1 + r_lightGamma 1 + r_framebufferGamma 1 + r_tonemapGamma 1 + +This is the same as Quake 3 behaviour, where colors are not adjusted for gamma +until presentation to the screen. + +These settings are more accurate: + + r_materialGamma 2 + r_lightGamma 2 + r_framebufferGamma 2 + r_tonemapGamma 2 + +This converts diffuse/specular from gamma 2 space to linear space +(r_materialGamma 2), converts light values similarly (r_lightGamma 2), +converts those to the gamma 2 of the framebuffer (r_framebufferGamma 2), and +converts to a monitor gamma of 2 after tonemapping (r_tonemapGamma 2). + +These settings are the most accurate: + + r_materialGamma 2.2 + r_lightGamma 2.2 + r_framebufferGamma 2.2 + r_tonemapGamma 2.2 + +This is the same as the previous, except using a more correct gamma of 2.2, +which approximates sRGB. + +The only issue with these last two examples are that dlights aren't added +linearly, since they are still performed as a straight add to a non-linear +framebuffer. To fix this, these settings are possible: + + r_materialGamma 2.2 + r_lightGamma 2.2 + r_framebufferGamma 1.0 + r_tonemapGamma 2.2 + +But these cause UI draws to have the wrong gamma, as these are rendered after +tonemapping. I recommend the use of the second or third set of settings. + +------------------------------------------------------------------------------- THANKS ------------------------------------------------------------------------------- -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits