From: havoc Date: Mon, 12 Jun 2006 12:43:47 +0000 (+0000) Subject: updated GLSL shader to match the one in Nexuiz 2.0, this fixes reliefmapping/offsetma... X-Git-Tag: xonotic-v0.1.0preview~3907 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=33f3fd006a3f9ed229c10455054d1c1dc7678bfd;p=xonotic%2Fdarkplaces.git updated GLSL shader to match the one in Nexuiz 2.0, this fixes reliefmapping/offsetmapping on models, and improves performance on NVIDIA by using more half-precision math git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6471 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/gl_rmain.c b/gl_rmain.c index a566a73f..00ef5aa0 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -334,6 +334,18 @@ static const char *builtinshaderstring = "\n" "// common definitions between vertex shader and fragment shader:\n" "\n" +"#ifdef __GLSL_CG_DATA_TYPES\n" +"#define myhalf half\n" +"#define myhvec2 hvec2\n" +"#define myhvec3 hvec3\n" +"#define myhvec4 hvec4\n" +"#else\n" +"#define myhalf float\n" +"#define myhvec2 vec2\n" +"#define myhvec3 vec3\n" +"#define myhvec4 vec4\n" +"#endif\n" +"\n" "varying vec2 TexCoord;\n" "varying vec2 TexCoordLightmap;\n" "\n" @@ -428,25 +440,25 @@ static const char *builtinshaderstring = "uniform sampler2D Texture_Deluxemap;\n" "uniform sampler2D Texture_Glow;\n" "\n" -"uniform vec3 LightColor;\n" -"uniform vec3 AmbientColor;\n" -"uniform vec3 DiffuseColor;\n" -"uniform vec3 SpecularColor;\n" -"uniform vec3 Color_Pants;\n" -"uniform vec3 Color_Shirt;\n" -"uniform vec3 FogColor;\n" +"uniform myhvec3 LightColor;\n" +"uniform myhvec3 AmbientColor;\n" +"uniform myhvec3 DiffuseColor;\n" +"uniform myhvec3 SpecularColor;\n" +"uniform myhvec3 Color_Pants;\n" +"uniform myhvec3 Color_Shirt;\n" +"uniform myhvec3 FogColor;\n" "\n" -"uniform float GlowScale;\n" -"uniform float SceneBrightness;\n" +"uniform myhalf GlowScale;\n" +"uniform myhalf SceneBrightness;\n" "\n" "uniform float OffsetMapping_Scale;\n" "uniform float OffsetMapping_Bias;\n" "uniform float FogRangeRecip;\n" "\n" -"uniform float AmbientScale;\n" -"uniform float DiffuseScale;\n" -"uniform float SpecularScale;\n" -"uniform float SpecularPower;\n" +"uniform myhalf AmbientScale;\n" +"uniform myhalf DiffuseScale;\n" +"uniform myhalf SpecularScale;\n" +"uniform myhalf SpecularPower;\n" "\n" "void main(void)\n" "{\n" @@ -461,7 +473,9 @@ static const char *builtinshaderstring = "\n" "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n" " // 14 sample relief mapping: linear search and then binary search\n" -" vec3 OffsetVector = vec3(EyeVector.xy * (1.0 / EyeVector.z) * depthbias * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n" +" //vec3 OffsetVector = vec3(EyeVector.xy * (1.0 / EyeVector.z) * depthbias * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n" +" //vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n" +" vec3 OffsetVector = vec3(eyedir.xy * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n" " vec3 RT = vec3(TexCoord - OffsetVector.xy * 10.0, 1.0) + OffsetVector;\n" " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n" " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n" @@ -478,20 +492,54 @@ static const char *builtinshaderstring = " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n" " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n" " TexCoord = RT.xy;\n" -"#else\n" +"#elif 1\n" " // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n" -" vec2 OffsetVector = vec2((EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333));\n" +" //vec2 OffsetVector = vec2(EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" +" //vec2 OffsetVector = vec2(normalize(EyeVector.xy)) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" +" vec2 OffsetVector = vec2(eyedir.xy) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" +" //TexCoord += OffsetVector * 3.0;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +"#elif 0\n" +" // 10 sample offset mapping\n" +" //vec2 OffsetVector = vec2(EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" +" //vec2 OffsetVector = vec2(normalize(EyeVector.xy)) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" +" vec2 OffsetVector = vec2(eyedir.xy) * OffsetMapping_Scale * vec2(-0.1, 0.1);\n" " //TexCoord += OffsetVector * 3.0;\n" " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" +"#elif 1\n" +" // parallax mapping as described in the paper\n" +" // 'Parallax Mapping with Offset Limiting: A Per-Pixel Approximation of Uneven Surfaces' by Terry Welsh\n" +" // The paper provides code in the ARB fragment program assembly language\n" +" // I translated it to GLSL but may have done something wrong - SavageX\n" +" // LordHavoc: removed bias and simplified to one line\n" +" // LordHavoc: this is just a single sample offsetmapping...\n" +" TexCoordOffset += vec2(eyedir.x, -1.0 * eyedir.y) * OffsetMapping_Scale * texture2D(Texture_Normal, TexCoord).a;\n" +"#else\n" +" // parallax mapping as described in the paper\n" +" // 'Parallax Mapping with Offset Limiting: A Per-Pixel Approximation of Uneven Surfaces' by Terry Welsh\n" +" // The paper provides code in the ARB fragment program assembly language\n" +" // I translated it to GLSL but may have done something wrong - SavageX\n" +" float height = texture2D(Texture_Normal, TexCoord).a;\n" +" height = (height - 0.5) * OffsetMapping_Scale; // bias and scale\n" +" TexCoordOffset += height * vec2(eyedir.x, -1.0 * eyedir.y);\n" "#endif\n" "#endif\n" "\n" " // combine the diffuse textures (base, pants, shirt)\n" -" vec4 color = vec4(texture2D(Texture_Color, TexCoord));\n" +" myhvec4 color = myhvec4(texture2D(Texture_Color, TexCoord));\n" "#ifdef USECOLORMAPPING\n" -" color.rgb += vec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + vec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n" +" color.rgb += myhvec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhvec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n" "#endif\n" "\n" "\n" @@ -501,20 +549,20 @@ static const char *builtinshaderstring = " // light source\n" "\n" " // get the surface normal and light normal\n" -" vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n" -" vec3 diffusenormal = vec3(normalize(LightVector));\n" +" myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5));\n" +" myhvec3 diffusenormal = myhvec3(normalize(LightVector));\n" "\n" " // calculate directional shading\n" -" color.rgb *= (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n" +" color.rgb *= AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n" "#ifdef USESPECULAR\n" -" vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n" -" color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n" +" myhvec3 specularnormal = normalize(diffusenormal + myhvec3(normalize(EyeVector)));\n" +" color.rgb += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" "#endif\n" "\n" "#ifdef USECUBEFILTER\n" " // apply light cubemap filter\n" " //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));\n" -" color.rgb *= vec3(textureCube(Texture_Cube, CubeVector));\n" +" color.rgb *= myhvec3(textureCube(Texture_Cube, CubeVector));\n" "#endif\n" "\n" " // apply light color\n" @@ -528,7 +576,7 @@ static const char *builtinshaderstring = " //\n" " // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to\n" " // provide significant illumination, large = slow = pain.\n" -" color.rgb *= max(1.0 - dot(CubeVector, CubeVector), 0.0);\n" +" color.rgb *= myhalf(max(1.0 - dot(CubeVector, CubeVector), 0.0));\n" "\n" "\n" "\n" @@ -537,87 +585,87 @@ static const char *builtinshaderstring = " // directional model lighting\n" "\n" " // get the surface normal and light normal\n" -" vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n" -" vec3 diffusenormal = vec3(normalize(LightVector));\n" +" myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5));\n" +" myhvec3 diffusenormal = myhvec3(normalize(LightVector));\n" "\n" " // calculate directional shading\n" -" color.rgb *= AmbientColor + DiffuseColor * max(dot(surfacenormal, diffusenormal), 0.0);\n" +" color.rgb *= AmbientColor + DiffuseColor * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n" "#ifdef USESPECULAR\n" -" vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n" -" color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n" +" myhvec3 specularnormal = normalize(diffusenormal + myhvec3(normalize(EyeVector)));\n" +" color.rgb += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" "#endif\n" "\n" "\n" "\n" "\n" -"#elif defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE)\n" +"#elif defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" " // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n" "\n" " // get the surface normal and light normal\n" -" vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n" -" vec3 diffusenormal_modelspace = vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5;\n" -" vec3 diffusenormal = normalize(vec3(dot(diffusenormal_modelspace, VectorS), dot(diffusenormal_modelspace, VectorT), dot(diffusenormal_modelspace, VectorR)));\n" +" myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5));\n" "\n" -" // calculate directional shading\n" -" vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n" -"#ifdef USESPECULAR\n" -" vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n" -" tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n" +"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n" +" myhvec3 diffusenormal_modelspace = myhvec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhvec3(0.5);\n" +" myhvec3 diffusenormal = normalize(myhvec3(dot(diffusenormal_modelspace, myhvec3(VectorS)), dot(diffusenormal_modelspace, myhvec3(VectorT)), dot(diffusenormal_modelspace, myhvec3(VectorR))));\n" +"#else\n" +" myhvec3 diffusenormal = normalize(myhvec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhvec3(0.5));\n" "#endif\n" -"\n" -" // apply lightmap color\n" -" color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n" -"\n" -"\n" -"\n" -"\n" -"#elif defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" -" // deluxemap lightmapping using light vectors in tangentspace\n" -"\n" -" // get the surface normal and light normal\n" -" vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n" -" vec3 diffusenormal = normalize(vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5);\n" -"\n" " // calculate directional shading\n" -" vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n" +" myhvec3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n" "#ifdef USESPECULAR\n" -" vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n" -" tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n" +" myhvec3 specularnormal = myhvec3(normalize(diffusenormal + myhvec3(normalize(EyeVector))));\n" +" tempcolor += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" "#endif\n" "\n" " // apply lightmap color\n" -" color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n" -"\n" -"\n" +" color.rgb = tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * AmbientScale;\n" "\n" "\n" "#else // MODE none (lightmap)\n" " // apply lightmap color\n" -" color.rgb *= vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + vec3(AmbientScale);\n" +" color.rgb *= myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + myhvec3(AmbientScale);\n" "#endif // MODE\n" "\n" -" color *= gl_Color;\n" +" color *= myhvec4(gl_Color);\n" "\n" "#ifdef USEGLOW\n" -" color.rgb += vec3(texture2D(Texture_Glow, TexCoord)) * GlowScale;\n" +" color.rgb += myhvec3(texture2D(Texture_Glow, TexCoord)) * GlowScale;\n" "#endif\n" "\n" "#ifdef USEFOG\n" " // apply fog\n" -" float fog = texture2D(Texture_FogMask, vec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0)).x;\n" +" myhalf fog = myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0)).x);\n" " color.rgb = color.rgb * fog + FogColor * (1.0 - fog);\n" "#endif\n" "\n" " color.rgb *= SceneBrightness;\n" "\n" -" gl_FragColor = color;\n" +" gl_FragColor = vec4(color);\n" "}\n" "\n" "#endif // FRAGMENT_SHADER\n" ; +// NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES! +const char *permutationinfo[][2] = +{ + {"#define MODE_LIGHTSOURCE\n", " lightsource"}, + {"#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, + {"#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, + {"#define MODE_LIGHTDIRECTION\n", " lightdirection"}, + {"#define USEGLOW\n", " glow"}, + {"#define USEFOG\n", " fog"}, + {"#define USECOLORMAPPING\n", " colormapping"}, + {"#define USESPECULAR\n", " specular"}, + {"#define USECUBEFILTER\n", " cubefilter"}, + {"#define USEOFFSETMAPPING\n", " offsetmapping"}, + {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"}, + {NULL, NULL} +}; + void R_GLSL_CompilePermutation(int permutation) { + int i; r_glsl_permutation_t *p = r_glsl_permutations + permutation; int vertstrings_count; int fragstrings_count; @@ -633,71 +681,20 @@ void R_GLSL_CompilePermutation(int permutation) vertstrings_count = 1; fragstrings_count = 1; permutationname[0] = 0; - if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) - { - vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTSOURCE\n"; - fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTSOURCE\n"; - strlcat(permutationname, " lightsource", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE) - { - vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"; - fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"; - strlcat(permutationname, " lightdirectionmap_modelspace", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE) - { - vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"; - fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"; - strlcat(permutationname, " lightdirectionmap_tangentspace", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION) - { - vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTION\n"; - fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTION\n"; - strlcat(permutationname, " lightdirection", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_GLOW) - { - vertstrings_list[vertstrings_count++] = "#define USEGLOW\n"; - fragstrings_list[fragstrings_count++] = "#define USEGLOW\n"; - strlcat(permutationname, " glow", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_COLORMAPPING) + for (i = 0;permutationinfo[i][0];i++) { - vertstrings_list[vertstrings_count++] = "#define USECOLORMAPPING\n"; - fragstrings_list[fragstrings_count++] = "#define USECOLORMAPPING\n"; - strlcat(permutationname, " colormapping", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_SPECULAR) - { - vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n"; - fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n"; - strlcat(permutationname, " specular", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_FOG) - { - vertstrings_list[vertstrings_count++] = "#define USEFOG\n"; - fragstrings_list[fragstrings_count++] = "#define USEFOG\n"; - strlcat(permutationname, " fog", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_CUBEFILTER) - { - vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n"; - fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n"; - strlcat(permutationname, " cubefilter", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_OFFSETMAPPING) - { - vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n"; - fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n"; - strlcat(permutationname, " offsetmapping", sizeof(permutationname)); - } - if (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) - { - vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n"; - fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n"; - strlcat(permutationname, " OFFSETMAPPING_RELIEFMAPPING", sizeof(permutationname)); + if (permutation & (1<