" myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
" //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n"
" //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n"
-" color = mix(myhalf4(texture2D(Texture_SecondaryColor, TexCoord)), color, terrainblend);\n"
+" color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord)), color.rgb, terrainblend);\n"
+" color.a = 1.0;\n"
" //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
"#endif\n"
"\n"
" myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
"# endif\n"
"# else\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
+" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n"
"# ifdef USESPECULAR\n"
" myhalf3 glosscolor = myhalf3(texture2D(Texture_Gloss, TexCoord));\n"
"# endif\n"
" myhalf3 diffusenormal = myhalf3(normalize(LightVector));\n"
"# endif\n"
"# ifdef USESPECULAR\n"
+"# ifndef USEEXACTSPECULARMATH\n"
" myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n"
"\n"
+"# endif\n"
" // calculate directional shading\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+" color.rgb = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower)) * glosscolor);\n"
+"# else\n"
" color.rgb = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * glosscolor);\n"
+"# endif\n"
"# else\n"
"# ifdef USEDIFFUSE\n"
" // calculate directional shading\n"
" // directional model lighting\n"
"# ifdef USEDIFFUSE\n"
" // get the light normal\n"
-" myhalf3 diffusenormal = myhalf3(LightVector);\n"
+" myhalf3 diffusenormal = myhalf3(normalize(LightVector));\n"
"# endif\n"
"# ifdef USESPECULAR\n"
" // calculate directional shading\n"
" color.rgb *= AmbientColor + DiffuseColor * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+" color.rgb += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
+"# else\n"
" myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n"
" color.rgb += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"# endif\n"
"# else\n"
"# ifdef USEDIFFUSE\n"
"\n"
" // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n"
"\n"
" // get the light normal\n"
-" myhalf3 diffusenormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhalf3(0.5);\n"
-" myhalf3 diffusenormal = normalize(myhalf3(dot(diffusenormal_modelspace, myhalf3(VectorS)), dot(diffusenormal_modelspace, myhalf3(VectorT)), dot(diffusenormal_modelspace, myhalf3(VectorR))));\n"
+" myhalf3 diffusenormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
+" myhalf3 diffusenormal;\n"
+" diffusenormal.x = dot(diffusenormal_modelspace, myhalf3(VectorS));\n"
+" diffusenormal.y = dot(diffusenormal_modelspace, myhalf3(VectorT));\n"
+" diffusenormal.z = dot(diffusenormal_modelspace, myhalf3(VectorR));\n"
" // calculate directional shading\n"
" myhalf3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n"
"# ifdef USESPECULAR\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
+"# else\n"
" myhalf3 specularnormal = myhalf3(normalize(diffusenormal + myhalf3(normalize(EyeVector))));\n"
" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"# endif\n"
"# endif\n"
"\n"
" // apply lightmap color\n"
" // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
"\n"
" // get the light normal\n"
-" myhalf3 diffusenormal = normalize(myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhalf3(0.5));\n"
+" myhalf3 diffusenormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
" // calculate directional shading\n"
" myhalf3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n"
"# ifdef USESPECULAR\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
+"# else\n"
" myhalf3 specularnormal = myhalf3(normalize(diffusenormal + myhalf3(normalize(EyeVector))));\n"
" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"# endif\n"
"# endif\n"
"\n"
" // apply lightmap color\n"
SHADERPERMUTATION_CUBEFILTER = 1<<5, // (lightsource) use cubemap light filter
SHADERPERMUTATION_GLOW = 1<<6, // (lightmap) blend in an additive glow texture
SHADERPERMUTATION_SPECULAR = 1<<7, // (lightsource or deluxemapping) render specular effects
- SHADERPERMUTATION_REFLECTION = 1<<8, // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
- SHADERPERMUTATION_OFFSETMAPPING = 1<<9, // adjust texcoords to roughly simulate a displacement mapped surface
- SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<10, // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
- SHADERPERMUTATION_GAMMARAMPS = 1<<11, // gamma (postprocessing only)
- SHADERPERMUTATION_POSTPROCESSING = 1<<12, // user defined postprocessing
- SHADERPERMUTATION_LIMIT = 1<<13, // size of permutations array
- SHADERPERMUTATION_COUNT = 13 // size of shaderpermutationinfo array
+ SHADERPERMUTATION_EXACTSPECULARMATH = 1<<8, // (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
+ SHADERPERMUTATION_REFLECTION = 1<<9, // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
+ SHADERPERMUTATION_OFFSETMAPPING = 1<<10, // adjust texcoords to roughly simulate a displacement mapped surface
+ SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<11, // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
+ SHADERPERMUTATION_GAMMARAMPS = 1<<12, // gamma (postprocessing only)
+ SHADERPERMUTATION_POSTPROCESSING = 1<<13, // user defined postprocessing
+ SHADERPERMUTATION_LIMIT = 1<<14, // size of permutations array
+ SHADERPERMUTATION_COUNT = 14 // size of shaderpermutationinfo array
}
shaderpermutation_t;
{"#define USECUBEFILTER\n", " cubefilter"},
{"#define USEGLOW\n", " glow"},
{"#define USESPECULAR\n", " specular"},
+ {"#define USEEXACTSPECULARMATH\n", " exactspecularmath"},
{"#define USEREFLECTION\n", " reflection"},
{"#define USEOFFSETMAPPING\n", " offsetmapping"},
{"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
{
int i;
- qfile_t *file = FS_Open("glsl/default.glsl", "w", false, false);
+ qfile_t *file = FS_OpenRealFile("glsl/default.glsl", "w", false);
if(!file)
{
Con_Printf("failed to write to glsl/default.glsl\n");
if (gl_support_fragment_shader)
{
if (r_glsl.integer && r_glsl_usegeneric.integer)
- R_SetupShader_SetPermutation(SHADERMODE_GENERIC, SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
+ R_SetupShader_SetPermutation(SHADERMODE_GENERIC, SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
else if (r_glsl_permutation)
{
r_glsl_permutation = NULL;
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
permutation |= SHADERPERMUTATION_REFLECTION;
}
+ if(permutation & SHADERPERMUTATION_SPECULAR)
+ if(r_shadow_glossexact.integer)
+ permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
R_SetupShader_SetPermutation(mode, permutation);
if (mode == SHADERMODE_LIGHTSOURCE)
{
qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
}
if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip * Matrix4x4_ScaleFromMatrix(&rsurface.matrix));
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower);
+ if(permutation & SHADERPERMUTATION_EXACTSPECULARMATH)
+ {
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * 0.25);
+ }
+ else
+ {
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower);
+ }
if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
CHECKGLERROR
}
void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
{
+ int w, h, idx;
int i;
dp_model_t *model = ent->model;
float f;
case Q3TCMOD_SCROLL:
Matrix4x4_CreateTranslate(&matrix, tcmod->parms[0] * r_refdef.scene.time, tcmod->parms[1] * r_refdef.scene.time, 0);
break;
+ case Q3TCMOD_PAGE: // poor man's animmap (to store animations into a single file, useful for HTTP downloaded textures)
+ w = tcmod->parms[0];
+ h = tcmod->parms[1];
+ f = r_refdef.scene.time / (tcmod->parms[2] * w * h);
+ f = f - floor(f);
+ idx = floor(f * w * h);
+ Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0);
+ break;
case Q3TCMOD_STRETCH:
f = 1.0f / R_EvaluateQ3WaveFunc(tcmod->wavefunc, tcmod->waveparms);
Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f);