diff options
-rw-r--r-- | src/renderergl2/glsl/lightall_fp.glsl | 17 | ||||
-rw-r--r-- | src/renderergl2/tr_glsl.c | 7 | ||||
-rw-r--r-- | src/renderergl2/tr_init.c | 6 | ||||
-rw-r--r-- | src/renderergl2/tr_local.h | 11 | ||||
-rw-r--r-- | src/renderergl2/tr_shade.c | 31 | ||||
-rw-r--r-- | src/renderergl2/tr_shader.c | 146 |
6 files changed, 174 insertions, 44 deletions
diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index 871c527e..c74d6844 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -25,7 +25,8 @@ uniform samplerCube u_CubeMap; #endif #if defined(USE_NORMALMAP) || defined(USE_DELUXEMAP) || defined(USE_SPECULARMAP) || defined(USE_CUBEMAP) -uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube +// y = deluxe, w = cube +uniform vec4 u_EnableTextures; #endif #if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) @@ -39,7 +40,8 @@ uniform vec3 u_PrimaryLightAmbient; #endif #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) -uniform vec2 u_MaterialInfo; +uniform vec4 u_NormalScale; +uniform vec4 u_SpecularScale; #endif varying vec4 var_TexCoords; @@ -360,7 +362,7 @@ void main() #if defined(USE_PARALLAXMAP) vec3 offsetDir = normalize(E * tangentToWorld); - offsetDir.xy *= -0.05 / offsetDir.z; + offsetDir.xy *= -u_NormalScale.a / offsetDir.z; texCoords += offsetDir.xy * RayIntersectDisplaceMap(texCoords, offsetDir.xy, u_NormalMap); #endif @@ -378,7 +380,7 @@ void main() #else N.xy = texture2D(u_NormalMap, texCoords).rg - vec2(0.5); #endif - N.xy *= u_EnableTextures.x; + N.xy *= u_NormalScale.xy; N.z = sqrt(clamp((0.25 - N.x * N.x) - N.y * N.y, 0.0, 1.0)); N = tangentToWorld * N; #else @@ -425,15 +427,16 @@ void main() NL = clamp(dot(N, L), 0.0, 1.0); NE = clamp(dot(N, E), 0.0, 1.0); - vec4 specular = vec4(1.0); #if defined(USE_SPECULARMAP) - specular += texture2D(u_SpecularMap, texCoords) * u_EnableTextures.z - u_EnableTextures.zzzz; + 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_MaterialInfo.xxxy; + specular *= u_SpecularScale; float gloss = specular.a; float shininess = exp2(gloss * 13.0); diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index 4919254f..c4a30b60 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -123,9 +123,10 @@ static uniformInfo_t uniformsInfo[] = { "u_ModelMatrix", GLSL_MAT16 }, { "u_ModelViewProjectionMatrix", GLSL_MAT16 }, - { "u_Time", GLSL_FLOAT }, - { "u_VertexLerp" , GLSL_FLOAT }, - { "u_MaterialInfo", GLSL_VEC2 }, + { "u_Time", GLSL_FLOAT }, + { "u_VertexLerp" , GLSL_FLOAT }, + { "u_NormalScale", GLSL_VEC4 }, + { "u_SpecularScale", GLSL_VEC4 }, { "u_ViewInfo", GLSL_VEC4 }, { "u_ViewOrigin", GLSL_VEC3 }, diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 0da24dff..d6252f51 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -136,6 +136,9 @@ cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; cvar_t *r_deluxeSpecular; cvar_t *r_specularIsMetallic; +cvar_t *r_baseNormalX; +cvar_t *r_baseNormalY; +cvar_t *r_baseParallax; cvar_t *r_baseSpecular; cvar_t *r_baseGloss; cvar_t *r_recalcMD3Normals; @@ -1118,6 +1121,9 @@ void R_Register( void ) r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_deluxeSpecular = ri.Cvar_Get( "r_deluxeSpecular", "0.3", CVAR_ARCHIVE | CVAR_LATCH ); r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "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 ); r_baseSpecular = ri.Cvar_Get( "r_baseSpecular", "0.04", CVAR_ARCHIVE | CVAR_LATCH ); r_baseGloss = ri.Cvar_Get( "r_baseGloss", "0.3", CVAR_ARCHIVE | CVAR_LATCH ); r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 3c778cbe..bdc55d69 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -401,7 +401,10 @@ typedef struct { stageType_t type; struct shaderProgram_s *glslShaderGroup; int glslShaderIndex; - vec2_t materialInfo; + + vec4_t normalScale; + vec4_t specularScale; + } shaderStage_t; struct shaderCommands_s; @@ -677,7 +680,8 @@ typedef enum UNIFORM_TIME, UNIFORM_VERTEXLERP, - UNIFORM_MATERIALINFO, + UNIFORM_NORMALSCALE, + UNIFORM_SPECULARSCALE, UNIFORM_VIEWINFO, // znear, zfar, width/2, height/2 UNIFORM_VIEWORIGIN, @@ -1797,6 +1801,9 @@ extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; extern cvar_t *r_deluxeSpecular; extern cvar_t *r_specularIsMetallic; +extern cvar_t *r_baseNormalX; +extern cvar_t *r_baseNormalY; +extern cvar_t *r_baseParallax; extern cvar_t *r_baseSpecular; extern cvar_t *r_baseGloss; extern cvar_t *r_dlightMode; diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index 7d22944d..0925b6d6 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -812,7 +812,8 @@ static void ForwardDlight( void ) { GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, radius); - GLSL_SetUniformVec2(sp, UNIFORM_MATERIALINFO, pStage->materialInfo); + GLSL_SetUniformVec4(sp, UNIFORM_NORMALSCALE, pStage->normalScale); + GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered @@ -823,11 +824,36 @@ static void ForwardDlight( void ) { if (pStage->bundle[TB_DIFFUSEMAP].image[0]) R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); + // bind textures that are sampled and used in the glsl shader, and + // bind whiteImage to textures that are sampled but zeroed in the glsl shader + // + // alternatives: + // - use the last bound texture + // -> costs more to sample a higher res texture then throw out the result + // - disable texture sampling in glsl shader with #ifdefs, as before + // -> increases the number of shaders that must be compiled + // + if (pStage->bundle[TB_NORMALMAP].image[0]) + { R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP); + } + else if (r_normalMapping->integer) + GL_BindToTMU( tr.whiteImage, TB_NORMALMAP ); if (pStage->bundle[TB_SPECULARMAP].image[0]) + { R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP); + } + else if (r_specularMapping->integer) + GL_BindToTMU( tr.whiteImage, TB_SPECULARMAP ); + + { + vec4_t enableTextures; + + VectorSet4(enableTextures, 0.0f, 0.0f, 0.0f, 0.0f); + GLSL_SetUniformVec4(sp, UNIFORM_ENABLETEXTURES, enableTextures); + } if (r_dlightMode->integer >= 2) { @@ -1223,7 +1249,8 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); - GLSL_SetUniformVec2(sp, UNIFORM_MATERIALINFO, pStage->materialInfo); + GLSL_SetUniformVec4(sp, UNIFORM_NORMALSCALE, pStage->normalScale); + GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale); //GLSL_SetUniformFloat(sp, UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale); diff --git a/src/renderergl2/tr_shader.c b/src/renderergl2/tr_shader.c index c5438f6d..1a46ebd0 100644 --- a/src/renderergl2/tr_shader.c +++ b/src/renderergl2/tr_shader.c @@ -912,6 +912,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) else if(!Q_stricmp(token, "normalMap") || !Q_stricmp(token, "bumpMap")) { stage->type = ST_NORMALMAP; + VectorSet4(stage->normalScale, r_baseNormalX->value, r_baseNormalY->value, 1.0f, r_baseParallax->value); } else if(!Q_stricmp(token, "normalParallaxMap") || !Q_stricmp(token, "bumpParallaxMap")) { @@ -919,12 +920,12 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) stage->type = ST_NORMALPARALLAXMAP; else stage->type = ST_NORMALMAP; + VectorSet4(stage->normalScale, r_baseNormalX->value, r_baseNormalY->value, 1.0f, r_baseParallax->value); } else if(!Q_stricmp(token, "specularMap")) { stage->type = ST_SPECULARMAP; - stage->materialInfo[0] = 1.0f; - stage->materialInfo[1] = 1.0f; + VectorSet4(stage->specularScale, 1.0f, 1.0f, 1.0f, 1.0f); } else { @@ -943,7 +944,9 @@ 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->materialInfo[0] = atof( token ); + stage->specularScale[0] = + stage->specularScale[1] = + stage->specularScale[2] = atof( token ); } // // specularExponent <value> @@ -965,7 +968,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) // 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->materialInfo[1] = log(exponent) / log(8192.0); + stage->specularScale[3] = log(exponent) / log(8192.0); } // // gloss <value> @@ -979,7 +982,103 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) continue; } - stage->materialInfo[1] = atof( token ); + stage->specularScale[3] = atof( token ); + } + // + // parallaxDepth <value> + // + else if (!Q_stricmp(token, "parallaxdepth")) + { + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + ri.Printf( PRINT_WARNING, "WARNING: missing parameter for parallaxDepth in shader '%s'\n", shader.name ); + continue; + } + + stage->normalScale[3] = atof( token ); + } + // + // normalScale <xy> + // or normalScale <x> <y> + // or normalScale <x> <y> <height> + // + else if (!Q_stricmp(token, "normalscale")) + { + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + ri.Printf( PRINT_WARNING, "WARNING: missing parameter for normalScale in shader '%s'\n", shader.name ); + continue; + } + + stage->normalScale[0] = atof( token ); + + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + // one value, applies to X/Y + stage->normalScale[1] = stage->normalScale[0]; + continue; + } + + stage->normalScale[1] = atof( token ); + + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + // two values, no height + continue; + } + + stage->normalScale[3] = atof( token ); + } + // + // specularScale <rgb> <gloss> + // or specularScale <r> <g> <b> + // or specularScale <r> <g> <b> <gloss> + // + else if (!Q_stricmp(token, "specularscale")) + { + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specularScale in shader '%s'\n", shader.name ); + continue; + } + + stage->specularScale[0] = atof( token ); + + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specularScale in shader '%s'\n", shader.name ); + continue; + } + + stage->specularScale[1] = atof( token ); + + 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]; + continue; + } + + stage->specularScale[2] = atof( token ); + + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + // three values, rgb + continue; + } + + stage->specularScale[2] = atof( token ); + } // // rgbGen @@ -2232,6 +2331,8 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, diffuse->bundle[TB_NORMALMAP] = normal->bundle[0]; if (parallax && r_parallaxMapping->integer) defs |= LIGHTDEF_USE_PARALLAXMAP; + + VectorCopy4(normal->normalScale, diffuse->normalScale); } else if ((lightmap || useLightVector || useLightVertex) && (diffuseImg = diffuse->bundle[TB_DIFFUSEMAP].image[0])) { @@ -2252,6 +2353,8 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, if (parallax && r_parallaxMapping->integer) defs |= LIGHTDEF_USE_PARALLAXMAP; + + VectorSet4(diffuse->normalScale, r_baseNormalX->value, r_baseNormalY->value, 1.0f, r_baseParallax->value); } } } @@ -2262,8 +2365,7 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, { //ri.Printf(PRINT_ALL, ", specularmap %s", specular->bundle[0].image[0]->imgName); diffuse->bundle[TB_SPECULARMAP] = specular->bundle[0]; - diffuse->materialInfo[0] = specular->materialInfo[0]; - diffuse->materialInfo[1] = specular->materialInfo[1]; + VectorCopy4(specular->specularScale, diffuse->specularScale); } } @@ -2569,29 +2671,6 @@ static qboolean CollapseStagesToGLSL(void) } } - // insert default material info if needed - for (i = 0; i < MAX_SHADER_STAGES; i++) - { - shaderStage_t *pStage = &stages[i]; - - if (!pStage->active) - continue; - - if (pStage->glslShaderGroup != tr.lightallShader) - continue; - - if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) == 0) - continue; - - if (!pStage->bundle[TB_SPECULARMAP].image[0] && r_specularMapping->integer) - { - if (!pStage->materialInfo[0]) - pStage->materialInfo[0] = r_baseSpecular->value; - if (!pStage->materialInfo[1]) - pStage->materialInfo[1] = r_baseGloss->value; - } - } - return numStages; } @@ -3217,6 +3296,13 @@ shader_t *R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImag shader.lightmapIndex = lightmapIndex; for ( i = 0 ; i < MAX_SHADER_STAGES ; i++ ) { stages[i].bundle[0].texMods = texMods[i]; + + // 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; } // |