shiyujia

08-14-2010, 04:34 AM

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.

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.