Add Global Surface Atlas rendering for Foliage

This commit is contained in:
Wojciech Figat
2022-08-11 11:33:41 +02:00
parent 6c9b1f6be0
commit d8c224112b
5 changed files with 113 additions and 8 deletions

View File

@@ -480,6 +480,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
const uint32 viewMask = renderContext.View.RenderLayersMask;
const Float3 viewPosition = renderContext.View.Position;
const float minObjectRadius = 20.0f; // Skip too small objects
_cullingPosDistance = Vector4(viewPosition, distance);
for (auto* scene : renderContext.List->Scenes)
{
for (auto& e : scene->Actors)
@@ -582,8 +583,9 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
// Fake projection matrix to disable Screen Size culling based on RenderTools::ComputeBoundsScreenRadiusSquared
renderContextTiles.View.Projection.Values[0][0] = 10000.0f;
// Collect draw calls for the object
_currentActorObject = actorObject;
object.Actor->Draw(renderContextTiles);
// Render all tiles into the atlas
@@ -1154,12 +1156,12 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex
}
}
void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, const BoundingSphere& actorObjectBounds, const Transform& localToWorld, const BoundingBox& localBounds, uint32 tilesMask, bool useVisibility)
void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, const BoundingSphere& actorObjectBounds, const Transform& localToWorld, const BoundingBox& localBounds, uint32 tilesMask, bool useVisibility, float qualityScale)
{
GlobalSurfaceAtlasCustomBuffer& surfaceAtlasData = *_surfaceAtlasData;
Float3 boundsSize = localBounds.GetSize() * actor->GetScale();
const float distanceScale = Math::Lerp(1.0f, surfaceAtlasData.DistanceScaling, Math::InverseLerp(surfaceAtlasData.DistanceScalingStart, surfaceAtlasData.DistanceScalingEnd, (float)CollisionsHelper::DistanceSpherePoint(actorObjectBounds, surfaceAtlasData.ViewPosition)));
const float tilesScale = surfaceAtlasData.TileTexelsPerWorldUnit * distanceScale;
const float tilesScale = surfaceAtlasData.TileTexelsPerWorldUnit * distanceScale * qualityScale;
GlobalSurfaceAtlasObject* object = surfaceAtlasData.Objects.TryGet(actorObject);
bool anyTile = false, dirty = false;
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)

View File

@@ -61,6 +61,8 @@ private:
class GlobalSurfaceAtlasCustomBuffer* _surfaceAtlasData;
Array<void*> _dirtyObjectsBuffer;
uint64 _culledObjectsSizeFrames[8];
Vector4 _cullingPosDistance;
void* _currentActorObject;
public:
/// <summary>
@@ -80,8 +82,20 @@ public:
/// <param name="output">The output buffer.</param>
void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output);
// Gets the culling view position (xyz) and view distance (w)
void GetCullingData(Vector4& cullingPosDistance) const
{
cullingPosDistance = _cullingPosDistance;
}
// Gets the current object of the actor that is drawn into atlas.
void* GetCurrentActorObject() const
{
return _currentActorObject;
}
// Rasterize actor into the Global Surface Atlas. Call it from actor Draw() method during DrawPass::GlobalSurfaceAtlas.
void RasterizeActor(Actor* actor, void* actorObject, const BoundingSphere& actorObjectBounds, const Transform& localToWorld, const BoundingBox& localBounds, uint32 tilesMask = MAX_uint32, bool useVisibility = true);
void RasterizeActor(Actor* actor, void* actorObject, const BoundingSphere& actorObjectBounds, const Transform& localToWorld, const BoundingBox& localBounds, uint32 tilesMask = MAX_uint32, bool useVisibility = true, float qualityScale = 1.0f);
private:
#if COMPILE_WITH_DEV_ENV

View File

@@ -76,7 +76,7 @@ public:
/// <param name="output">The output buffer.</param>
void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output);
void GetCullingBounds(BoundingBox& bounds) const
void GetCullingData(BoundingBox& bounds) const
{
bounds = _cascadeCullingBounds;
}