improve shadow process, now shadow can render according to the camera position

This commit is contained in:
2026-04-07 13:20:02 +08:00
parent 3c64abd77e
commit 230957f728
5 changed files with 309 additions and 274 deletions

View File

@ -1085,7 +1085,6 @@ namespace Prism
continue; continue;
auto& submeshes = mesh->GetSubmeshes(); auto& submeshes = mesh->GetSubmeshes();
float lastT = std::numeric_limits<float>::max();
for (uint32_t i = 0; i < submeshes.size(); i++) for (uint32_t i = 0; i < submeshes.size(); i++)
{ {
auto& submesh = submeshes[i]; auto& submesh = submeshes[i];

View File

@ -1,22 +1,58 @@
Scene: Scene Name Scene: Scene Name
Environment: Environment:
AssetHandle: 5211537204242875091 AssetHandle: 10745193190519058183
Entities: 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 Parent: 0
Children: Children:
[] []
TagComponent: TagComponent:
Tag: Cube Tag: Cube
TransformComponent: TransformComponent:
Position: [1.736814, 1.4724115, -4.2181306] Position: [0, -2.6466873, 0]
Rotation: [0, 0, 0] Rotation: [0, 0, 0]
Scale: [1, 1, 1] Scale: [100, 1, 100]
MeshComponent: MeshComponent:
AssetID: 18328012085543462741 AssetID: 14957733959243172548
AssetPath: assets/meshes/Default/Cube.fbx AssetPath: assets/meshes/Default/Cube.fbx
Materials:
Slot 0:
AssetHandle: 0
AssetPath: ""
RigidBodyComponent: RigidBodyComponent:
BodyType: 1 BodyType: 0
Mass: 1 Mass: 1
LinearDrag: 0 LinearDrag: 0
AngularDrag: 0.05 AngularDrag: 0.05
@ -36,19 +72,50 @@ Entities:
IsTrigger: false IsTrigger: false
Material: 0 Material: 0
MaterialPath: "" MaterialPath: ""
- Entity: 5834225236589765516 - Entity: 9267298328378270409
Parent: 0 Parent: 0
Children: Children:
[] []
TagComponent: TagComponent:
Tag: Cube Tag: Player
TransformComponent: TransformComponent:
Position: [-2.6417403, 1.4724115, -7.9285727] Position: [0, 0.70693016, 0]
Rotation: [0.52199936, 0, 0] Rotation: [0, 0, 0]
Scale: [1, 1.0000001, 1.0000001] 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: MeshComponent:
AssetID: 18328012085543462741 AssetID: 8763440120556133680
AssetPath: assets/meshes/Default/Cube.fbx AssetPath: assets/meshes/Default/Capsule.fbx
Materials:
Slot 0:
AssetHandle: 0
AssetPath: ""
RigidBodyComponent: RigidBodyComponent:
BodyType: 1 BodyType: 1
Mass: 1 Mass: 1
@ -57,6 +124,64 @@ Entities:
DisableGravity: false DisableGravity: false
IsKinematic: false IsKinematic: false
Layer: 0 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: Constraints:
LockPositionX: false LockPositionX: false
LockPositionY: false LockPositionY: false
@ -70,19 +195,23 @@ Entities:
IsTrigger: false IsTrigger: false
Material: 0 Material: 0
MaterialPath: "" MaterialPath: ""
- Entity: 8234256119181302872 - Entity: 3328246672296261054
Parent: 0 Parent: 0
Children: Children:
[] []
TagComponent: TagComponent:
Tag: Cube Tag: Cube
TransformComponent: TransformComponent:
Position: [1.736814, 1.4724115, -7.9285727] Position: [1.736814, 1.4724115, -0.88378817]
Rotation: [0, 0, 0] Rotation: [0, 0, 0]
Scale: [1, 1, 1] Scale: [1, 1, 1]
MeshComponent: MeshComponent:
AssetID: 18328012085543462741 AssetID: 14957733959243172548
AssetPath: assets/meshes/Default/Cube.fbx AssetPath: assets/meshes/Default/Cube.fbx
Materials:
Slot 0:
AssetHandle: 0
AssetPath: ""
RigidBodyComponent: RigidBodyComponent:
BodyType: 1 BodyType: 1
Mass: 1 Mass: 1
@ -115,8 +244,12 @@ Entities:
Rotation: [0, 0, 0] Rotation: [0, 0, 0]
Scale: [1, 1, 1] Scale: [1, 1, 1]
MeshComponent: MeshComponent:
AssetID: 18328012085543462741 AssetID: 14957733959243172548
AssetPath: assets/meshes/Default/Cube.fbx AssetPath: assets/meshes/Default/Cube.fbx
Materials:
Slot 0:
AssetHandle: 0
AssetPath: ""
RigidBodyComponent: RigidBodyComponent:
BodyType: 1 BodyType: 1
Mass: 1 Mass: 1
@ -138,19 +271,23 @@ Entities:
IsTrigger: false IsTrigger: false
Material: 0 Material: 0
MaterialPath: "" MaterialPath: ""
- Entity: 3328246672296261054 - Entity: 8234256119181302872
Parent: 0 Parent: 0
Children: Children:
[] []
TagComponent: TagComponent:
Tag: Cube Tag: Cube
TransformComponent: TransformComponent:
Position: [1.736814, 1.4724115, -0.88378817] Position: [1.736814, 1.4724115, -7.9285727]
Rotation: [0, 0, 0] Rotation: [0, 0, 0]
Scale: [1, 1, 1] Scale: [1, 1, 1]
MeshComponent: MeshComponent:
AssetID: 18328012085543462741 AssetID: 14957733959243172548
AssetPath: assets/meshes/Default/Cube.fbx AssetPath: assets/meshes/Default/Cube.fbx
Materials:
Slot 0:
AssetHandle: 0
AssetPath: ""
RigidBodyComponent: RigidBodyComponent:
BodyType: 1 BodyType: 1
Mass: 1 Mass: 1
@ -172,25 +309,29 @@ Entities:
IsTrigger: false IsTrigger: false
Material: 0 Material: 0
MaterialPath: "" MaterialPath: ""
- Entity: 4208267561919679628 - Entity: 5834225236589765516
Parent: 0 Parent: 0
Children: Children:
[] []
TagComponent: TagComponent:
Tag: Cube Tag: Cube
TransformComponent: TransformComponent:
Position: [-2.6417403, 1.4724115, -4.8956265] Position: [-2.6417403, 1.4724115, -7.9285727]
Rotation: [-0.4034239, 0, 0] Rotation: [0.52199936, 0, 0]
Scale: [1, 0.99999994, 0.99999994] Scale: [1, 1.0000001, 1.0000001]
MeshComponent: MeshComponent:
AssetID: 18328012085543462741 AssetID: 14957733959243172548
AssetPath: assets/meshes/Default/Cube.fbx AssetPath: assets/meshes/Default/Cube.fbx
Materials:
Slot 0:
AssetHandle: 0
AssetPath: ""
RigidBodyComponent: RigidBodyComponent:
BodyType: 1 BodyType: 1
Mass: 1 Mass: 1
LinearDrag: 0 LinearDrag: 0
AngularDrag: 0.05 AngularDrag: 0.05
DisableGravity: true DisableGravity: false
IsKinematic: false IsKinematic: false
Layer: 0 Layer: 0
Constraints: Constraints:
@ -206,96 +347,25 @@ Entities:
IsTrigger: false IsTrigger: false
Material: 0 Material: 0
MaterialPath: "" MaterialPath: ""
- Entity: 8114736924719261351 - Entity: 8293051279669100759
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
Parent: 0 Parent: 0
Children: Children:
[] []
TagComponent: TagComponent:
Tag: Cube Tag: Cube
TransformComponent: TransformComponent:
Position: [0, -2.6466873, 0] Position: [1.736814, 1.4724115, -4.2181306]
Rotation: [0, 0, 0] Rotation: [0, 0, 0]
Scale: [100, 1, 100] Scale: [1, 1, 1]
MeshComponent: MeshComponent:
AssetID: 18328012085543462741 AssetID: 14957733959243172548
AssetPath: assets/meshes/Default/Cube.fbx AssetPath: assets/meshes/Default/Cube.fbx
Materials:
Slot 0:
AssetHandle: 0
AssetPath: ""
RigidBodyComponent: RigidBodyComponent:
BodyType: 0 BodyType: 1
Mass: 1 Mass: 1
LinearDrag: 0 LinearDrag: 0
AngularDrag: 0.05 AngularDrag: 0.05
@ -315,22 +385,5 @@ Entities:
IsTrigger: false IsTrigger: false
Material: 0 Material: 0
MaterialPath: "" 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: PhysicsLayers:
[] []

View File

@ -362,44 +362,38 @@ vec3 IBL(vec3 F0, vec3 Lr)
} }
// shadow // shadow
float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir) float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir)
{ {
// Perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// Transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5; 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 ||
if(projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0) projCoords.y < 0.0 || projCoords.y > 1.0)
return 0.0; return 0.0;
// Get closest depth value from light's perspective
float closestDepth = texture(u_ShadowMap, projCoords.xy).r; float closestDepth = texture(u_ShadowMap, projCoords.xy).r;
float currentDepth = projCoords.z; float currentDepth = projCoords.z;
// Calculate bias based on surface angle
float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1); float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1);
// PCF (Percentage Closer Filtering) for soft shadows int pcfRange = clamp(int(u_ShadowSoftness), 0, 3);
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0);
int pcfRange = int(u_ShadowSoftness);
int sampleCount = 0;
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; vec2 offset = vec2(x, y) * texelSize;
shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; float pcfDepth = texture(u_ShadowMap, projCoords.xy + offset).r;
sampleCount++; shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0;
samples++;
} }
} }
shadow /= float(sampleCount); shadow /= float(samples);
return shadow * u_ShadowIntensity;
return shadow;
} }

View File

@ -347,44 +347,38 @@ vec3 IBL(vec3 F0, vec3 Lr)
} }
// shadow // shadow
float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir) float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir)
{ {
// Perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// Transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5; 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 ||
if(projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0) projCoords.y < 0.0 || projCoords.y > 1.0)
return 0.0; return 0.0;
// Get closest depth value from light's perspective
float closestDepth = texture(u_ShadowMap, projCoords.xy).r; float closestDepth = texture(u_ShadowMap, projCoords.xy).r;
float currentDepth = projCoords.z; float currentDepth = projCoords.z;
// Calculate bias based on surface angle
float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1); float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1);
// PCF (Percentage Closer Filtering) for soft shadows int pcfRange = clamp(int(u_ShadowSoftness), 0, 3);
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0);
int pcfRange = int(u_ShadowSoftness);
int sampleCount = 0;
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; vec2 offset = vec2(x, y) * texelSize;
shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; float pcfDepth = texture(u_ShadowMap, projCoords.xy + offset).r;
sampleCount++; shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0;
samples++;
} }
} }
shadow /= float(sampleCount); shadow /= float(samples);
return shadow * u_ShadowIntensity;
return shadow;
} }

View File

@ -39,13 +39,28 @@ namespace Prism
float FogHeightFalloff = 0.01f; float FogHeightFalloff = 0.01f;
}FogData; }FogData;
struct ShadowData
{
Ref<Shader> ShadowMapShader, ShadowMapAnimShader;
Ref<RenderPass> 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<Texture2D> BRDFLUT; Ref<Texture2D> BRDFLUT;
Ref<Shader> CompositeShader; Ref<Shader> CompositeShader;
Ref<Shader> BloomBlurShader; Ref<Shader> BloomBlurShader;
Ref<Shader> BloomBlendShader; Ref<Shader> BloomBlendShader;
Ref<RenderPass> GeoPass; Ref<RenderPass> GeoPass;
// Ref<RenderPass> CompositePass;
Ref<RenderPass> BloomBlurPass[2]; Ref<RenderPass> BloomBlurPass[2];
Ref<RenderPass> BloomBlendPass; Ref<RenderPass> BloomBlendPass;
Ref<Texture2D> ResolvedHDRTexture; // 解析后的单样本 HDR 颜色 Ref<Texture2D> ResolvedHDRTexture; // 解析后的单样本 HDR 颜色
@ -76,36 +91,16 @@ namespace Prism
Ref<Shader> ExposureCS; Ref<Shader> ExposureCS;
} AutoExposureData; } AutoExposureData;
Ref<Shader> ShadowMapShader, ShadowMapAnimShader; RendererID ShadowMapSampler;
Ref<RenderPass> ShadowMapRenderPass;
glm::mat4 LightMatrices; 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; bool EnableBloom = false;
float BloomThreshold = 1.5f; float BloomThreshold = 1.5f;
glm::vec2 FocusPoint = { 0.5f, 0.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 struct DrawCommand
{ {
@ -179,7 +174,7 @@ namespace Prism
{ {
FramebufferSpecification bloomBlurFramebufferSpec; FramebufferSpecification bloomBlurFramebufferSpec;
bloomBlurFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F , FramebufferTextureFormat::RGBA16F}; 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; RenderPassSpecification bloomBlurRenderPassSpec;
bloomBlurRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(bloomBlurFramebufferSpec); bloomBlurRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(bloomBlurFramebufferSpec);
@ -189,7 +184,7 @@ namespace Prism
FramebufferSpecification bloomBlendFramebufferSpec; FramebufferSpecification bloomBlendFramebufferSpec;
bloomBlendFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F }; 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; RenderPassSpecification bloomBlendRenderPassSpec;
bloomBlendRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(bloomBlendFramebufferSpec); bloomBlendRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(bloomBlendFramebufferSpec);
@ -233,7 +228,7 @@ namespace Prism
RenderPassSpecification shadowMapRenderPassSpec; RenderPassSpecification shadowMapRenderPassSpec;
shadowMapRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(shadowMapFramebufferSpec); shadowMapRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(shadowMapFramebufferSpec);
s_Data.ShadowMapRenderPass = RenderPass::Create(shadowMapRenderPassSpec); s_Data.ShadowData.ShadowMapRenderPass = RenderPass::Create(shadowMapRenderPassSpec);
auto cmd = Renderer::GetCommandBuffer(); auto cmd = Renderer::GetCommandBuffer();
@ -270,8 +265,8 @@ namespace Prism
s_Data.ColliderMaterial = MaterialInstance::Create(Material::Create(colliderShader)); s_Data.ColliderMaterial = MaterialInstance::Create(Material::Create(colliderShader));
s_Data.ColliderMaterial->SetFlag(MaterialFlag::DepthTest, false); s_Data.ColliderMaterial->SetFlag(MaterialFlag::DepthTest, false);
s_Data.ShadowMapShader = Shader::Create("assets/shaders/ShadowMap.glsl"); s_Data.ShadowData.ShadowMapShader = Shader::Create("assets/shaders/ShadowMap.glsl");
s_Data.ShadowMapAnimShader = Shader::Create("assets/shaders/ShadowMap_Anim.glsl"); s_Data.ShadowData.ShadowMapAnimShader = Shader::Create("assets/shaders/ShadowMap_Anim.glsl");
uint32_t blackTextureData[6] = { 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000 }; uint32_t blackTextureData[6] = { 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000 };
@ -591,48 +586,63 @@ namespace Prism
{ {
const auto& directionalLights = s_Data.SceneData.SceneLightEnvironment.DirectionalLights; const auto& directionalLights = s_Data.SceneData.SceneLightEnvironment.DirectionalLights;
auto cmd = Renderer::GetCommandBuffer(); 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.ShadowData.ShadowMapRenderPass);
Renderer::BeginRenderPass(s_Data.ShadowMapRenderPass);
Renderer::EndRenderPass(); Renderer::EndRenderPass();
return; return;
} }
// TODO: this will not be hardcode const float shadowOrthoSize = s_Data.ShadowData.OrthoSize;
const glm::vec3 lightDir = glm::normalize(directionalLights.Direction); // 光线方向(从光源指向场景) const float shadowNear = 0.1f;
const glm::vec3 lightPos = lightDir * 100.0f; const float shadowFar = shadowOrthoSize * 6.0f;
const glm::mat4 lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.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]() Renderer::Submit([cmd]()
{ {
cmd->SetCullMode(CullMode::Back); 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> shader = dc.mesh->IsAnimated()
? s_Data.ShadowData.ShadowMapAnimShader
: s_Data.ShadowData.ShadowMapShader;
shader->SetMat4("u_LightViewProjection", lightSpaceMatrix);
// Render entities Renderer::SubmitMeshWithShader(dc.mesh, dc.Transform, shader);
for (auto& dc : s_Data.ShadowPassDrawList)
{
Ref<Shader> shader = dc.mesh->IsAnimated() ? s_Data.ShadowMapAnimShader : s_Data.ShadowMapShader;
shader->SetMat4("u_LightViewProjection", lightSpaceMatrix);
Renderer::SubmitMeshWithShader(dc.mesh, dc.Transform, shader);
}
Renderer::EndRenderPass();
} }
Renderer::EndRenderPass();
} }
void Renderer3D::GeometryPass() void Renderer3D::GeometryPass()
{ {
const bool outline = !s_Data.SelectedMeshDrawList.empty(); const bool outline = !s_Data.SelectedMeshDrawList.empty();
@ -730,21 +740,25 @@ namespace Prism
// shadow // shadow
baseMaterial->Set("u_LightSpaceMatrix", s_Data.LightMatrices); baseMaterial->Set("u_LightSpaceMatrix", s_Data.LightMatrices);
baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowEnabled); baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowData.ShadowEnabled);
baseMaterial->Set("u_ShadowBias", s_Data.ShadowBias); if (s_Data.ShadowData.ShadowEnabled)
baseMaterial->Set("u_ShadowIntensity", s_Data.ShadowIntensity);
auto rd = baseMaterial->FindResourceDeclaration("u_ShadowMap");
if (rd)
{ {
auto reg = rd->GetRegister(); baseMaterial->Set("u_ShadowBias", s_Data.ShadowData.ShadowBias);
auto tex = s_Data.ShadowMapRenderPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID(); 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); auto reg = rd->GetRegister();
cmd->BindSampler(reg, s_Data.ShadowMapSampler); 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); Renderer::SubmitMesh(dc.mesh, dc.Transform, dc.MaterialInstances);
@ -811,23 +825,27 @@ namespace Prism
// shadow // shadow
baseMaterial->Set("u_LightSpaceMatrix", s_Data.LightMatrices); baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowData.ShadowEnabled);
baseMaterial->Set("u_ShadowEnabled", s_Data.ShadowEnabled); if (s_Data.ShadowData.ShadowEnabled)
baseMaterial->Set("u_ShadowBias", s_Data.ShadowBias);
baseMaterial->Set("u_ShadowIntensity", s_Data.ShadowIntensity);
auto rd = baseMaterial->FindResourceDeclaration("u_ShadowMap");
if (rd)
{ {
auto reg = rd->GetRegister(); baseMaterial->Set("u_LightSpaceMatrix", s_Data.LightMatrices);
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); auto reg = rd->GetRegister();
cmd->BindSampler(reg, s_Data.ShadowMapSampler); 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); Renderer::SubmitMesh(dc.mesh, dc.Transform, dc.MaterialInstances);
@ -1085,30 +1103,6 @@ namespace Prism
} }
std::vector<glm::vec3> GetFrustumCornersWorldSpace(const SceneRendererCamera& sceneCamera)
{
std::vector<glm::vec3> 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<glm::vec4> 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() void Renderer3D::ResolveMSAA()
{ {
@ -1194,13 +1188,15 @@ namespace Prism
{ {
UI::BeginPropertyGrid(); UI::BeginPropertyGrid();
UI::Property("EnableMap", s_Data.ShadowEnabled); UI::Property("EnableMap", s_Data.ShadowData.ShadowEnabled);
UI::Property("ShadowBias", s_Data.ShadowBias, 0.01f); UI::Property("ShadowBias", s_Data.ShadowData.ShadowBias, 0.01f);
UI::Property("ShadowSoftness", s_Data.ShadowSoftness); UI::PropertySlider("ShadowSoftness", s_Data.ShadowData.ShadowSoftness, 0, 3);
UI::Property("ShadowIntensity", s_Data.ShadowIntensity, 0.01f); 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(); UI::EndPropertyGrid();
auto fb = s_Data.ShadowMapRenderPass->GetSpecification().TargetFramebuffer; auto fb = s_Data.ShadowData.ShadowMapRenderPass->GetSpecification().TargetFramebuffer;
auto id = fb->GetDepthAttachmentRendererID(); auto id = fb->GetDepthAttachmentRendererID();
float size = ImGui::GetContentRegionAvail().x; // (float)fb->GetWidth() * 0.5f, (float)fb->GetHeight() * 0.5f float size = ImGui::GetContentRegionAvail().x; // (float)fb->GetWidth() * 0.5f, (float)fb->GetHeight() * 0.5f
@ -1268,4 +1264,3 @@ namespace Prism
} }
} }