|
|
|
|
@@ -6,14 +6,13 @@
|
|
|
|
|
#include "Engine/Core/Log.h"
|
|
|
|
|
#include "Engine/Core/Random.h"
|
|
|
|
|
#include "Engine/Engine/Engine.h"
|
|
|
|
|
#include "Engine/Graphics/Graphics.h"
|
|
|
|
|
#include "Engine/Graphics/RenderTask.h"
|
|
|
|
|
#include "Engine/Graphics/RenderTools.h"
|
|
|
|
|
#include "Engine/Graphics/GPUDevice.h"
|
|
|
|
|
#include "Engine/Content/Deprecated.h"
|
|
|
|
|
#if !FOLIAGE_USE_SINGLE_QUAD_TREE
|
|
|
|
|
#include "Engine/Threading/JobSystem.h"
|
|
|
|
|
#if FOLIAGE_USE_DRAW_CALLS_BATCHING
|
|
|
|
|
#include "Engine/Graphics/RenderTools.h"
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
#include "Engine/Level/SceneQuery.h"
|
|
|
|
|
#include "Engine/Profiler/ProfilerCPU.h"
|
|
|
|
|
@@ -125,7 +124,7 @@ void Foliage::AddToCluster(ChunkedArray<FoliageCluster, FOLIAGE_CLUSTER_CHUNKS_S
|
|
|
|
|
|
|
|
|
|
#if !FOLIAGE_USE_SINGLE_QUAD_TREE && FOLIAGE_USE_DRAW_CALLS_BATCHING
|
|
|
|
|
|
|
|
|
|
void Foliage::DrawInstance(RenderContext& renderContext, FoliageInstance& instance, const FoliageType& type, Model* model, int32 lod, float lodDitherFactor, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const
|
|
|
|
|
void Foliage::DrawInstance(DrawContext& context, FoliageInstance& instance, Model* model, int32 lod, float lodDitherFactor, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const
|
|
|
|
|
{
|
|
|
|
|
const auto& meshes = model->LODs.Get()[lod].Meshes;
|
|
|
|
|
for (int32 meshIndex = 0; meshIndex < meshes.Count(); meshIndex++)
|
|
|
|
|
@@ -141,7 +140,7 @@ void Foliage::DrawInstance(RenderContext& renderContext, FoliageInstance& instan
|
|
|
|
|
auto* e = result.TryGet(key);
|
|
|
|
|
if (!e)
|
|
|
|
|
{
|
|
|
|
|
e = &result.Add(key, BatchedDrawCall(renderContext.List))->Value;
|
|
|
|
|
e = &result.Add(key, BatchedDrawCall(context.RenderContext.List))->Value;
|
|
|
|
|
ASSERT_LOW_LAYER(key.Mat);
|
|
|
|
|
e->DrawCall.Material = key.Mat;
|
|
|
|
|
e->DrawCall.Surface.Lightmap = EnumHasAnyFlags(_staticFlags, StaticFlags::Lightmap) && _scene ? _scene->LightmapsData.GetReadyLightmap(key.Lightmap) : nullptr;
|
|
|
|
|
@@ -152,21 +151,18 @@ void Foliage::DrawInstance(RenderContext& renderContext, FoliageInstance& instan
|
|
|
|
|
auto& instanceData = e->Instances.AddOne();
|
|
|
|
|
Matrix world;
|
|
|
|
|
const Transform transform = _transform.LocalToWorld(instance.Transform);
|
|
|
|
|
const Float3 translation = transform.Translation - renderContext.View.Origin;
|
|
|
|
|
const Float3 translation = transform.Translation - context.ViewOrigin;
|
|
|
|
|
Matrix::Transformation(transform.Scale, transform.Orientation, translation, world);
|
|
|
|
|
constexpr float worldDeterminantSign = 1.0f;
|
|
|
|
|
instanceData.Store(world, world, instance.Lightmap.UVsArea, drawCall.Surface.GeometrySize, instance.Random, worldDeterminantSign, lodDitherFactor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster, const FoliageType& type, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const
|
|
|
|
|
void Foliage::DrawCluster(DrawContext& context, FoliageCluster* cluster, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const
|
|
|
|
|
{
|
|
|
|
|
// Skip clusters that around too far from view
|
|
|
|
|
const auto lodView = (renderContext.LodProxyView ? renderContext.LodProxyView : &renderContext.View);
|
|
|
|
|
if (Float3::Distance(lodView->Position, cluster->TotalBoundsSphere.Center - lodView->Origin) - (float)cluster->TotalBoundsSphere.Radius > cluster->MaxCullDistance)
|
|
|
|
|
if (Float3::Distance(context.LodView.Position, cluster->TotalBoundsSphere.Center - context.LodView.Origin) - (float)cluster->TotalBoundsSphere.Radius > cluster->MaxCullDistance)
|
|
|
|
|
return;
|
|
|
|
|
const Vector3 viewOrigin = renderContext.View.Origin;
|
|
|
|
|
|
|
|
|
|
//DebugDraw::DrawBox(cluster->Bounds, Color::Red);
|
|
|
|
|
|
|
|
|
|
// Draw visible children
|
|
|
|
|
@@ -178,10 +174,10 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
BoundingBox box;
|
|
|
|
|
#define DRAW_CLUSTER(idx) \
|
|
|
|
|
box = cluster->Children[idx]->TotalBounds; \
|
|
|
|
|
box.Minimum -= viewOrigin; \
|
|
|
|
|
box.Maximum -= viewOrigin; \
|
|
|
|
|
if (renderContext.View.CullingFrustum.Intersects(box)) \
|
|
|
|
|
DrawCluster(renderContext, cluster->Children[idx], type, drawCallsLists, result)
|
|
|
|
|
box.Minimum -= context.ViewOrigin; \
|
|
|
|
|
box.Maximum -= context.ViewOrigin; \
|
|
|
|
|
if (context.RenderContext.View.CullingFrustum.Intersects(box)) \
|
|
|
|
|
DrawCluster(context, cluster->Children[idx], drawCallsLists, result)
|
|
|
|
|
DRAW_CLUSTER(0);
|
|
|
|
|
DRAW_CLUSTER(1);
|
|
|
|
|
DRAW_CLUSTER(2);
|
|
|
|
|
@@ -192,21 +188,22 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
{
|
|
|
|
|
// Draw visible instances
|
|
|
|
|
const auto frame = Engine::FrameCount;
|
|
|
|
|
const auto model = type.Model.Get();
|
|
|
|
|
const auto transitionLOD = renderContext.View.Pass != DrawPass::Depth; // Let the main view pass update LOD transitions
|
|
|
|
|
const auto model = context.FoliageType.Model.Get();
|
|
|
|
|
const auto transitionLOD = context.RenderContext.View.Pass != DrawPass::Depth; // Let the main view pass update LOD transitions
|
|
|
|
|
// TODO: move DrawState to be stored per-view (so shadows can fade objects on their own)
|
|
|
|
|
for (int32 i = 0; i < cluster->Instances.Count(); i++)
|
|
|
|
|
{
|
|
|
|
|
auto& instance = *cluster->Instances.Get()[i];
|
|
|
|
|
BoundingSphere sphere = instance.Bounds;
|
|
|
|
|
sphere.Center -= viewOrigin;
|
|
|
|
|
if (Float3::Distance(lodView->Position, sphere.Center) - (float)sphere.Radius < instance.CullDistance &&
|
|
|
|
|
renderContext.View.CullingFrustum.Intersects(sphere))
|
|
|
|
|
sphere.Center -= context.ViewOrigin;
|
|
|
|
|
if (Float3::Distance(context.LodView.Position, sphere.Center) - (float)sphere.Radius < instance.CullDistance &&
|
|
|
|
|
context.RenderContext.View.CullingFrustum.Intersects(sphere) &&
|
|
|
|
|
RenderTools::ComputeBoundsScreenRadiusSquared(sphere.Center, sphere.Radius, context.RenderContext.View) * context.ViewScreenSizeSq >= context.MinObjectPixelSizeSq)
|
|
|
|
|
{
|
|
|
|
|
const auto modelFrame = instance.DrawState.PrevFrame + 1;
|
|
|
|
|
|
|
|
|
|
// Select a proper LOD index (model may be culled)
|
|
|
|
|
int32 lodIndex = RenderTools::ComputeModelLOD(model, sphere.Center, (float)sphere.Radius, renderContext);
|
|
|
|
|
int32 lodIndex = RenderTools::ComputeModelLOD(model, sphere.Center, (float)sphere.Radius, context.RenderContext);
|
|
|
|
|
if (lodIndex == -1)
|
|
|
|
|
{
|
|
|
|
|
// Handling model fade-out transition
|
|
|
|
|
@@ -231,20 +228,20 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
{
|
|
|
|
|
const auto prevLOD = model->ClampLODIndex(instance.DrawState.PrevLOD);
|
|
|
|
|
const float normalizedProgress = static_cast<float>(instance.DrawState.LODTransition) * (1.0f / 255.0f);
|
|
|
|
|
DrawInstance(renderContext, instance, type, model, prevLOD, normalizedProgress, drawCallsLists, result);
|
|
|
|
|
DrawInstance(context, instance, model, prevLOD, normalizedProgress, drawCallsLists, result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (instance.DrawState.LODTransition < 255)
|
|
|
|
|
{
|
|
|
|
|
const auto prevLOD = model->ClampLODIndex(instance.DrawState.PrevLOD);
|
|
|
|
|
const float normalizedProgress = static_cast<float>(instance.DrawState.LODTransition) * (1.0f / 255.0f);
|
|
|
|
|
DrawInstance(renderContext, instance, type, model, prevLOD, normalizedProgress, drawCallsLists, result);
|
|
|
|
|
DrawInstance(context, instance, model, prevLOD, normalizedProgress, drawCallsLists, result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
instance.DrawState.PrevFrame = frame;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
lodIndex += renderContext.View.ModelLODBias;
|
|
|
|
|
lodIndex += context.RenderContext.View.ModelLODBias;
|
|
|
|
|
lodIndex = model->ClampLODIndex(lodIndex);
|
|
|
|
|
|
|
|
|
|
if (transitionLOD)
|
|
|
|
|
@@ -278,19 +275,19 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
// Draw
|
|
|
|
|
if (instance.DrawState.PrevLOD == lodIndex)
|
|
|
|
|
{
|
|
|
|
|
DrawInstance(renderContext, instance, type, model, lodIndex, 0.0f, drawCallsLists, result);
|
|
|
|
|
DrawInstance(context, instance, model, lodIndex, 0.0f, drawCallsLists, result);
|
|
|
|
|
}
|
|
|
|
|
else if (instance.DrawState.PrevLOD == -1)
|
|
|
|
|
{
|
|
|
|
|
const float normalizedProgress = static_cast<float>(instance.DrawState.LODTransition) * (1.0f / 255.0f);
|
|
|
|
|
DrawInstance(renderContext, instance, type, model, lodIndex, 1.0f - normalizedProgress, drawCallsLists, result);
|
|
|
|
|
DrawInstance(context, instance, model, lodIndex, 1.0f - normalizedProgress, drawCallsLists, result);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const auto prevLOD = model->ClampLODIndex(instance.DrawState.PrevLOD);
|
|
|
|
|
const float normalizedProgress = static_cast<float>(instance.DrawState.LODTransition) * (1.0f / 255.0f);
|
|
|
|
|
DrawInstance(renderContext, instance, type, model, prevLOD, normalizedProgress, drawCallsLists, result);
|
|
|
|
|
DrawInstance(renderContext, instance, type, model, lodIndex, normalizedProgress - 1.0f, drawCallsLists, result);
|
|
|
|
|
DrawInstance(context, instance, model, prevLOD, normalizedProgress, drawCallsLists, result);
|
|
|
|
|
DrawInstance(context, instance, model, lodIndex, normalizedProgress - 1.0f, drawCallsLists, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//DebugDraw::DrawSphere(instance.Bounds, Color::YellowGreen);
|
|
|
|
|
@@ -304,14 +301,11 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster, Mesh::DrawInfo& draw)
|
|
|
|
|
void Foliage::DrawCluster(DrawContext& context, FoliageCluster* cluster, Mesh::DrawInfo& draw)
|
|
|
|
|
{
|
|
|
|
|
// Skip clusters that around too far from view
|
|
|
|
|
const auto lodView = (renderContext.LodProxyView ? renderContext.LodProxyView : &renderContext.View);
|
|
|
|
|
if (Float3::Distance(lodView->Position, cluster->TotalBoundsSphere.Center - lodView->Origin) - (float)cluster->TotalBoundsSphere.Radius > cluster->MaxCullDistance)
|
|
|
|
|
if (Float3::Distance(context.LodView.Position, cluster->TotalBoundsSphere.Center - context.LodView.Origin) - (float)cluster->TotalBoundsSphere.Radius > cluster->MaxCullDistance)
|
|
|
|
|
return;
|
|
|
|
|
const Vector3 viewOrigin = renderContext.View.Origin;
|
|
|
|
|
|
|
|
|
|
//DebugDraw::DrawBox(cluster->Bounds, Color::Red);
|
|
|
|
|
|
|
|
|
|
// Draw visible children
|
|
|
|
|
@@ -323,10 +317,10 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
BoundingBox box;
|
|
|
|
|
#define DRAW_CLUSTER(idx) \
|
|
|
|
|
box = cluster->Children[idx]->TotalBounds; \
|
|
|
|
|
box.Minimum -= viewOrigin; \
|
|
|
|
|
box.Maximum -= viewOrigin; \
|
|
|
|
|
if (renderContext.View.CullingFrustum.Intersects(box)) \
|
|
|
|
|
DrawCluster(renderContext, cluster->Children[idx], draw)
|
|
|
|
|
box.Minimum -= context.ViewOrigin; \
|
|
|
|
|
box.Maximum -= context.ViewOrigin; \
|
|
|
|
|
if (context.RenderContext.View.CullingFrustum.Intersects(box)) \
|
|
|
|
|
DrawCluster(context, cluster->Children[idx], draw)
|
|
|
|
|
DRAW_CLUSTER(0);
|
|
|
|
|
DRAW_CLUSTER(1);
|
|
|
|
|
DRAW_CLUSTER(2);
|
|
|
|
|
@@ -342,16 +336,17 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
auto& instance = *cluster->Instances[i];
|
|
|
|
|
auto& type = FoliageTypes[instance.Type];
|
|
|
|
|
BoundingSphere sphere = instance.Bounds;
|
|
|
|
|
sphere.Center -= viewOrigin;
|
|
|
|
|
sphere.Center -= context.ViewOrigin;
|
|
|
|
|
|
|
|
|
|
// Check if can draw this instance
|
|
|
|
|
if (type._canDraw &&
|
|
|
|
|
Float3::Distance(lodView->Position, sphere.Center) - (float)sphere.Radius < instance.CullDistance &&
|
|
|
|
|
renderContext.View.CullingFrustum.Intersects(sphere))
|
|
|
|
|
Float3::Distance(context.LodView.Position, sphere.Center) - (float)sphere.Radius < instance.CullDistance &&
|
|
|
|
|
context.RenderContext.View.CullingFrustum.Intersects(sphere) &&
|
|
|
|
|
RenderTools::ComputeBoundsScreenRadiusSquared(sphere.Center, sphere.Radius, context.RenderContext.View) * context.ViewScreenSizeSq >= context.MinObjectPixelSizeSq)
|
|
|
|
|
{
|
|
|
|
|
Matrix world;
|
|
|
|
|
const Transform transform = _transform.LocalToWorld(instance.Transform);
|
|
|
|
|
const Float3 translation = transform.Translation - renderContext.View.Origin;
|
|
|
|
|
const Float3 translation = transform.Translation - context.ViewOrigin;
|
|
|
|
|
Matrix::Transformation(transform.Scale, transform.Orientation, translation, world);
|
|
|
|
|
|
|
|
|
|
// Disable motion blur
|
|
|
|
|
@@ -367,7 +362,7 @@ void Foliage::DrawCluster(RenderContext& renderContext, FoliageCluster* cluster,
|
|
|
|
|
draw.PerInstanceRandom = instance.Random;
|
|
|
|
|
draw.DrawModes = type.DrawModes;
|
|
|
|
|
draw.SetStencilValue(_layer);
|
|
|
|
|
type.Model->Draw(renderContext, draw);
|
|
|
|
|
type.Model->Draw(context.RenderContext, draw);
|
|
|
|
|
|
|
|
|
|
//DebugDraw::DrawSphere(instance.Bounds, Color::YellowGreen);
|
|
|
|
|
|
|
|
|
|
@@ -446,22 +441,50 @@ void Foliage::DrawFoliageJob(int32 i)
|
|
|
|
|
PROFILE_CPU();
|
|
|
|
|
PROFILE_MEM(Graphics);
|
|
|
|
|
const FoliageType& type = FoliageTypes[i];
|
|
|
|
|
if (type.IsReady() && type.Model->CanBeRendered())
|
|
|
|
|
if (type._canDraw)
|
|
|
|
|
{
|
|
|
|
|
DrawCallsList drawCallsLists[MODEL_MAX_LODS];
|
|
|
|
|
for (RenderContext& renderContext : _renderContextBatch->Contexts)
|
|
|
|
|
{
|
|
|
|
|
#if !FOLIAGE_USE_SINGLE_QUAD_TREE && FOLIAGE_USE_DRAW_CALLS_BATCHING
|
|
|
|
|
DrawType(renderContext, type, drawCallsLists);
|
|
|
|
|
#else
|
|
|
|
|
Mesh::DrawInfo draw;
|
|
|
|
|
draw.Flags = GetStaticFlags();
|
|
|
|
|
draw.DrawModes = (DrawPass)(DrawPass::Default & renderContext.View.Pass);
|
|
|
|
|
draw.LODBias = 0;
|
|
|
|
|
draw.ForcedLOD = -1;
|
|
|
|
|
draw.VertexColors = nullptr;
|
|
|
|
|
draw.Deformation = nullptr;
|
|
|
|
|
DrawType(renderContext, type, draw);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !FOLIAGE_USE_SINGLE_QUAD_TREE && FOLIAGE_USE_DRAW_CALLS_BATCHING
|
|
|
|
|
void Foliage::DrawType(RenderContext& renderContext, const FoliageType& type, DrawCallsList* drawCallsLists)
|
|
|
|
|
#else
|
|
|
|
|
void Foliage::DrawType(RenderContext& renderContext, const FoliageType& type, Mesh::DrawInfo& draw)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if (!type.Root || !FOLIAGE_CAN_DRAW(renderContext, type))
|
|
|
|
|
return;
|
|
|
|
|
const DrawPass typeDrawModes = FOLIAGE_GET_DRAW_MODES(renderContext, type);
|
|
|
|
|
PROFILE_CPU_ASSET(type.Model);
|
|
|
|
|
DrawContext context
|
|
|
|
|
{
|
|
|
|
|
renderContext,
|
|
|
|
|
renderContext.LodProxyView ? *renderContext.LodProxyView : renderContext.View,
|
|
|
|
|
type,
|
|
|
|
|
renderContext.View.Origin,
|
|
|
|
|
Math::Square(Graphics::Shadows::MinObjectPixelSize),
|
|
|
|
|
renderContext.View.ScreenSize.X * renderContext.View.ScreenSize.Y,
|
|
|
|
|
};
|
|
|
|
|
if (context.RenderContext.View.Pass != DrawPass::Depth)
|
|
|
|
|
context.MinObjectPixelSizeSq = 0.0f; // Don't use it in main view
|
|
|
|
|
#if FOLIAGE_USE_DRAW_CALLS_BATCHING
|
|
|
|
|
// Initialize draw calls for foliage type all LODs meshes
|
|
|
|
|
for (int32 lod = 0; lod < type.Model->LODs.Count(); lod++)
|
|
|
|
|
@@ -506,7 +529,7 @@ void Foliage::DrawType(RenderContext& renderContext, const FoliageType& type, Dr
|
|
|
|
|
|
|
|
|
|
// Draw instances of the foliage type
|
|
|
|
|
BatchedDrawCalls result(&renderContext.List->Memory);
|
|
|
|
|
DrawCluster(renderContext, type.Root, type, drawCallsLists, result);
|
|
|
|
|
DrawCluster(context, type.Root, drawCallsLists, result);
|
|
|
|
|
|
|
|
|
|
// Submit draw calls with valid instances added
|
|
|
|
|
for (auto& e : result)
|
|
|
|
|
@@ -568,10 +591,22 @@ void Foliage::DrawType(RenderContext& renderContext, const FoliageType& type, Dr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
DrawCluster(renderContext, type.Root, draw);
|
|
|
|
|
DrawCluster(context, type.Root, draw);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Foliage::InitType(const RenderView& view, FoliageType& type)
|
|
|
|
|
{
|
|
|
|
|
const DrawPass drawModes = type.DrawModes & view.Pass & view.GetShadowsDrawPassMask(type.ShadowsMode);
|
|
|
|
|
type._canDraw = type.IsReady() && drawModes != DrawPass::None && type.Model && type.Model->CanBeRendered();
|
|
|
|
|
for (int32 j = 0; j < type.Entries.Count(); j++)
|
|
|
|
|
{
|
|
|
|
|
auto& e = type.Entries[j];
|
|
|
|
|
e.ReceiveDecals = type.ReceiveDecals != 0;
|
|
|
|
|
e.ShadowsMode = type.ShadowsMode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32 Foliage::GetInstancesCount() const
|
|
|
|
|
{
|
|
|
|
|
return Instances.Count();
|
|
|
|
|
@@ -1131,12 +1166,7 @@ void Foliage::Draw(RenderContext& renderContext)
|
|
|
|
|
// Cache data per foliage instance type
|
|
|
|
|
for (auto& type : FoliageTypes)
|
|
|
|
|
{
|
|
|
|
|
for (int32 j = 0; j < type.Entries.Count(); j++)
|
|
|
|
|
{
|
|
|
|
|
auto& e = type.Entries[j];
|
|
|
|
|
e.ReceiveDecals = type.ReceiveDecals != 0;
|
|
|
|
|
e.ShadowsMode = type.ShadowsMode;
|
|
|
|
|
}
|
|
|
|
|
InitType(renderContext.View, type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (renderContext.View.Pass == DrawPass::GlobalSDF)
|
|
|
|
|
@@ -1202,12 +1232,7 @@ void Foliage::Draw(RenderContext& renderContext)
|
|
|
|
|
// Draw single foliage instance projection into Global Surface Atlas
|
|
|
|
|
auto& instance = *(FoliageInstance*)GlobalSurfaceAtlasPass::Instance()->GetCurrentActorObject();
|
|
|
|
|
auto& type = FoliageTypes[instance.Type];
|
|
|
|
|
for (int32 i = 0; i < type.Entries.Count(); i++)
|
|
|
|
|
{
|
|
|
|
|
auto& e = type.Entries[i];
|
|
|
|
|
e.ReceiveDecals = type.ReceiveDecals != 0;
|
|
|
|
|
e.ShadowsMode = type.ShadowsMode;
|
|
|
|
|
}
|
|
|
|
|
InitType(renderContext.View, type);
|
|
|
|
|
Matrix world;
|
|
|
|
|
const Transform transform = _transform.LocalToWorld(instance.Transform);
|
|
|
|
|
renderContext.View.GetWorldMatrix(transform, world);
|
|
|
|
|
@@ -1239,8 +1264,9 @@ void Foliage::Draw(RenderContext& renderContext)
|
|
|
|
|
draw.LODBias = 0;
|
|
|
|
|
draw.ForcedLOD = -1;
|
|
|
|
|
draw.VertexColors = nullptr;
|
|
|
|
|
draw.Deformation = nullptr;
|
|
|
|
|
#else
|
|
|
|
|
DrawCallsList drawCallsLists[MODEL_MAX_LODS];
|
|
|
|
|
DrawCallsList draw[MODEL_MAX_LODS];
|
|
|
|
|
#endif
|
|
|
|
|
#if FOLIAGE_USE_SINGLE_QUAD_TREE
|
|
|
|
|
if (Root)
|
|
|
|
|
@@ -1248,7 +1274,7 @@ void Foliage::Draw(RenderContext& renderContext)
|
|
|
|
|
#else
|
|
|
|
|
for (auto& type : FoliageTypes)
|
|
|
|
|
{
|
|
|
|
|
DrawType(renderContext, type, drawCallsLists);
|
|
|
|
|
DrawType(renderContext, type, draw);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -1265,14 +1291,7 @@ void Foliage::Draw(RenderContextBatch& renderContextBatch)
|
|
|
|
|
{
|
|
|
|
|
// Cache data per foliage instance type
|
|
|
|
|
for (FoliageType& type : FoliageTypes)
|
|
|
|
|
{
|
|
|
|
|
for (int32 j = 0; j < type.Entries.Count(); j++)
|
|
|
|
|
{
|
|
|
|
|
auto& e = type.Entries[j];
|
|
|
|
|
e.ReceiveDecals = type.ReceiveDecals != 0;
|
|
|
|
|
e.ShadowsMode = type.ShadowsMode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InitType(view, type);
|
|
|
|
|
|
|
|
|
|
// Run async job for each foliage type
|
|
|
|
|
_renderContextBatch = &renderContextBatch;
|
|
|
|
|
|