From 230957f728e6bc769951b657b22c274fc24a844c Mon Sep 17 00:00:00 2001 From: Atdunbg Date: Tue, 7 Apr 2026 13:20:02 +0800 Subject: [PATCH] improve shadow process, now shadow can render according to the camera position --- Editor/Editor/EditorLayer.cpp | 1 - Editor/assets/scenes/FPS.scene | 299 ++++++++++++-------- Editor/assets/shaders/PBRShader_Anim.glsl | 36 +-- Editor/assets/shaders/PBRShader_Static.glsl | 36 +-- Prism/src/Prism/Renderer/Renderer3D.cpp | 211 +++++++------- 5 files changed, 309 insertions(+), 274 deletions(-) diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index 2dd0072..83627e5 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -1085,7 +1085,6 @@ namespace Prism continue; auto& submeshes = mesh->GetSubmeshes(); - float lastT = std::numeric_limits::max(); for (uint32_t i = 0; i < submeshes.size(); i++) { auto& submesh = submeshes[i]; diff --git a/Editor/assets/scenes/FPS.scene b/Editor/assets/scenes/FPS.scene index a6e510b..ad26872 100644 --- a/Editor/assets/scenes/FPS.scene +++ b/Editor/assets/scenes/FPS.scene @@ -1,22 +1,58 @@ Scene: Scene Name Environment: - AssetHandle: 5211537204242875091 + AssetHandle: 10745193190519058183 Entities: - - Entity: 8293051279669100759 + - Entity: 4944419254382500800 + Parent: 0 + Children: + [] + TagComponent: + Tag: Directional Light + TransformComponent: + Position: [0, 0, 0] + Rotation: [-2.2312348, 0, 0] + Scale: [1, 1, 1] + DirectionalLightComponent: + Radiance: [1, 1, 1] + CastShadows: true + SoftShadows: true + LightSize: 0.5 + - Entity: 5099152432245948441 + Parent: 0 + Children: + [] + TagComponent: + Tag: venice_dawn_1_4k + TransformComponent: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + SkyLightComponent: + EnvironmentMap: 10745193190519058183 + EnvironmentAssetPath: assets/env/venice_dawn_1_4k.hdr + Intensity: 1 + Angle: 0 + DynamicSky: false + TurbidityAzimuthInclination: [2, 0, 0] + - Entity: 10732070446010033158 Parent: 0 Children: [] TagComponent: Tag: Cube TransformComponent: - Position: [1.736814, 1.4724115, -4.2181306] + Position: [0, -2.6466873, 0] Rotation: [0, 0, 0] - Scale: [1, 1, 1] + Scale: [100, 1, 100] MeshComponent: - AssetID: 18328012085543462741 + AssetID: 14957733959243172548 AssetPath: assets/meshes/Default/Cube.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" RigidBodyComponent: - BodyType: 1 + BodyType: 0 Mass: 1 LinearDrag: 0 AngularDrag: 0.05 @@ -36,19 +72,50 @@ Entities: IsTrigger: false Material: 0 MaterialPath: "" - - Entity: 5834225236589765516 + - Entity: 9267298328378270409 Parent: 0 Children: [] TagComponent: - Tag: Cube + Tag: Player TransformComponent: - Position: [-2.6417403, 1.4724115, -7.9285727] - Rotation: [0.52199936, 0, 0] - Scale: [1, 1.0000001, 1.0000001] + Position: [0, 0.70693016, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + ScriptComponent: + ModuleName: FPSExample.FPSPlayer + StoredFields: + - Name: m_Radius + Type: 1 + Data: 0 + - Name: WalkingSpeed + Type: 1 + Data: 2 + - Name: RunSpeed + Type: 1 + Data: 5 + - Name: JumpForce + Type: 1 + Data: 1 + - Name: TorqueStrength + Type: 1 + Data: 0 + - Name: MouseSensitivity + Type: 1 + Data: 10 + - Name: CameraForwardOffset + Type: 1 + Data: -2 + - Name: CameraYOffset + Type: 1 + Data: 2 MeshComponent: - AssetID: 18328012085543462741 - AssetPath: assets/meshes/Default/Cube.fbx + AssetID: 8763440120556133680 + AssetPath: assets/meshes/Default/Capsule.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" RigidBodyComponent: BodyType: 1 Mass: 1 @@ -57,6 +124,64 @@ Entities: DisableGravity: false IsKinematic: false Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: true + LockRotationY: false + LockRotationZ: true + MeshColliderComponent: + IsConvex: true + IsTrigger: false + OverrideMesh: false + Material: 0 + MaterialPath: "" + - Entity: 8114736924719261351 + Parent: 0 + Children: + [] + TagComponent: + Tag: Camera + TransformComponent: + Position: [0, 0.8097433, 4.573171] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + CameraComponent: + Camera: + ProjectionType: 0 + PerspectiveFOV: 45 + PerspectiveNear: 0.01 + PerspectiveFar: 10000 + OrthographicSize: 10 + OrthographicNear: -1 + OrthographicFar: 1 + Primary: true + - Entity: 4208267561919679628 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [-2.6417403, 1.4724115, -4.8956265] + Rotation: [-0.4034239, 0, 0] + Scale: [1, 0.99999994, 0.99999994] + MeshComponent: + AssetID: 14957733959243172548 + AssetPath: assets/meshes/Default/Cube.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: true + IsKinematic: false + Layer: 0 Constraints: LockPositionX: false LockPositionY: false @@ -70,19 +195,23 @@ Entities: IsTrigger: false Material: 0 MaterialPath: "" - - Entity: 8234256119181302872 + - Entity: 3328246672296261054 Parent: 0 Children: [] TagComponent: Tag: Cube TransformComponent: - Position: [1.736814, 1.4724115, -7.9285727] + Position: [1.736814, 1.4724115, -0.88378817] Rotation: [0, 0, 0] Scale: [1, 1, 1] MeshComponent: - AssetID: 18328012085543462741 + AssetID: 14957733959243172548 AssetPath: assets/meshes/Default/Cube.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" RigidBodyComponent: BodyType: 1 Mass: 1 @@ -115,8 +244,12 @@ Entities: Rotation: [0, 0, 0] Scale: [1, 1, 1] MeshComponent: - AssetID: 18328012085543462741 + AssetID: 14957733959243172548 AssetPath: assets/meshes/Default/Cube.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" RigidBodyComponent: BodyType: 1 Mass: 1 @@ -138,19 +271,23 @@ Entities: IsTrigger: false Material: 0 MaterialPath: "" - - Entity: 3328246672296261054 + - Entity: 8234256119181302872 Parent: 0 Children: [] TagComponent: Tag: Cube TransformComponent: - Position: [1.736814, 1.4724115, -0.88378817] + Position: [1.736814, 1.4724115, -7.9285727] Rotation: [0, 0, 0] Scale: [1, 1, 1] MeshComponent: - AssetID: 18328012085543462741 + AssetID: 14957733959243172548 AssetPath: assets/meshes/Default/Cube.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" RigidBodyComponent: BodyType: 1 Mass: 1 @@ -172,25 +309,29 @@ Entities: IsTrigger: false Material: 0 MaterialPath: "" - - Entity: 4208267561919679628 + - Entity: 5834225236589765516 Parent: 0 Children: [] TagComponent: Tag: Cube TransformComponent: - Position: [-2.6417403, 1.4724115, -4.8956265] - Rotation: [-0.4034239, 0, 0] - Scale: [1, 0.99999994, 0.99999994] + Position: [-2.6417403, 1.4724115, -7.9285727] + Rotation: [0.52199936, 0, 0] + Scale: [1, 1.0000001, 1.0000001] MeshComponent: - AssetID: 18328012085543462741 + AssetID: 14957733959243172548 AssetPath: assets/meshes/Default/Cube.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" RigidBodyComponent: BodyType: 1 Mass: 1 LinearDrag: 0 AngularDrag: 0.05 - DisableGravity: true + DisableGravity: false IsKinematic: false Layer: 0 Constraints: @@ -206,96 +347,25 @@ Entities: IsTrigger: false Material: 0 MaterialPath: "" - - Entity: 8114736924719261351 - Parent: 0 - Children: - [] - TagComponent: - Tag: Camera - TransformComponent: - Position: [0, 0.8097433, 4.573171] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - CameraComponent: - Camera: - ProjectionType: 0 - PerspectiveFOV: 45 - PerspectiveNear: 0.01 - PerspectiveFar: 10000 - OrthographicSize: 10 - OrthographicNear: -1 - OrthographicFar: 1 - Primary: true - - Entity: 9267298328378270409 - Parent: 0 - Children: - [] - TagComponent: - Tag: Player - TransformComponent: - Position: [0, 0.70693016, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - ScriptComponent: - ModuleName: FPSExample.FPSPlayer - StoredFields: - - Name: WalkingSpeed - Type: 1 - Data: 2 - - Name: RunSpeed - Type: 1 - Data: 5 - - Name: JumpForce - Type: 1 - Data: 1 - - Name: MouseSensitivity - Type: 1 - Data: 10 - - Name: CameraForwardOffset - Type: 1 - Data: -2 - - Name: CameraYOffset - Type: 1 - Data: 2 - MeshComponent: - AssetID: 3043502408333723884 - AssetPath: assets/meshes/Default/Capsule.fbx - RigidBodyComponent: - BodyType: 1 - Mass: 1 - LinearDrag: 0 - AngularDrag: 0.05 - DisableGravity: false - IsKinematic: false - Layer: 0 - Constraints: - LockPositionX: false - LockPositionY: false - LockPositionZ: false - LockRotationX: true - LockRotationY: false - LockRotationZ: true - MeshColliderComponent: - IsConvex: true - IsTrigger: false - OverrideMesh: false - Material: 0 - MaterialPath: "" - - Entity: 10732070446010033158 + - Entity: 8293051279669100759 Parent: 0 Children: [] TagComponent: Tag: Cube TransformComponent: - Position: [0, -2.6466873, 0] + Position: [1.736814, 1.4724115, -4.2181306] Rotation: [0, 0, 0] - Scale: [100, 1, 100] + Scale: [1, 1, 1] MeshComponent: - AssetID: 18328012085543462741 + AssetID: 14957733959243172548 AssetPath: assets/meshes/Default/Cube.fbx + Materials: + Slot 0: + AssetHandle: 0 + AssetPath: "" RigidBodyComponent: - BodyType: 0 + BodyType: 1 Mass: 1 LinearDrag: 0 AngularDrag: 0.05 @@ -315,22 +385,5 @@ Entities: IsTrigger: false Material: 0 MaterialPath: "" - - Entity: 5099152432245948441 - Parent: 0 - Children: - [] - TagComponent: - Tag: venice_dawn_1_4k - TransformComponent: - Position: [0, 0, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SkyLightComponent: - EnvironmentMap: 5211537204242875091 - EnvironmentAssetPath: assets/env/venice_dawn_1_4k.hdr - Intensity: 1 - Angle: 0 - DynamicSky: false - TurbidityAzimuthInclination: [2, 0, 0] PhysicsLayers: [] \ No newline at end of file diff --git a/Editor/assets/shaders/PBRShader_Anim.glsl b/Editor/assets/shaders/PBRShader_Anim.glsl index 72845fa..b0b14df 100644 --- a/Editor/assets/shaders/PBRShader_Anim.glsl +++ b/Editor/assets/shaders/PBRShader_Anim.glsl @@ -362,44 +362,38 @@ vec3 IBL(vec3 F0, vec3 Lr) } // shadow - float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir) { - // Perspective divide vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; - - // Transform to [0,1] range projCoords = projCoords * 0.5 + 0.5; - // If outside shadow map bounds, assume no shadow - if(projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0) + if (projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || + projCoords.y < 0.0 || projCoords.y > 1.0) return 0.0; - // Get closest depth value from light's perspective float closestDepth = texture(u_ShadowMap, projCoords.xy).r; float currentDepth = projCoords.z; - // Calculate bias based on surface angle float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1); - // PCF (Percentage Closer Filtering) for soft shadows - float shadow = 0.0; - vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0); - int pcfRange = int(u_ShadowSoftness); - int sampleCount = 0; + int pcfRange = clamp(int(u_ShadowSoftness), 0, 3); - for(int x = -pcfRange; x <= pcfRange; ++x) + vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0); + float shadow = 0.0; + int samples = 0; + + for (int x = -pcfRange; x <= pcfRange; ++x) { - for(int y = -pcfRange; y <= pcfRange; ++y) + for (int y = -pcfRange; y <= pcfRange; ++y) { - float pcfDepth = texture(u_ShadowMap, projCoords.xy + vec2(x, y) * texelSize).r; - shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; - sampleCount++; + vec2 offset = vec2(x, y) * texelSize; + float pcfDepth = texture(u_ShadowMap, projCoords.xy + offset).r; + shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0; + samples++; } } - shadow /= float(sampleCount); - - return shadow; + shadow /= float(samples); + return shadow * u_ShadowIntensity; } diff --git a/Editor/assets/shaders/PBRShader_Static.glsl b/Editor/assets/shaders/PBRShader_Static.glsl index 303a2d1..3761a71 100644 --- a/Editor/assets/shaders/PBRShader_Static.glsl +++ b/Editor/assets/shaders/PBRShader_Static.glsl @@ -347,44 +347,38 @@ vec3 IBL(vec3 F0, vec3 Lr) } // shadow - float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir) { - // Perspective divide vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; - - // Transform to [0,1] range projCoords = projCoords * 0.5 + 0.5; - // If outside shadow map bounds, assume no shadow - if(projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0) + if (projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || + projCoords.y < 0.0 || projCoords.y > 1.0) return 0.0; - // Get closest depth value from light's perspective float closestDepth = texture(u_ShadowMap, projCoords.xy).r; float currentDepth = projCoords.z; - // Calculate bias based on surface angle float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1); - // PCF (Percentage Closer Filtering) for soft shadows - float shadow = 0.0; - vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0); - int pcfRange = int(u_ShadowSoftness); - int sampleCount = 0; + int pcfRange = clamp(int(u_ShadowSoftness), 0, 3); - for(int x = -pcfRange; x <= pcfRange; ++x) + vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0); + float shadow = 0.0; + int samples = 0; + + for (int x = -pcfRange; x <= pcfRange; ++x) { - for(int y = -pcfRange; y <= pcfRange; ++y) + for (int y = -pcfRange; y <= pcfRange; ++y) { - float pcfDepth = texture(u_ShadowMap, projCoords.xy + vec2(x, y) * texelSize).r; - shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; - sampleCount++; + vec2 offset = vec2(x, y) * texelSize; + float pcfDepth = texture(u_ShadowMap, projCoords.xy + offset).r; + shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0; + samples++; } } - shadow /= float(sampleCount); - - return shadow; + shadow /= float(samples); + return shadow * u_ShadowIntensity; } diff --git a/Prism/src/Prism/Renderer/Renderer3D.cpp b/Prism/src/Prism/Renderer/Renderer3D.cpp index 492278b..e8dea0a 100644 --- a/Prism/src/Prism/Renderer/Renderer3D.cpp +++ b/Prism/src/Prism/Renderer/Renderer3D.cpp @@ -39,13 +39,28 @@ namespace Prism float FogHeightFalloff = 0.01f; }FogData; + struct ShadowData + { + Ref ShadowMapShader, ShadowMapAnimShader; + Ref ShadowMapRenderPass; + + bool ShadowEnabled = true; + float ShadowBias = 0.001f; + float ShadowIntensity = 1.0f; + int ShadowSoftness = 1; + + // Dynamic shadow mapping + glm::vec3 SceneCenter{ 0.0f }; + glm::vec3 SceneBounds{ 50.0f }; // Default bounds + float OrthoSize = 100.0f; + }ShadowData; + Ref BRDFLUT; Ref CompositeShader; Ref BloomBlurShader; Ref BloomBlendShader; Ref GeoPass; - // Ref CompositePass; Ref BloomBlurPass[2]; Ref BloomBlendPass; Ref ResolvedHDRTexture; // 解析后的单样本 HDR 颜色 @@ -76,36 +91,16 @@ namespace Prism Ref ExposureCS; } AutoExposureData; - Ref ShadowMapShader, ShadowMapAnimShader; - Ref ShadowMapRenderPass; + RendererID ShadowMapSampler; glm::mat4 LightMatrices; - // float ShadowMapSize = 20.0f; - // float LightDistance = 0.1f; - - // glm::mat4 LightViewMatrix; - // float CascadeSplitLambda = 0.91f; - // glm::vec4 CascadeSplits; - // float CascadeFarPlaneOffset = 15.0f, CascadeNearPlaneOffset = -15.0f; - // bool ShowCascades = false; - // bool SoftShadows = true; - // float LightSize = 0.5f; - // float MaxShadowDistance = 200.0f; - // float ShadowFade = 25.0f; - // float CascadeTransitionFade = 1.0f; - // bool CascadeFading = true; bool EnableBloom = false; float BloomThreshold = 1.5f; glm::vec2 FocusPoint = { 0.5f, 0.5f }; - RendererID ShadowMapSampler; - bool ShadowEnabled = true; - float ShadowBias = 0.001f; - float ShadowIntensity = 0.0f; - int ShadowSoftness = 0; struct DrawCommand { @@ -179,7 +174,7 @@ namespace Prism { FramebufferSpecification bloomBlurFramebufferSpec; bloomBlurFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F , FramebufferTextureFormat::RGBA16F}; - bloomBlurFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f }; + bloomBlurFramebufferSpec.ClearColor = { 0.1f, 0.1f, 1.0f, 1.0f }; RenderPassSpecification bloomBlurRenderPassSpec; bloomBlurRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(bloomBlurFramebufferSpec); @@ -189,7 +184,7 @@ namespace Prism FramebufferSpecification bloomBlendFramebufferSpec; bloomBlendFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F }; - bloomBlendFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f }; + bloomBlendFramebufferSpec.ClearColor = { 0.1f, 0.1f, 1.0f, 1.0f }; RenderPassSpecification bloomBlendRenderPassSpec; bloomBlendRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(bloomBlendFramebufferSpec); @@ -233,7 +228,7 @@ namespace Prism RenderPassSpecification shadowMapRenderPassSpec; shadowMapRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(shadowMapFramebufferSpec); - s_Data.ShadowMapRenderPass = RenderPass::Create(shadowMapRenderPassSpec); + s_Data.ShadowData.ShadowMapRenderPass = RenderPass::Create(shadowMapRenderPassSpec); auto cmd = Renderer::GetCommandBuffer(); @@ -270,8 +265,8 @@ namespace Prism s_Data.ColliderMaterial = MaterialInstance::Create(Material::Create(colliderShader)); s_Data.ColliderMaterial->SetFlag(MaterialFlag::DepthTest, false); - s_Data.ShadowMapShader = Shader::Create("assets/shaders/ShadowMap.glsl"); - s_Data.ShadowMapAnimShader = Shader::Create("assets/shaders/ShadowMap_Anim.glsl"); + s_Data.ShadowData.ShadowMapShader = Shader::Create("assets/shaders/ShadowMap.glsl"); + s_Data.ShadowData.ShadowMapAnimShader = Shader::Create("assets/shaders/ShadowMap_Anim.glsl"); uint32_t blackTextureData[6] = { 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000 }; @@ -591,48 +586,63 @@ namespace Prism { const auto& directionalLights = s_Data.SceneData.SceneLightEnvironment.DirectionalLights; auto cmd = Renderer::GetCommandBuffer(); - if (!s_Data.ShadowEnabled || directionalLights.Intensity == 0.0f || !directionalLights.CastShadows) + + if (!s_Data.ShadowData.ShadowEnabled || directionalLights.Intensity == 0.0f || !directionalLights.CastShadows) { - // Clear shadow maps - Renderer::BeginRenderPass(s_Data.ShadowMapRenderPass); + Renderer::BeginRenderPass(s_Data.ShadowData.ShadowMapRenderPass); Renderer::EndRenderPass(); return; } - // TODO: this will not be hardcode - const glm::vec3 lightDir = glm::normalize(directionalLights.Direction); // 光线方向(从光源指向场景) - const glm::vec3 lightPos = lightDir * 100.0f; - const glm::mat4 lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + const float shadowOrthoSize = s_Data.ShadowData.OrthoSize; + const float shadowNear = 0.1f; + const float shadowFar = shadowOrthoSize * 6.0f; + + const glm::vec3 lightDir = glm::normalize(directionalLights.Direction); + + const glm::vec3 cameraPos = glm::inverse(s_Data.SceneData.SceneCamera.ViewMatrix)[3]; + glm::vec3 shadowCenter = cameraPos; + shadowCenter.y = 0.0f; + + glm::vec3 lightUp = glm::vec3(0.0f, 1.0f, 0.0f); + if (glm::abs(lightDir.y) > 0.9f) + lightUp = glm::vec3(1.0f, 0.0f, 0.0f); + + const glm::vec3 lightPos = shadowCenter + lightDir * (shadowOrthoSize * 3.0f); + const glm::mat4 lightView = glm::lookAt(lightPos, shadowCenter, lightUp); + const glm::mat4 lightProj = glm::ortho( + -shadowOrthoSize, shadowOrthoSize, + -shadowOrthoSize, shadowOrthoSize, + shadowNear, shadowFar + ); + + const glm::mat4 lightSpaceMatrix = lightProj * lightView; + s_Data.LightMatrices = lightSpaceMatrix; - const float orthoSize = 100.0f; - const float nearPlane = 0.01f, farPlane = 1000.0f; - const glm::mat4 lightProjection = glm::ortho(-orthoSize, orthoSize, -orthoSize, orthoSize, nearPlane, farPlane); - const glm::mat4 lightSpaceMatrix = lightProjection * lightView; - // auto cmd = Renderer::GetCommandBuffer(); Renderer::Submit([cmd]() { cmd->SetCullMode(CullMode::Back); }); + Renderer::BeginRenderPass(s_Data.ShadowData.ShadowMapRenderPass); + + for (auto& dc : s_Data.ShadowPassDrawList) { - Renderer::BeginRenderPass(s_Data.ShadowMapRenderPass); + if (!dc.mesh) continue; - s_Data.LightMatrices = lightSpaceMatrix; + Ref shader = dc.mesh->IsAnimated() + ? s_Data.ShadowData.ShadowMapAnimShader + : s_Data.ShadowData.ShadowMapShader; - - // Render entities - for (auto& dc : s_Data.ShadowPassDrawList) - { - Ref shader = dc.mesh->IsAnimated() ? s_Data.ShadowMapAnimShader : s_Data.ShadowMapShader; - shader->SetMat4("u_LightViewProjection", lightSpaceMatrix); - Renderer::SubmitMeshWithShader(dc.mesh, dc.Transform, shader); - } - - Renderer::EndRenderPass(); + shader->SetMat4("u_LightViewProjection", lightSpaceMatrix); + Renderer::SubmitMeshWithShader(dc.mesh, dc.Transform, shader); } + + Renderer::EndRenderPass(); } + void Renderer3D::GeometryPass() { const bool outline = !s_Data.SelectedMeshDrawList.empty(); @@ -730,21 +740,25 @@ namespace Prism // shadow baseMaterial->Set("u_LightSpaceMatrix", s_Data.LightMatrices); - baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowEnabled); - baseMaterial->Set("u_ShadowBias", s_Data.ShadowBias); - baseMaterial->Set("u_ShadowIntensity", s_Data.ShadowIntensity); - - auto rd = baseMaterial->FindResourceDeclaration("u_ShadowMap"); - if (rd) + baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowData.ShadowEnabled); + if (s_Data.ShadowData.ShadowEnabled) { - auto reg = rd->GetRegister(); - auto tex = s_Data.ShadowMapRenderPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID(); + baseMaterial->Set("u_ShadowBias", s_Data.ShadowData.ShadowBias); + baseMaterial->Set("u_ShadowIntensity", s_Data.ShadowData.ShadowIntensity); + baseMaterial->Set("u_ShadowSoftness", (float)s_Data.ShadowData.ShadowSoftness); - Renderer::Submit([reg, tex, cmd]() mutable + auto rd = baseMaterial->FindResourceDeclaration("u_ShadowMap"); + if (rd) { - cmd->BindTextureUnit(reg, tex); - cmd->BindSampler(reg, s_Data.ShadowMapSampler); - }); + auto reg = rd->GetRegister(); + auto tex = s_Data.ShadowData.ShadowMapRenderPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID(); + + Renderer::Submit([reg, tex, cmd]() mutable + { + cmd->BindTextureUnit(reg, tex); + cmd->BindSampler(reg, s_Data.ShadowMapSampler); + }); + } } Renderer::SubmitMesh(dc.mesh, dc.Transform, dc.MaterialInstances); @@ -811,23 +825,27 @@ namespace Prism // shadow - baseMaterial->Set("u_LightSpaceMatrix", s_Data.LightMatrices); - baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowEnabled); - baseMaterial->Set("u_ShadowBias", s_Data.ShadowBias); - baseMaterial->Set("u_ShadowIntensity", s_Data.ShadowIntensity); - - - auto rd = baseMaterial->FindResourceDeclaration("u_ShadowMap"); - if (rd) + baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowData.ShadowEnabled); + if (s_Data.ShadowData.ShadowEnabled) { - auto reg = rd->GetRegister(); - auto tex = s_Data.ShadowMapRenderPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID(); + baseMaterial->Set("u_LightSpaceMatrix", s_Data.LightMatrices); + baseMaterial->Set("u_ShadowBias", s_Data.ShadowData.ShadowBias); + baseMaterial->Set("u_ShadowIntensity", s_Data.ShadowData.ShadowIntensity); + baseMaterial->Set("u_ShadowSoftness", (float)s_Data.ShadowData.ShadowSoftness); - Renderer::Submit([reg, tex, cmd]() mutable + + auto rd = baseMaterial->FindResourceDeclaration("u_ShadowMap"); + if (rd) { - cmd->BindTextureUnit(reg, tex); - cmd->BindSampler(reg, s_Data.ShadowMapSampler); - }); + auto reg = rd->GetRegister(); + auto tex = s_Data.ShadowData.ShadowMapRenderPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID(); + + Renderer::Submit([reg, tex, cmd]() mutable + { + cmd->BindTextureUnit(reg, tex); + cmd->BindSampler(reg, s_Data.ShadowMapSampler); + }); + } } Renderer::SubmitMesh(dc.mesh, dc.Transform, dc.MaterialInstances); @@ -1085,30 +1103,6 @@ namespace Prism } - std::vector GetFrustumCornersWorldSpace(const SceneRendererCamera& sceneCamera) - { - std::vector corners(8); - const auto& proj = sceneCamera.Camera.GetProjectionMatrix(); - const auto& view = sceneCamera.ViewMatrix; - const glm::mat4 invViewProj = glm::inverse(proj * view); - - // 视锥体在 NDC 空间中的八个点 - const std::vector ndcCorners = { - glm::vec4(-1, -1, -1, 1), glm::vec4( 1, -1, -1, 1), - glm::vec4( 1, 1, -1, 1), glm::vec4(-1, 1, -1, 1), - glm::vec4(-1, -1, 1, 1), glm::vec4( 1, -1, 1, 1), - glm::vec4( 1, 1, 1, 1), glm::vec4(-1, 1, 1, 1) - }; - - for (size_t i = 0; i < 8; ++i) - { - glm::vec4 worldPos = invViewProj * ndcCorners[i]; - worldPos /= worldPos.w; - corners[i] = glm::vec3(worldPos); - } - return corners; - } - void Renderer3D::ResolveMSAA() { @@ -1194,13 +1188,15 @@ namespace Prism { UI::BeginPropertyGrid(); - UI::Property("EnableMap", s_Data.ShadowEnabled); - UI::Property("ShadowBias", s_Data.ShadowBias, 0.01f); - UI::Property("ShadowSoftness", s_Data.ShadowSoftness); - UI::Property("ShadowIntensity", s_Data.ShadowIntensity, 0.01f); + UI::Property("EnableMap", s_Data.ShadowData.ShadowEnabled); + UI::Property("ShadowBias", s_Data.ShadowData.ShadowBias, 0.01f); + UI::PropertySlider("ShadowSoftness", s_Data.ShadowData.ShadowSoftness, 0, 3); + UI::Property("ShadowIntensity", s_Data.ShadowData.ShadowIntensity, 0.01f); + UI::Property("Ortho Size", s_Data.ShadowData.OrthoSize); + // UI::Property("Shadow Distance", s_Data.ShadowD0ata.ShadowDistance); UI::EndPropertyGrid(); - auto fb = s_Data.ShadowMapRenderPass->GetSpecification().TargetFramebuffer; + auto fb = s_Data.ShadowData.ShadowMapRenderPass->GetSpecification().TargetFramebuffer; auto id = fb->GetDepthAttachmentRendererID(); float size = ImGui::GetContentRegionAvail().x; // (float)fb->GetWidth() * 0.5f, (float)fb->GetHeight() * 0.5f @@ -1267,5 +1263,4 @@ namespace Prism ImGui::End(); } -} - +} \ No newline at end of file