EDIT: Forward-Z cascaded shadow map

This commit is contained in:
2025-10-13 23:19:28 +09:00
parent 26b7db9030
commit b419cc1148
3 changed files with 14 additions and 9 deletions

View File

@@ -80,8 +80,11 @@ float calcShadowVisibility(vec3 worldPos, vec3 N, vec3 L)
float mapD = texture(shadowTex[ci], suv + off).r; float mapD = texture(shadowTex[ci], suv + off).r;
// Standard depth shadow map: occluded when current > mapD + bias // Forward-Z depth shadow map:
float occ = step(current + bias, mapD); // - Occluded when current + bias > mapD
// - Unoccluded otherwise
// Use step(edge, x): returns 1 when x >= edge. Make occ=1 for occluded.
float occ = step(mapD + bias, current);
occluded += occ * w; occluded += occ * w;
wsum += w; wsum += w;
@@ -161,7 +164,7 @@ void main(){
vec3 kD = (1.0 - kS) * (1.0 - metallic); vec3 kD = (1.0 - kS) * (1.0 - metallic);
float NdotL = max(dot(N, L), 0.0); float NdotL = max(dot(N, L), 0.0);
// Shadowing (directional, reversed-Z shadow map) // Shadowing (directional, forward-Z shadow map)
float visibility = calcShadowVisibility(pos, N, L); float visibility = calcShadowVisibility(pos, N, L);
vec3 irradiance = sceneData.sunlightColor.rgb * sceneData.sunlightColor.a * NdotL * visibility; vec3 irradiance = sceneData.sunlightColor.rgb * sceneData.sunlightColor.a * NdotL * visibility;

View File

@@ -45,11 +45,11 @@ void ShadowPass::init(EngineContext *context)
b.set_cull_mode(VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE); b.set_cull_mode(VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE);
b.set_multisampling_none(); b.set_multisampling_none();
b.disable_blending(); b.disable_blending();
// Reverse-Z depth test for shadow maps (clear=0.0, GREATER_OR_EQUAL) // Forward-Z for shadow maps only (engine uses reversed-Z elsewhere)
b.enable_depthtest(true, VK_COMPARE_OP_GREATER_OR_EQUAL); // We clear depth to 1.0 and use LESS_OR_EQUAL so the nearest depth wins.
b.enable_depthtest(true, VK_COMPARE_OP_LESS_OR_EQUAL);
b.set_depth_format(VK_FORMAT_D32_SFLOAT); b.set_depth_format(VK_FORMAT_D32_SFLOAT);
// Static depth bias to help with surface acne (tune later)
b._rasterizer.depthBiasEnable = VK_TRUE; b._rasterizer.depthBiasEnable = VK_TRUE;
b._rasterizer.depthBiasConstantFactor = 2.0f; b._rasterizer.depthBiasConstantFactor = 2.0f;
b._rasterizer.depthBiasSlopeFactor = 2.0f; b._rasterizer.depthBiasSlopeFactor = 2.0f;
@@ -85,8 +85,8 @@ void ShadowPass::register_graph(RenderGraph *graph, std::span<RGImageHandle> cas
RGPassType::Graphics, RGPassType::Graphics,
[shadowDepth](RGPassBuilder &builder, EngineContext *ctx) [shadowDepth](RGPassBuilder &builder, EngineContext *ctx)
{ {
// Reverse-Z depth clear to 0.0 // Forward-Z in shadow pass: clear depth to 1.0 (far)
VkClearValue clear{}; clear.depthStencil = {0.f, 0}; VkClearValue clear{}; clear.depthStencil = {1.f, 0};
builder.write_depth(shadowDepth, true, clear); builder.write_depth(shadowDepth, true, clear);
// Ensure index/vertex buffers are tracked as reads (like Geometry) // Ensure index/vertex buffers are tracked as reads (like Geometry)

View File

@@ -110,7 +110,9 @@ void SceneManager::update_scene()
{ {
using namespace glm; using namespace glm;
const vec3 camPos = vec3(inverse(view)[3]); const vec3 camPos = vec3(inverse(view)[3]);
vec3 L = normalize(-vec3(sceneData.sunlightDirection)); // Use light-ray direction (from light to scene).
// Shaders compute per-fragment L as -sunlightDirection (vector to light).
vec3 L = normalize(vec3(sceneData.sunlightDirection));
if (!glm::all(glm::isfinite(L)) || glm::length2(L) < 1e-10f) if (!glm::all(glm::isfinite(L)) || glm::length2(L) < 1e-10f)
L = glm::vec3(0.0f, -1.0f, 0.0f); L = glm::vec3(0.0f, -1.0f, 0.0f);