rendering: formalize main light shadow params

This commit is contained in:
2026-04-13 01:06:09 +08:00
parent 64212a53c7
commit 2ee74e7761
8 changed files with 94 additions and 61 deletions

View File

@@ -19,6 +19,10 @@ namespace Rendering {
namespace {
constexpr float kDirectionalShadowReceiverDepthBias = 0.0015f;
constexpr float kDirectionalShadowNormalBiasScale = 1.5f;
constexpr float kDirectionalShadowStrength = 0.85f;
std::shared_ptr<const RenderPipelineAsset> CreateDefaultPipelineAsset() {
static const std::shared_ptr<const RenderPipelineAsset> s_defaultPipelineAsset =
std::make_shared<Pipelines::BuiltinForwardPipelineAsset>();
@@ -386,16 +390,14 @@ RenderDirectionalShadowData BuildDirectionalShadowData(
: (plan.orthographicHalfExtent > Math::EPSILON && plan.mapWidth > 0u
? (plan.orthographicHalfExtent * 2.0f) / static_cast<float>(plan.mapWidth)
: 0.0f);
shadowData.shadowParams = Math::Vector4(
0.0015f,
shadowData.mapMetrics.inverseMapSize = Math::Vector2(
1.0f / static_cast<float>(plan.mapWidth),
1.0f / static_cast<float>(plan.mapHeight),
0.85f);
shadowData.shadowOptions = Math::Vector4(
1.0f,
texelWorldSize,
1.5f,
0.0f);
1.0f / static_cast<float>(plan.mapHeight));
shadowData.mapMetrics.worldTexelSize = texelWorldSize;
shadowData.sampling.enabled = 1.0f;
shadowData.sampling.receiverDepthBias = kDirectionalShadowReceiverDepthBias;
shadowData.sampling.normalBiasScale = kDirectionalShadowNormalBiasScale;
shadowData.sampling.shadowStrength = kDirectionalShadowStrength;
return shadowData;
}

View File

@@ -714,17 +714,12 @@ bool BuiltinForwardPipeline::DrawVisibleItem(
visibleItem.localToWorld.Inverse()
};
const LightingConstants lightingConstants = BuildLightingConstants(sceneData.lighting);
const ShadowReceiverConstants shadowReceiverConstants = {
sceneData.lighting.HasMainDirectionalShadow()
? sceneData.lighting.mainDirectionalShadow.viewProjection
: Math::Matrix4x4::Identity(),
sceneData.lighting.HasMainDirectionalShadow()
? sceneData.lighting.mainDirectionalShadow.shadowParams
: Math::Vector4::Zero(),
sceneData.lighting.HasMainDirectionalShadow()
? sceneData.lighting.mainDirectionalShadow.shadowOptions
: Math::Vector4::Zero()
};
ShadowReceiverConstants shadowReceiverConstants = {};
if (sceneData.lighting.HasMainDirectionalShadow()) {
shadowReceiverConstants.worldToShadow = sceneData.lighting.mainDirectionalShadow.viewProjection;
shadowReceiverConstants.shadowMapMetrics = sceneData.lighting.mainDirectionalShadow.mapMetrics;
shadowReceiverConstants.shadowSampling = sceneData.lighting.mainDirectionalShadow.sampling;
}
const Resources::Material* material = ResolveMaterial(visibleItem);
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(sceneData, material);

View File

@@ -12,7 +12,6 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <cstdio>
#include <limits>
namespace XCEngine {
@@ -134,12 +133,8 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
const Components::LightComponent& light,
const DirectionalShadowPlanningSettings& shadowSettings,
float viewportAspect) {
std::fprintf(stderr, "[shadow-debug] enter BuildDirectionalShadowRenderPlan\n");
std::fflush(stderr);
DirectionalShadowRenderPlan plan = {};
if (!light.GetCastsShadows()) {
std::fprintf(stderr, "[shadow-debug] early out: light shadows disabled\n");
std::fflush(stderr);
return plan;
}
@@ -173,8 +168,6 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
shadowSettings.maxFocusDistance);
const float sliceNear = std::max(camera.GetNearClipPlane(), 0.1f);
const float sliceFar = std::max(sliceNear + 0.1f, shadowDistance);
std::fprintf(stderr, "[shadow-debug] built slice distances\n");
std::fflush(stderr);
std::array<Math::Vector3, 8> frustumCorners = {};
if (camera.GetProjectionType() == Components::CameraProjectionType::Perspective) {
@@ -216,8 +209,6 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
focusPoint += corner;
}
focusPoint /= static_cast<float>(frustumCorners.size());
std::fprintf(stderr, "[shadow-debug] built frustum corners\n");
std::fflush(stderr);
Math::Bounds frustumWorldBounds(frustumCorners[0], Math::Vector3::Zero());
for (size_t index = 1; index < frustumCorners.size(); ++index) {
@@ -241,8 +232,6 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
shadowWorldPosition,
shadowRotation,
Math::Vector3::One()).Inverse();
std::fprintf(stderr, "[shadow-debug] built light view matrix\n");
std::fflush(stderr);
float minX = std::numeric_limits<float>::max();
float maxX = std::numeric_limits<float>::lowest();
@@ -251,14 +240,10 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
float minZ = std::numeric_limits<float>::max();
float maxZ = std::numeric_limits<float>::lowest();
ExpandLightSpaceBounds(view, frustumCorners, minX, maxX, minY, maxY, minZ, maxZ);
std::fprintf(stderr, "[shadow-debug] expanded frustum bounds\n");
std::fflush(stderr);
const uint32_t cullingMask = camera.GetCullingMask();
const std::vector<Components::MeshFilterComponent*> meshFilters =
scene.FindObjectsOfType<Components::MeshFilterComponent>();
std::fprintf(stderr, "[shadow-debug] mesh filter count=%zu\n", meshFilters.size());
std::fflush(stderr);
for (Components::MeshFilterComponent* meshFilter : meshFilters) {
if (meshFilter == nullptr ||
!meshFilter->IsEnabled() ||
@@ -300,8 +285,6 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
ExpandLightSpaceBounds(view, worldCorners, minX, maxX, minY, maxY, minZ, maxZ);
}
std::fprintf(stderr, "[shadow-debug] finished mesh bounds expansion\n");
std::fflush(stderr);
minX -= shadowSettings.boundsPadding;
maxX += shadowSettings.boundsPadding;
@@ -349,8 +332,6 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
maxY,
minZ,
maxZ);
std::fprintf(stderr, "[shadow-debug] built orthographic projection\n");
std::fflush(stderr);
plan.enabled = true;
plan.lightDirection = lightDirection;
@@ -369,8 +350,6 @@ DirectionalShadowRenderPlan BuildDirectionalShadowRenderPlan(
plan.cameraData.clearFlags = RenderClearFlags::Depth;
plan.cameraData.viewportWidth = plan.mapWidth;
plan.cameraData.viewportHeight = plan.mapHeight;
std::fprintf(stderr, "[shadow-debug] leave BuildDirectionalShadowRenderPlan\n");
std::fflush(stderr);
return plan;
}