Skip to content

Commit 42cee47

Browse files
authored
[WIP] Fixed feature set override in shadow, outline, and picking passes (#523)
* Fixed feature set override in shadow, outline, and picking passes * Removed _LightSpaceMatrix for shadow casting, using ubo instead (view and proj) * Cleaned up shadow rendering code * Updated Engine UBO code to support overriding the view
1 parent 7fbf15b commit 42cee47

File tree

25 files changed

+232
-179
lines changed

25 files changed

+232
-179
lines changed

Resources/Engine/Shaders/Lambert.ovfx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,13 @@ out VS_OUT
1717
vec3 Normal;
1818
} vs_out;
1919

20-
#if defined(SHADOW_PASS)
21-
uniform mat4 _LightSpaceMatrix;
22-
#endif
23-
2420
void main()
2521
{
2622
vs_out.FragPos = vec3(ubo_Model * vec4(geo_Pos, 1.0));
2723
vs_out.TexCoords = geo_TexCoords;
2824
vs_out.Normal = normalize(mat3(transpose(inverse(ubo_Model))) * geo_Normal);
2925

30-
#if defined(SHADOW_PASS)
31-
gl_Position = _LightSpaceMatrix * vec4(vs_out.FragPos, 1.0);
32-
#else
3326
gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0);
34-
#endif
3527
}
3628

3729
#shader fragment

Resources/Engine/Shaders/ShadowFallback.ovfx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ layout (location = 0) in vec3 geo_Pos;
55

66
#include ":Shaders/Common/Buffers/EngineUBO.ovfxh"
77

8-
uniform mat4 _LightSpaceMatrix;
9-
108
void main()
119
{
12-
gl_Position = _LightSpaceMatrix * ubo_Model * vec4(geo_Pos, 1.0);
10+
gl_Position = ubo_Projection * ubo_View * ubo_Model * vec4(geo_Pos, 1.0);
1311
}
1412

1513
#shader fragment

Resources/Engine/Shaders/Standard.ovfx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ out VS_OUT
2727
#endif
2828
} vs_out;
2929

30-
#if defined(SHADOW_PASS)
31-
uniform mat4 _LightSpaceMatrix;
32-
#endif
33-
3430
void main()
3531
{
3632
vs_out.FragPos = vec3(ubo_Model * vec4(geo_Pos, 1.0));
@@ -43,11 +39,7 @@ void main()
4339
vs_out.TangentFragPos = transpose(vs_out.TBN) * vs_out.FragPos;
4440
#endif
4541

46-
#if defined(SHADOW_PASS)
47-
gl_Position = _LightSpaceMatrix * vec4(vs_out.FragPos, 1.0);
48-
#else
4942
gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0);
50-
#endif
5143
}
5244

5345
#shader fragment

Resources/Engine/Shaders/StandardPBR.ovfx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ out VS_OUT
2727
#endif
2828
} vs_out;
2929

30-
#if defined(SHADOW_PASS)
31-
uniform mat4 _LightSpaceMatrix;
32-
#endif
33-
3430
void main()
3531
{
3632
vs_out.FragPos = vec3(ubo_Model * vec4(geo_Pos, 1.0));
@@ -43,11 +39,7 @@ void main()
4339
vs_out.TangentFragPos = transpose(vs_out.TBN) * vs_out.FragPos;
4440
#endif
4541

46-
#if defined(SHADOW_PASS)
47-
gl_Position = _LightSpaceMatrix * vec4(vs_out.FragPos, 1.0);
48-
#else
4942
gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0);
50-
#endif
5143
}
5244

5345
#shader fragment

Resources/Engine/Shaders/Unlit.ovfx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,12 @@ out VS_OUT
1616
vec2 TexCoords;
1717
} vs_out;
1818

19-
#if defined(SHADOW_PASS)
20-
uniform mat4 _LightSpaceMatrix;
21-
#endif
22-
2319
void main()
2420
{
2521
vs_out.FragPos = vec3(ubo_Model * vec4(geo_Pos, 1.0));
2622
vs_out.TexCoords = geo_TexCoords;
2723

28-
#if defined(SHADOW_PASS)
29-
gl_Position = _LightSpaceMatrix * vec4(vs_out.FragPos, 1.0);
30-
#else
3124
gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0);
32-
#endif
3325
}
3426

3527
#shader fragment

Sources/Overload/OvCore/include/OvCore/Rendering/EngineBufferRenderFeature.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
#pragma once
88

9-
#include <map>
109
#include <chrono>
10+
#include <map>
11+
#include <stack>
1112

1213
#include <OvRendering/Features/ARenderFeature.h>
1314
#include <OvRendering/HAL/UniformBuffer.h>
@@ -27,6 +28,12 @@ namespace OvCore::Rendering
2728
*/
2829
EngineBufferRenderFeature(OvRendering::Core::CompositeRenderer& p_renderer);
2930

31+
/**
32+
* Replace the current camera data in the engine buffer by the provided camera
33+
* @param p_camera
34+
*/
35+
void SetCamera(const OvRendering::Entities::Camera& p_camera);
36+
3037
protected:
3138
virtual void OnBeginFrame(const OvRendering::Data::FrameDescriptor& p_frameDescriptor) override;
3239
virtual void OnEndFrame() override;
@@ -35,6 +42,5 @@ namespace OvCore::Rendering
3542
protected:
3643
std::chrono::high_resolution_clock::time_point m_startTime;
3744
std::unique_ptr<OvRendering::HAL::UniformBuffer> m_engineBuffer;
38-
OvRendering::Data::FrameDescriptor m_cachedFrameDescriptor;
3945
};
4046
}

Sources/Overload/OvCore/include/OvCore/Rendering/ShadowRenderPass.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ namespace OvCore::Rendering
3636

3737
void DrawShadows(
3838
OvRendering::Data::PipelineState p_pso,
39-
OvCore::SceneSystem::Scene& p_scene,
40-
const OvMaths::FMatrix4& p_lightSpaceMatrix
39+
OvCore::SceneSystem::Scene& p_scene
4140
);
4241

4342
private:

Sources/Overload/OvCore/src/OvCore/Rendering/EngineBufferRenderFeature.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,32 @@ OvCore::Rendering::EngineBufferRenderFeature::EngineBufferRenderFeature(OvRender
2424
: ARenderFeature(p_renderer)
2525
{
2626
m_engineBuffer = std::make_unique<OvRendering::HAL::UniformBuffer>();
27-
2827
m_engineBuffer->Allocate(kUBOSize, OvRendering::Settings::EAccessSpecifier::STREAM_DRAW);
29-
3028
m_startTime = std::chrono::high_resolution_clock::now();
3129
}
3230

31+
void OvCore::Rendering::EngineBufferRenderFeature::SetCamera(const OvRendering::Entities::Camera& p_camera)
32+
{
33+
struct
34+
{
35+
OvMaths::FMatrix4 viewMatrix;
36+
OvMaths::FMatrix4 projectionMatrix;
37+
OvMaths::FVector3 cameraPosition;
38+
} uboDataPage{
39+
.viewMatrix = OvMaths::FMatrix4::Transpose(p_camera.GetViewMatrix()),
40+
.projectionMatrix = OvMaths::FMatrix4::Transpose(p_camera.GetProjectionMatrix()),
41+
.cameraPosition = p_camera.GetPosition()
42+
};
43+
44+
m_engineBuffer->Upload(&uboDataPage, OvRendering::HAL::BufferMemoryRange{
45+
.offset = sizeof(OvMaths::FMatrix4), // Skip uploading the first matrix (Model matrix)
46+
.size = sizeof(uboDataPage)
47+
});
48+
}
49+
3350
void OvCore::Rendering::EngineBufferRenderFeature::OnBeginFrame(const OvRendering::Data::FrameDescriptor& p_frameDescriptor)
3451
{
35-
m_cachedFrameDescriptor = p_frameDescriptor;
52+
OVASSERT(p_frameDescriptor.camera.has_value(), "Camera is not set in the frame descriptor");
3653

3754
auto currentTime = std::chrono::high_resolution_clock::now();
3855
auto elapsedTime = std::chrono::duration_cast<std::chrono::duration<float>>(currentTime - m_startTime);
@@ -43,7 +60,7 @@ void OvCore::Rendering::EngineBufferRenderFeature::OnBeginFrame(const OvRenderin
4360
OvMaths::FMatrix4 projectionMatrix;
4461
OvMaths::FVector3 cameraPosition;
4562
float elapsedTime;
46-
} uboDataPage {
63+
} uboDataPage{
4764
.viewMatrix = OvMaths::FMatrix4::Transpose(p_frameDescriptor.camera->GetViewMatrix()),
4865
.projectionMatrix = OvMaths::FMatrix4::Transpose(p_frameDescriptor.camera->GetProjectionMatrix()),
4966
.cameraPosition = p_frameDescriptor.camera->GetPosition(),
@@ -70,7 +87,7 @@ void OvCore::Rendering::EngineBufferRenderFeature::OnBeforeDraw(OvRendering::Dat
7087
if (p_drawable.TryGetDescriptor<EngineDrawableDescriptor>(descriptor))
7188
{
7289
const auto modelMatrix = OvMaths::FMatrix4::Transpose(descriptor->modelMatrix);
73-
90+
7491
// Upload model matrix (First matrix in the UBO)
7592
m_engineBuffer->Upload(&modelMatrix, OvRendering::HAL::BufferMemoryRange{
7693
.offset = 0,

Sources/Overload/OvCore/src/OvCore/Rendering/ShadowRenderFeature.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,18 @@ void OvCore::Rendering::ShadowRenderFeature::OnBeforeDraw(OvRendering::Data::Pip
4141
{
4242
if (light.type == OvRendering::Settings::ELightType::DIRECTIONAL)
4343
{
44-
const auto shadowTex = light.GetShadowBuffer().GetAttachment<OvRendering::HAL::Texture>(OvRendering::Settings::EFramebufferAttachment::DEPTH);
44+
OVASSERT(light.IsSetupForShadowRendering(), "This light isn't setup for shadow rendering");
45+
46+
const auto shadowTex = light.shadowBuffer->GetAttachment<OvRendering::HAL::Texture>(
47+
OvRendering::Settings::EFramebufferAttachment::DEPTH
48+
);
4549

4650
if (!material.TrySetProperty("_ShadowMap", &shadowTex.value(), true))
4751
{
4852
OVLOG_WARNING("ShadowRenderFeature: Material does not have a _ShadowMap property");
4953
}
5054

51-
if (!material.TrySetProperty("_LightSpaceMatrix", light.GetLightSpaceMatrix(), true))
55+
if (!material.TrySetProperty("_LightSpaceMatrix", light.lightSpaceMatrix.value(), true))
5256
{
5357
OVLOG_WARNING("ShadowRenderFeature: Material does not have a _LightSpaceMatrix property");
5458
}

Sources/Overload/OvCore/src/OvCore/Rendering/ShadowRenderPass.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,17 @@ void OvCore::Rendering::ShadowRenderPass::Draw(OvRendering::Data::PipelineState
5757
{
5858
if (light.type == OvRendering::Settings::ELightType::DIRECTIONAL)
5959
{
60-
light.UpdateShadowData(frameDescriptor.camera.value());
61-
const auto& lightSpaceMatrix = light.GetLightSpaceMatrix();
62-
const auto& shadowBuffer = light.GetShadowBuffer();
63-
shadowBuffer.Bind();
60+
light.PrepareForShadowRendering(frameDescriptor);
61+
62+
engineBufferRenderFeature.SetCamera(light.shadowCamera.value());
63+
64+
light.shadowBuffer->Bind();
6465
m_renderer.SetViewport(0, 0, light.shadowMapResolution, light.shadowMapResolution);
6566
m_renderer.Clear(true, true, true);
66-
DrawShadows(pso, scene, lightSpaceMatrix);
67-
shadowBuffer.Unbind();
67+
DrawShadows(pso, scene);
68+
light.shadowBuffer->Unbind();
69+
70+
engineBufferRenderFeature.SetCamera(frameDescriptor.camera.value());
6871
}
6972
else
7073
{
@@ -84,8 +87,7 @@ void OvCore::Rendering::ShadowRenderPass::Draw(OvRendering::Data::PipelineState
8487

8588
void OvCore::Rendering::ShadowRenderPass::DrawShadows(
8689
OvRendering::Data::PipelineState p_pso,
87-
OvCore::SceneSystem::Scene& p_scene,
88-
const OvMaths::FMatrix4& p_lightSpaceMatrix
90+
OvCore::SceneSystem::Scene& p_scene
8991
)
9092
{
9193
for (auto modelRenderer : p_scene.GetFastAccessComponents().modelRenderers)
@@ -124,19 +126,19 @@ void OvCore::Rendering::ShadowRenderPass::DrawShadows(
124126
drawable.stateMask.depthTest = true; // The shadow pass should always use depth test.
125127
drawable.stateMask.colorWriting = false; // The shadow pass should never write color.
126128
drawable.stateMask.depthWriting = true; // The shadow pass should always write depth.
127-
// No front/backface culling for shadow pass.
128-
// A "two-sided" shadow pass setting could be added in the future, to change this behavior.
129+
130+
// No front/backface culling for shadow pass (aka: two-sided shadow pass).
131+
// A "two-sided" shadow pass setting could be added in the future to change this behavior.
129132
drawable.stateMask.frontfaceCulling = false;
130133
drawable.stateMask.backfaceCulling = false;
131134

132-
drawable.featureSetOverride = { shadowPassName };
135+
drawable.featureSetOverride = targetMaterial.GetFeatures() + shadowPassName;
136+
133137
drawable.AddDescriptor<EngineDrawableDescriptor>({
134138
modelMatrix,
135139
materialRenderer->GetUserMatrix()
136140
});
137141

138-
targetMaterial.SetProperty("_LightSpaceMatrix", p_lightSpaceMatrix, true);
139-
140142
m_renderer.DrawEntity(p_pso, drawable);
141143
}
142144
}

Sources/Overload/OvEditor/src/OvEditor/Rendering/DebugSceneRenderer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ class DebugActorRenderPass : public OvRendering::Core::ARenderPass
464464
pso,
465465
data.transform->GetWorldPosition(),
466466
data.transform->GetWorldRotation(),
467-
data.GetEffectRange(),
467+
data.CalculateEffectRange(),
468468
kDebugBoundsColor,
469469
1.0f
470470
);
@@ -482,7 +482,7 @@ class DebugActorRenderPass : public OvRendering::Core::ARenderPass
482482
p_ambientBoxLight.owner.transform.GetWorldPosition(),
483483
data.transform->GetWorldRotation(),
484484
{ data.constant, data.linear, data.quadratic },
485-
data.GetEffectRange(),
485+
data.CalculateEffectRange(),
486486
1.0f
487487
);
488488
}

Sources/Overload/OvEditor/src/OvEditor/Rendering/OutlineRenderFeature.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ void OvEditor::Rendering::OutlineRenderFeature::DrawModelToStencil(
178178
element.stateMask = stateMask;
179179
element.stateMask.depthTest = false;
180180
element.stateMask.colorWriting = false;
181-
element.featureSetOverride = { outlinePassName };
181+
element.featureSetOverride = targetMaterial.GetFeatures() + outlinePassName;
182+
182183
element.AddDescriptor(engineDrawableDescriptor);
183184

184185
m_renderer.DrawEntity(p_pso, element);
@@ -221,14 +222,15 @@ void OvEditor::Rendering::OutlineRenderFeature::DrawModelOutline(
221222
OvMaths::FMatrix4::Identity
222223
};
223224

224-
OvRendering::Entities::Drawable element;
225-
element.mesh = *mesh;
226-
element.material = targetMaterial;
227-
element.stateMask = stateMask;
228-
element.stateMask.depthTest = false;
229-
element.featureSetOverride = { outlinePassName };
230-
element.AddDescriptor(engineDrawableDescriptor);
225+
OvRendering::Entities::Drawable drawable;
226+
drawable.mesh = *mesh;
227+
drawable.material = targetMaterial;
228+
drawable.stateMask = stateMask;
229+
drawable.stateMask.depthTest = false;
230+
drawable.featureSetOverride = targetMaterial.GetFeatures() + outlinePassName;
231231

232-
m_renderer.DrawEntity(p_pso, element);
232+
drawable.AddDescriptor(engineDrawableDescriptor);
233+
234+
m_renderer.DrawEntity(p_pso, drawable);
233235
}
234236
}

Sources/Overload/OvEditor/src/OvEditor/Rendering/PickingRenderPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ void OvEditor::Rendering::PickingRenderPass::DrawPickableModels(
186186
drawable.stateMask = stateMask;
187187
drawable.stateMask.frontfaceCulling = false;
188188
drawable.stateMask.backfaceCulling = false;
189-
drawable.featureSetOverride = { pickingPassName };
189+
drawable.featureSetOverride = targetMaterial.GetFeatures() + pickingPassName;
190190

191191
drawable.AddDescriptor<OvCore::Rendering::EngineDrawableDescriptor>({
192192
modelMatrix
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @project: Overload
3+
* @author: Overload Tech.
4+
* @licence: MIT
5+
*/
6+
7+
#pragma once
8+
9+
#include <string>
10+
#include <unordered_set>
11+
12+
namespace OvRendering::Data
13+
{
14+
using FeatureSet = std::unordered_set<std::string>;
15+
16+
struct FeatureSetHash
17+
{
18+
size_t operator()(const FeatureSet& fs) const;
19+
};
20+
21+
struct FeatureSetEqual
22+
{
23+
bool operator()(const FeatureSet& lhs, const FeatureSet& rhs) const;
24+
};
25+
}
26+
27+
/**
28+
* Convenience operator to add a feature to a set
29+
* @param p_lhs
30+
* @param p_feature
31+
*/
32+
OvRendering::Data::FeatureSet operator+(const OvRendering::Data::FeatureSet& p_lhs, const std::string& p_feature);
33+
34+
/**
35+
* Convenience operator to remove a feature from a set
36+
* @param p_lhs
37+
* @param p_feature
38+
*/
39+
OvRendering::Data::FeatureSet operator-(const OvRendering::Data::FeatureSet& p_lhs, const std::string& p_feature);

0 commit comments

Comments
 (0)