Add **Hardware Occlusion Culling** to models, foliage, particles, terrain and local light shadows

This commit is contained in:
2026-08-28 19:53:10 +02:00
parent 48b1931546
commit 97186f1970
31 changed files with 793 additions and 50 deletions
+19 -3
View File
@@ -11,12 +11,15 @@
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/GPUBuffer.h"
#include "Engine/Graphics/GPUContext.h"
#include "Engine/Graphics/RenderBuffers.h"
#include "Engine/Graphics/RenderContext.h"
#include "Engine/Graphics/RenderTools.h"
#include "Engine/Level/Scene/Scene.h"
#include "Engine/Level/Scene/SceneRendering.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Renderer/DrawCall.h"
#include "Engine/Renderer/RenderList.h"
#include "Engine/Renderer/Culling/IOcclusionCulling.h"
#if USE_EDITOR
#include "Editor/Editor.h"
#endif
@@ -392,6 +395,17 @@ void SplineModel::Draw(RenderContextBatch& renderContextBatch)
return; // TODO: Spline Model rendering to Global SDF
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
return; // TODO: Spline Model rendering to Global Surface Atlas
auto drawState = renderContext.Buffers->GetGeometryDrawState(&GetScene()->Rendering, _sceneRenderingKey, this);
ACTOR_GET_WORLD_MATRIX(this, view, world);
DrawPass drawModes = DrawModes;
if (drawState && renderContextBatch.Buffers->OcclusionCulling && !renderContextBatch.Buffers->OcclusionCulling->IsVisible(_box, *drawState))
{
// Draw shadows-only (or cull)
drawModes &= DrawPass::Depth;
if (renderContextBatch.Contexts.Count() == 1 || drawModes == DrawPass::None)
return;
}
GEOMETRY_DRAW_STATE_EVENT_BEGIN(drawState, world);
if (!Entries.IsValidFor(model))
Entries.Setup(model);
@@ -466,16 +480,18 @@ void SplineModel::Draw(RenderContextBatch& renderContextBatch)
// Check if skip rendering
const auto shadowsMode = entry.ShadowsMode & slot.ShadowsMode;
const auto drawModes = DrawModes & material->GetDrawModes();
if (drawModes == DrawPass::None)
const auto meshDrawModes = drawModes & material->GetDrawModes();
if (meshDrawModes == DrawPass::None)
continue;
// Submit draw call
mesh->GetDrawCallGeometry(drawCall);
drawCall.Material = material;
renderContext.List->AddDrawCall(renderContextBatch, drawModes, _staticFlags, shadowsMode, instanceSphere, drawCall, entry.ReceiveDecals);
renderContext.List->AddDrawCall(renderContextBatch, meshDrawModes, _staticFlags, shadowsMode, instanceSphere, drawCall, entry.ReceiveDecals);
}
}
GEOMETRY_DRAW_STATE_EVENT_END(drawState, world);
}
bool SplineModel::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal)