I’ve been running this shader on:
Radeon X850, GeForce 6/7, GeForce 8800 GTS.
Now one of my testers reported a problem on his 8800 GTS.
I get link error, but no information about the reason from the driver. I only have log file. I can’t experiment with the GPU/driver itself, but my game reported linker errors properly so far, so for now I assume it’s the driver that’s not telling me why it failed.
Maybe I’m missing some knowledge here. I will check it with GLSLValidate a bit later.
For now, maybe someone can help.
Vertex shader:
#ifndef __GLSL_CG_DATA_TYPES
#define hfloat float
#define hvec2 vec2
#define hvec3 vec3
#define hvec4 vec4
#else
#define hfloat half
#define hvec2 half2
#define hvec3 half3
#define hvec4 half4
#endif
varying hvec4 eyeVec;
varying hvec4 zenithVec;
varying hvec4 lightVec;
varying hfloat fog;
void main( void )
{
hvec3 normal;
hvec3 tangent;
hvec3 binormal;
gl_Position = ftransform();
#ifdef __GLSL_CG_DATA_TYPES
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
#endif
vec2 tc = (gl_Vertex.xz + gl_MultiTexCoord0.zw) * hvec2(0.01, 0.01);
gl_TexCoord[0].xy = tc * 0.024414;
gl_TexCoord[0].zw = tc * 5;
gl_TexCoord[1].xy = tc * 0.2;
normal.xyz = (gl_ModelViewMatrix * hvec4(gl_Normal.x, gl_Normal.y, gl_Normal.z, 0.0)).xyz;
normal = normalize(normal);
tangent.xyz = (gl_ModelViewMatrix * hvec4(1.0, 0.0, 0.0, 0.0)).xyz;
binormal.xyz = (gl_ModelViewMatrix * hvec4(0.0, 0.0, 1.0, 0.0)).xyz;
tangent = tangent - normal * dot(tangent, normal);
binormal = binormal - normal * dot(binormal, normal);
eyeVec.xyz = (gl_ModelViewMatrix * gl_Vertex).xyz;
eyeVec.xyz = hvec3(dot(eyeVec.xyz,tangent), dot(eyeVec.xyz,binormal), dot(eyeVec.xyz,normal));
/* alt */
eyeVec.w = gl_Vertex.y;
lightVec.xyz = normalize(gl_LightSource[0].position.xyz);
lightVec.xyz = hvec3(dot(lightVec.xyz,tangent), dot(lightVec.xyz,binormal), dot(lightVec.xyz,normal));
/* eye alt */
lightVec.w = dot ( (gl_ModelViewMatrix * hvec4(0.0, 1.0, 0.0, 0.0)).xyz,
(gl_ModelViewMatrix * hvec4(0.0, 0.0, 0.0, 1.0)).xyz );
zenithVec.xyz = (gl_ModelViewMatrix * hvec4(0.0, 1.0, 0.0, 0.0)).xyz;
zenithVec.xyz = hvec3(dot(zenithVec.xyz,tangent), dot(zenithVec.xyz,binormal), dot(zenithVec.xyz,normal));
zenithVec.w = gl_Vertex.y;
hfloat depth = max(-eyeVec.w, 1.0);
hfloat f_dist = length(eyeVec.xyz);
fog = f_dist * ((depth) / (depth - lightVec.w));
fog = clamp(pow(fog * 0.03, 0.5), 0.0, 1.0);
}
Fragment shader:
#ifndef __GLSL_CG_DATA_TYPES
#define hfloat float
#define hvec2 vec2
#define hvec3 vec3
#define hvec4 vec4
#else
#define hfloat half
#define hvec2 half2
#define hvec3 half3
#define hvec4 half4
#endif
uniform sampler2D texNormal;
uniform sampler2D texMap;
uniform sampler2D texReef;
uniform float brightness;
varying hvec4 eyeVec;
varying hvec4 zenithVec;
varying hvec4 lightVec;
varying hfloat fog;
void main( void )
{
if (eyeVec.w > 0.8) discard;
hvec3 eyeVec2 = normalize(eyeVec.xyz);
hvec3 lightVec2 = normalize(lightVec.xyz);
hvec3 v_normal = texture2D(texMap, gl_TexCoord[0].xy).rgb - hvec3(0.5, 0.5, 0.5);
hfloat shadow = length(v_normal) * 2.0;
v_normal = texture2D(texNormal, gl_TexCoord[0].zw).rgb - hvec3(0.5, 0.5, 0.5)
+ v_normal;
v_normal = normalize(v_normal);
hvec4 color = texture2D(texReef, gl_TexCoord[0].zw).rgba;
hfloat reef = smoothstep(3.0, 3.2, texture2D(texNormal, gl_TexCoord[1].xy).r * 4.0 - eyeVec.w * 0.5);
reef *= color.a;
color.rgb = mix(hvec3(1.0, 0.9, 0.6), color.rgb, reef);
color.rgb = color.rgb * clamp(dot(v_normal, lightVec2) + 0.2, 0.2, 1.0) * shadow;
gl_FragColor.rgb = mix(color.rgb, hvec3(0.0, 0.3, 0.1), fog) * brightness;
}
This is terrain shader for underwater refraction rendering. All terrain shaders in my game fail to link on that machine. All other shaders seem fine.
Some additional clues:
GL_VENDOR: NVIDIA Corporation
GL_RENDERER: GeForce 8800 GTS/PCI/SSE2
GL_VERSION: 2.1.2
I mix general attributes with fixed function attributes but I do not bind general attributes to fixed location before linking - I’m always retrieving attribute location after linking.
I use half types to pass varying variables but I do that in other shaders and they compile just fine.
Both shaders “compile” (glCompileShader) just fine, it’s the glLinkProgram that reports a failure.
At first glance it looks like driver bug. I remember pulling my hair out, trying to figure out the cause for ATI drivers not to link one of shaders (same as here - no error message from driver). It turned out I had 8 varying variables + glFragCoord = 9 varying variables (8 supported).
Anyone finds something suspicious about these shaders?
Thanks in advance for any clues.