1 Reply Latest reply on Aug 16, 2010 12:45 AM by frali

    Shadow map problem using GLSL with Catalyst 10.7 driver

    shiyujia
      Shadow map used to work in Catalyst 9.12, but does not work properly with 10.7

      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 latest driver. Now after installing Catalyst 10.7 on the HD 4830, the program does not work properly. It seems shadows

      are clipped. 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.