Add **Hardware Occlusion Culling** to models, foliage, particles, terrain and local light shadows
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "Engine/Graphics/Models/MeshDeformation.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Renderer/Culling/IOcclusionCulling.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Level/SceneObjectsFactory.h"
|
||||
#include "Engine/Profiler/Profiler.h"
|
||||
@@ -1262,6 +1263,15 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
const Float3 translation = _transform.Translation - renderContext.View.Origin;
|
||||
Matrix::Transformation(_transform.Scale, _transform.Orientation, translation, world);
|
||||
auto drawState = renderContext.Buffers->GetGeometryDrawState(&GetScene()->Rendering, _sceneRenderingKey, this);
|
||||
SkinnedMesh::DrawInfo draw;
|
||||
draw.DrawModes = DrawModes;
|
||||
if (drawState && renderContextBatch.Buffers->OcclusionCulling && !renderContextBatch.Buffers->OcclusionCulling->IsVisible(_box, *drawState))
|
||||
{
|
||||
// Draw shadows-only (or cull)
|
||||
draw.DrawModes &= DrawPass::Depth;
|
||||
if (renderContextBatch.Contexts.Count() == 1 || draw.DrawModes == DrawPass::None)
|
||||
return;
|
||||
}
|
||||
GEOMETRY_DRAW_STATE_EVENT_BEGIN(drawState, world);
|
||||
|
||||
_lastMinDstSqr = Math::Min(_lastMinDstSqr, Vector3::DistanceSquared(_transform.Translation, renderContext.View.WorldPosition));
|
||||
@@ -1271,7 +1281,6 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
if (_bones.IsDirty)
|
||||
_bones.Flush();
|
||||
|
||||
SkinnedMesh::DrawInfo draw;
|
||||
draw.Buffer = &Entries;
|
||||
draw.SkinningBones = RenderListExtension.GlobalBuffer;
|
||||
draw.SkinningBonesOffset = _bones.GlobalBufferOffset / sizeof(Matrix3x4);
|
||||
@@ -1289,7 +1298,6 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
draw.World = &world;
|
||||
draw.DrawState = drawState;
|
||||
draw.Deformation = _deformation;
|
||||
draw.DrawModes = DrawModes;
|
||||
draw.Bounds = _sphere;
|
||||
draw.Bounds.Center -= renderContext.View.Origin;
|
||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "PointLight.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/RenderContext.h"
|
||||
@@ -123,6 +124,12 @@ void PointLight::Draw(RenderContextBatch& renderContextBatch)
|
||||
data.StaticFlags = GetStaticFlags();
|
||||
data.ID = GetID();
|
||||
data.ScreenSize = Math::Min(1.0f, Math::Sqrt(RenderTools::ComputeBoundsScreenRadiusSquared(position, (float)_sphere.Radius, renderContext.View)));
|
||||
uint32 cullingId = 0;
|
||||
if (data.CanRenderShadow(renderContext.View) && !renderContext.Buffers->TestOcclusionCulling(this, cullingId))
|
||||
{
|
||||
// Occlusion cull dynamic shadow
|
||||
data.ShadowsMode = ShadowsCastingMode::None;
|
||||
}
|
||||
renderContext.List->PointLights.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "SpotLight.h"
|
||||
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Content/Assets/IESProfile.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/RenderContext.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Level/Scene/SceneRendering.h"
|
||||
|
||||
@@ -175,6 +175,12 @@ void SpotLight::Draw(RenderContextBatch& renderContextBatch)
|
||||
data.StaticFlags = GetStaticFlags();
|
||||
data.ID = GetID();
|
||||
data.ScreenSize = Math::Min(1.0f, Math::Sqrt(RenderTools::ComputeBoundsScreenRadiusSquared(position, (float)_sphere.Radius, renderContext.View)));
|
||||
uint32 cullingId = 0;
|
||||
if (data.CanRenderShadow(renderContext.View) && !renderContext.Buffers->TestOcclusionCulling(this, cullingId))
|
||||
{
|
||||
// Occlusion cull dynamic shadow
|
||||
data.ShadowsMode = ShadowsCastingMode::None;
|
||||
}
|
||||
renderContext.List->SpotLights.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/Utils/GlobalSignDistanceFieldPass.h"
|
||||
#include "Engine/Renderer/Culling/IOcclusionCulling.h"
|
||||
#include "Engine/Renderer/GI/GlobalSurfaceAtlasPass.h"
|
||||
#include "Engine/Utilities/Encryption.h"
|
||||
#if USE_EDITOR
|
||||
@@ -386,11 +387,19 @@ void StaticModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
}
|
||||
auto drawState = renderContext.Buffers->GetGeometryDrawState(&GetScene()->Rendering, _sceneRenderingKey, this);
|
||||
ACTOR_GET_WORLD_MATRIX(this, view, world);
|
||||
Mesh::DrawInfo draw;
|
||||
draw.DrawModes = _drawModes;
|
||||
if (drawState && renderContextBatch.Buffers->OcclusionCulling && !renderContextBatch.Buffers->OcclusionCulling->IsVisible(_box, *drawState))
|
||||
{
|
||||
// Draw shadows-only (or cull)
|
||||
draw.DrawModes &= DrawPass::Depth;
|
||||
if (renderContextBatch.Contexts.Count() == 1 || draw.DrawModes == DrawPass::None)
|
||||
return;
|
||||
}
|
||||
GEOMETRY_DRAW_STATE_EVENT_BEGIN(drawState, world);
|
||||
if (_vertexColorsDirty)
|
||||
FlushVertexColors();
|
||||
|
||||
Mesh::DrawInfo draw;
|
||||
draw.Buffer = &Entries;
|
||||
draw.World = &world;
|
||||
draw.DrawState = drawState;
|
||||
@@ -398,7 +407,6 @@ void StaticModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
draw.Lightmap = _scene && Lightmap.TextureIndex != -1 ? _scene->LightmapsData.GetReadyLightmap(Lightmap.TextureIndex) : nullptr;
|
||||
draw.LightmapUVs = &Lightmap.UVsArea;
|
||||
draw.Flags = _staticFlags;
|
||||
draw.DrawModes = _drawModes;
|
||||
draw.Bounds = _sphere;
|
||||
draw.Bounds.Center -= renderContext.View.Origin;
|
||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||
|
||||
Reference in New Issue
Block a user