c++ – Vulkan shadow map artifacts

c++ – Vulkan shadow map artifacts

[ad_1]

I’m experiencing some bizarre shadow artifacts.

I think it to be some type of self shadowing/depth bias factor.

enter image description here

enter image description here

My shader for the shadow map is kind of easy:

shadow_map.vert

#model 450

structure(location = 0) in vec3 in_position;

structure(binding = 0) uniform uniform_scene {
  mat4 light_space;
} scene;

structure(push_constant) uniform uniform_object {
  mat4 mannequin;
} object;

void foremost() {
  gl_Position = scene.light_space * object.mannequin * vec4(in_position, 1.0);
}

shadow_map.frag:


#model 450

// structure(location = 0) out float out_depth;

void foremost() {
  // out_depth = gl_FragCoord.z;
}


And for truly doing the depth check for shadows I adopted alongside learnopengl.com since I believed the shader code needs to be the identical for vulkan and opengl.

base.vert

#model 450

struct per_mesh_data {
  mat4 mannequin;
  mat4 regular;
  vec4 tint;
}; // struct per_mesh_data

structure(location = 0) in vec3 in_position;
structure(location = 1) in vec3 in_normal;
structure(location = 2) in vec2 in_uv;

structure(location = 0) out vec3 out_position;
structure(location = 1) out vec3 out_normal;
structure(location = 2) out vec2 out_uv;
structure(location = 3) out vec4 out_light_space_position;
structure(location = 4) out vec4 out_tint;

structure(binding = 0) uniform uniform_scene {
  mat4 view;
  mat4 projection;
  vec3 camera_position;
  mat4 light_space;
  vec3 light_direction;
  vec4 light_color;
} scene;

structure(binding = 1) buffer buffer_mesh_data {
  per_mesh_data knowledge[];
} mesh_data;

const mat4 depth_bias = mat4( 
    0.5, 0.0, 0.0, 0.0,
    0.0, 0.5, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.5, 0.5, 0.0, 1.0
);

void foremost() {
  per_mesh_data knowledge = mesh_data.knowledge[gl_InstanceIndex]; 

  out_position = vec3(knowledge.mannequin * vec4(in_position, 1.0));
  out_normal = normalize(mat3(knowledge.regular) * in_normal);
  out_uv = in_uv;
  out_light_space_position = (depth_bias * scene.light_space) * vec4(out_position, 1.0);
  out_tint = knowledge.tint;

  gl_Position = scene.projection * scene.view * vec4(out_position, 1.0);
}

base.frag


#model 450

#embody "../widespread/lighting.glsl"
#embody "../widespread/materials.glsl"

structure(location = 0) in vec3 in_position;
structure(location = 1) in vec3 in_normal;
structure(location = 2) in vec2 in_uv;
structure(location = 3) in vec4 in_light_space_position;
structure(location = 4) in vec4 in_tint;

structure(location = 0) out vec4 out_color;

structure(binding = 0) uniform uniform_scene {
  mat4 view;
  mat4 projection;
  vec3 camera_position;
  mat4 light_space;
  vec3 light_direction;
  vec4 light_color;
} scene;

structure(binding = 2) uniform sampler2D picture;
structure(binding = 3) uniform sampler2D shadow_map;

structure(push_constant) uniform uniform_object {
  mat4 mannequin;
  mat4 regular;
} object;

const materials default_material = materials(
  vec4(1.0, 1.0, 1.0, 1.0),
  vec4(1.0, 1.0, 1.0, 1.0),
  vec4(0.5, 0.5, 0.5, 1.0),
  16.0
);

vec4 phong_lighting(vec3 light_direction, vec3 view_direction, vec3 regular, materials materials) {
  // Ambient
  vec4 ambient_color = scene.light_color * materials.ambient;

  // Diffuse
  float diffuse_factor = max(dot(light_direction, regular), 0.0);
  vec4 diffuse_color = diffuse_factor * scene.light_color * materials.diffuse;

  // Specular
  vec3 halfway_direction = normalize(light_direction + view_direction);  
  float specular_factor = pow(max(dot(regular, halfway_direction), 0.0), materials.shininess);
  vec4 specular_color = specular_factor * scene.light_color * materials.specular; 

  return ambient_color + diffuse_color + specular_color;
}

float pcf_shadow(vec3 light_direction) {
  vec2 texture_size = textureSize(shadow_map, 0);
  vec2 texel_size = 1.0 / texture_size;

  vec3 coordinates = in_light_space_position.xyz / in_light_space_position.w;

  if (coordinates.z > 1.0 || coordinates.z < -1.0) {
    return 0.0;
  }

  float shadow = 0.0;

  float bias = max(0.001 * (1.0 - dot(in_normal, light_direction)), 0.0001);
  // float bias = 0.001;
  
  float current_depth = coordinates.z;
  
  int depend = 0;
  int vary = 2;

  for (int x = -range; x <= vary; ++x) {
    for (int y = -range; y <= vary; ++y) {
      float pcf_depth = texture(shadow_map, coordinates.xy + vec2(x, y) * texel_size).r;
      shadow += (current_depth - bias) > pcf_depth ? 1.0 : 0.0;
      ++depend;
    }
  }

  return shadow / float(depend);
}

void foremost() {
  vec3 light_direction = normalize(-scene.light_direction);
  vec3 view_direction = normalize(scene.camera_position - in_position);

  // Calculate lighting
  vec4 lighting = phong_lighting(light_direction, view_direction, in_normal, default_material);

  // Calculate shadow
  float shadow_factor = pcf_shadow(light_direction);

  // Pattern texture
  vec4 sampled_color = texture(picture, in_uv);

  vec4 shaded_lighting = combine(lighting * (1.0 - shadow_factor), lighting * 0.2, shadow_factor);

  out_color = shaded_lighting * sampled_color * in_tint;
}


The included recordsdata right here simply outline structs like materials and directional_light

[ad_2]

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply