I wrote a shadow map demo program using GLSL. It used to work with Catalyst driver 9.12 on HD 4830. And it also works on a NVidia Geforce 8800 GTS 320 with 258.96 driver. Now after installing Catalyst 10.7 on the HD 4830, the program does not work properly. It seems shadows are either clipped or there are no shadows at all. Here are the GLSL source codes:
Vertex shader:
uniform mat4 Model; // Model matrix
uniform mat4 ModelIT; // Inverse transpose of Model matrix
uniform mat4 ModelViewProj; // Model View Projection matrix
uniform vec2 texcoord_scaling; // Texture coordinate scaling factors
uniform vec2 texcoord_bias; // Texture coordinate bias
uniform vec3 viewer_position;
varying vec2 diffuse_map_texcoord;
varying vec3 position_in_world_space;
varying vec3 normal_in_world_space;
varying vec3 dir_to_viewer;
void main()
{
gl_Position=ModelViewProj*gl_Vertex;
diffuse_map_texcoord=gl_MultiTexCoord0.xy*texcoord_scaling+texcoord_bias;
position_in_world_space=(Model*gl_Vertex).xyz;
normal_in_world_space=(ModelIT*vec4(gl_Normal, 0.0)).xyz;
dir_to_viewer=normalize(viewer_position-position_in_world_space);
}
Fragment shader:
#define NUM_LIGHTS 3
#define NUM_LIGHTS_WITH_SHADOW 2
#define NUM_SHADOWMAP_SAMPLES 2
struct CLight
{
bvec2 enabled_flags; // x--Light enabled, y--Shadow enabled
vec4 pos; // Light position
vec3 dir; // Light Direction
vec4 color; // Light Color
vec3 afactors; // Attenuation factors
vec2 misc; // x--Cosine of cut off angle, y--Angular falloff factor
};
vec4 Illuminate(CLight lt, vec3 P, out vec3 L)
// Input:
// lt: light source
// P: Position of the point to be illuminated
// Output:
// L: Direction to light unit vector
// Return value: Light intensity at point P
{
vec3 to_light=lt.pos.xyz-P*lt.pos.w;
L=normalize(to_light);
float d=length(to_light); // Distance to light
float fd=1.0/(lt.afactors.x+d*(lt.afactors.y+d*lt.afactors.z)); // Radial attenuation
float cosine_theta=dot(lt.dir, -L);
float fa=(cosine_theta-lt.misc.x)/(1.0-lt.misc.x);
fa=pow(clamp(fa, 0.0, 1.0), lt.misc.y); // Angular attenuation
return lt.color*fa*fd;
}
// Shadow map sample points in pairs (xy and zw)
vec4 shadow_map_sample_points[]=vec4[NUM_SHADOWMAP_SAMPLES](
vec4(-0.4, -0.2, 0.2, -0.4),
vec4(0.4, 0.2, -0.2, 0.4)
);
vec4 ShadowMapFiltering(sampler2DShadow shadow_map, vec4 texcoord, vec2 kernel_size)
{
vec4 shadow_mask=vec4(0.0);
vec2 dtexcoord=texcoord.w*kernel_size;
for (int k=0; k<NUM_SHADOWMAP_SAMPLES; ++k)
{
vec4 tap, shadow_sample;
tap=texcoord+vec4(shadow_map_sample_points[k].xy*dtexcoord, 0.0, 0.0);
shadow_sample=shadow2DProj(shadow_map, tap);
shadow_mask+=shadow_sample;
tap=texcoord+vec4(shadow_map_sample_points[k].zw*dtexcoord, 0.0, 0.0);
shadow_sample=shadow2DProj(shadow_map, tap);
shadow_mask+=shadow_sample;
}
shadow_mask/=vec4(2.0*float(NUM_SHADOWMAP_SAMPLES));
return shadow_mask;
}
uniform CLight lights[NUM_LIGHTS]; // Lights
uniform sampler2DShadow shadow_maps[NUM_LIGHTS_WITH_SHADOW]; // Shadow maps
uniform mat4 shadow_map_matrices[NUM_LIGHTS_WITH_SHADOW]; // Projective matrices for shadow maps
uniform bvec2 texture_flags;
// x--Diffuse map enabled, y--Specular map enabled
uniform sampler2D diffuse_map;
uniform sampler2D specular_map;
uniform vec4 global_ambient;
uniform vec4 diffuse;
uniform vec4 specular;
uniform float shininess;
varying vec2 diffuse_map_texcoord;
varying vec3 position_in_world_space;
varying vec3 normal_in_world_space;
varying vec3 dir_to_viewer;
void main()
{
int k;
// Get base diffuse and specular color
vec4 tex_color;
vec4 base_diffuse_color=diffuse;
vec4 base_specular_color=specular;
if (texture_flags.x)
{
tex_color=texture2D(diffuse_map, diffuse_map_texcoord);
base_diffuse_color*=tex_color;
}
if (texture_flags.y)
{
tex_color=texture2D(specular_map, diffuse_map_texcoord);
base_specular_color*=tex_color;
}
// Calculate vectors
vec3 N=normalize(normal_in_world_space);
vec3 V=normalize(dir_to_viewer);
vec3 L; // Direction to light vector
vec3 H; // Halfway vector
// Global ambient contribution
vec4 diffuse_color=global_ambient;
vec4 specular_color=vec4(0.0);
// Contribution from lights with shadows
vec4 lcolor;
for (k=0; k<NUM_LIGHTS_WITH_SHADOW; ++k)
if (lights[k].enabled_flags.x)
{
lcolor=Illuminate(lights[k], position_in_world_space, L);
if (lights[k].enabled_flags.y)
{
vec4 shadow_map_texcoord=shadow_map_matrices[k]*vec4(position_in_world_space, 1.0);
vec4 shadow_mask=ShadowMapFiltering(shadow_maps[k],
shadow_map_texcoord, vec2(0.001, 0.001));
lcolor*=shadow_mask;
}
H=normalize(L+V);
float diffuse_factor=max(dot(N,L), 0.0);
float specular_factor=pow(max(dot(N,H), 0.0), shininess);
diffuse_color+=lcolor*diffuse_factor;
specular_color+=lcolor*specular_factor;
}
// Contribution from lights without shadows
for (k=NUM_LIGHTS_WITH_SHADOW; k<NUM_LIGHTS; ++k)
if (lights[k].enabled_flags.x)
{
lcolor=Illuminate(lights[k], position_in_world_space, L);
H=normalize(L+V);
float diffuse_factor=max(dot(N,L), 0.0);
float specular_factor=pow(max(dot(N,H), 0.0), shininess);
diffuse_color+=lcolor*diffuse_factor;
specular_color+=lcolor*specular_factor;
}
diffuse_color*=base_diffuse_color;
specular_color*=base_specular_color;
gl_FragColor=diffuse_color+specular_color;
gl_FragColor.a=base_diffuse_color.a;
}
If I comment out these two lines:
tex_color=texture2D(specular_map, diffuse_map_texcoord);
base_specular_color*=tex_color;
then it works. I think there is something weird going on with 10.7’s GLSL compiler.