Fix terrain rendering to use the same LOD for main view and shadow passes
#2555 #2256
This commit is contained in:
@@ -291,7 +291,7 @@ void Terrain::SetPhysicalMaterials(const Array<JsonAssetReference<PhysicalMateri
|
||||
_physicalMaterials = value;
|
||||
_physicalMaterials.Resize(8);
|
||||
JsonAsset* materials[8];
|
||||
for (int32 i = 0;i<8;i++)
|
||||
for (int32 i = 0; i < 8; i++)
|
||||
materials[i] = _physicalMaterials[i];
|
||||
for (int32 pathIndex = 0; pathIndex < _patches.Count(); pathIndex++)
|
||||
{
|
||||
@@ -509,16 +509,39 @@ void Terrain::RemovePatch(const Int2& patchCoord)
|
||||
|
||||
#endif
|
||||
|
||||
void Terrain::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
if (DrawSetup(renderContextBatch.GetMainContext()))
|
||||
return;
|
||||
HashSet<TerrainChunk*, RendererAllocation> drawnChunks;
|
||||
for (RenderContext& renderContext : renderContextBatch.Contexts)
|
||||
{
|
||||
const DrawPass drawModes = DrawModes & renderContext.View.Pass;
|
||||
if (drawModes == DrawPass::None)
|
||||
continue;
|
||||
DrawImpl(renderContext, drawnChunks);
|
||||
}
|
||||
}
|
||||
|
||||
void Terrain::Draw(RenderContext& renderContext)
|
||||
{
|
||||
const DrawPass drawModes = DrawModes & renderContext.View.Pass;
|
||||
if (drawModes == DrawPass::None)
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF)
|
||||
if (DrawSetup(renderContext))
|
||||
return;
|
||||
HashSet<TerrainChunk*, RendererAllocation> drawnChunks;
|
||||
DrawImpl(renderContext, drawnChunks);
|
||||
}
|
||||
|
||||
bool Terrain::DrawSetup(RenderContext& renderContext)
|
||||
{
|
||||
// Special drawing modes
|
||||
const DrawPass drawModes = DrawModes & renderContext.View.Pass;
|
||||
if (drawModes == DrawPass::GlobalSDF)
|
||||
{
|
||||
if ((DrawModes & DrawPass::GlobalSDF) == DrawPass::None)
|
||||
return;
|
||||
const float chunkSize = TERRAIN_UNITS_PER_VERTEX * (float)_chunkSize;
|
||||
const float posToUV = 0.25f / chunkSize;
|
||||
Float4 localToUV(posToUV, posToUV, 0.0f, 0.0f);
|
||||
@@ -533,12 +556,10 @@ void Terrain::Draw(RenderContext& renderContext)
|
||||
patchTransform = _transform.LocalToWorld(patchTransform);
|
||||
GlobalSignDistanceFieldPass::Instance()->RasterizeHeightfield(this, patch->Heightmap->GetTexture(), patchTransform, patch->_bounds, localToUV);
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
if (drawModes == DrawPass::GlobalSurfaceAtlas)
|
||||
{
|
||||
if ((DrawModes & DrawPass::GlobalSurfaceAtlas) == DrawPass::None)
|
||||
return;
|
||||
for (TerrainPatch* patch : _patches)
|
||||
{
|
||||
if (!patch->Heightmap)
|
||||
@@ -556,11 +577,27 @@ void Terrain::Draw(RenderContext& renderContext)
|
||||
GlobalSurfaceAtlasPass::Instance()->RasterizeActor(this, chunk, chunkSphere, chunk->GetTransform(), localBounds, 1 << 2, false);
|
||||
}
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reset cached LOD for chunks (prevent LOD transition from invisible chunks)
|
||||
for (int32 patchIndex = 0; patchIndex < _patches.Count(); patchIndex++)
|
||||
{
|
||||
const auto patch = _patches[patchIndex];
|
||||
for (int32 chunkIndex = 0; chunkIndex < Terrain::ChunksCount; chunkIndex++)
|
||||
{
|
||||
auto chunk = &patch->Chunks[chunkIndex];
|
||||
chunk->_cachedDrawLOD = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Terrain::DrawImpl(RenderContext& renderContext, HashSet<TerrainChunk*, RendererAllocation>& drawnChunks)
|
||||
{
|
||||
// Collect chunks to render and calculate LOD/material for them (required to be done before to gather NeighborLOD)
|
||||
_drawChunks.Clear();
|
||||
Array<TerrainChunk*, RendererAllocation> drawChunks;
|
||||
|
||||
// Frustum vs Box culling for patches
|
||||
const BoundingFrustum frustum = renderContext.View.CullingFrustum;
|
||||
@@ -579,33 +616,24 @@ void Terrain::Draw(RenderContext& renderContext)
|
||||
for (int32 chunkIndex = 0; chunkIndex < Terrain::ChunksCount; chunkIndex++)
|
||||
{
|
||||
auto chunk = &patch->Chunks[chunkIndex];
|
||||
chunk->_cachedDrawLOD = 0;
|
||||
bounds = BoundingBox(chunk->_bounds.Minimum - origin, chunk->_bounds.Maximum - origin);
|
||||
if (renderContext.View.IsCullingDisabled || frustum.Intersects(bounds))
|
||||
{
|
||||
if (chunk->PrepareDraw(renderContext))
|
||||
{
|
||||
// Add chunk for drawing
|
||||
_drawChunks.Add(chunk);
|
||||
}
|
||||
if (!drawnChunks.Contains(chunk) && !chunk->PrepareDraw(renderContext))
|
||||
continue;
|
||||
|
||||
// Add chunk for drawing
|
||||
drawChunks.Add(chunk);
|
||||
drawnChunks.Add(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset cached LOD for chunks (prevent LOD transition from invisible chunks)
|
||||
for (int32 chunkIndex = 0; chunkIndex < Terrain::ChunksCount; chunkIndex++)
|
||||
{
|
||||
auto chunk = &patch->Chunks[chunkIndex];
|
||||
chunk->_cachedDrawLOD = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw all visible chunks
|
||||
for (int32 i = 0; i < _drawChunks.Count(); i++)
|
||||
for (int32 i = 0; i < drawChunks.Count(); i++)
|
||||
{
|
||||
_drawChunks.Get()[i]->Draw(renderContext);
|
||||
drawChunks.Get()[i]->Draw(renderContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,6 @@ private:
|
||||
Vector3 _boundsExtent;
|
||||
Float3 _cachedScale;
|
||||
Array<TerrainPatch*, InlinedAllocation<64>> _patches;
|
||||
Array<TerrainChunk*> _drawChunks;
|
||||
Array<JsonAssetReference<PhysicalMaterial>, FixedAllocation<8>> _physicalMaterials;
|
||||
|
||||
public:
|
||||
@@ -424,9 +423,12 @@ private:
|
||||
#if TERRAIN_USE_PHYSICS_DEBUG
|
||||
void DrawPhysicsDebug(RenderView& view);
|
||||
#endif
|
||||
bool DrawSetup(RenderContext& renderContext);
|
||||
void DrawImpl(RenderContext& renderContext, HashSet<TerrainChunk*, class RendererAllocation>& drawnChunks);
|
||||
|
||||
public:
|
||||
// [PhysicsColliderActor]
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
|
||||
@@ -34,9 +34,9 @@ private:
|
||||
float _perInstanceRandom;
|
||||
float _yOffset, _yHeight;
|
||||
|
||||
TerrainChunk* _neighbors[4];
|
||||
byte _cachedDrawLOD;
|
||||
IMaterial* _cachedDrawMaterial;
|
||||
TerrainChunk* _neighbors[4] = {};
|
||||
byte _cachedDrawLOD = 0;
|
||||
IMaterial* _cachedDrawMaterial = nullptr;
|
||||
|
||||
void Init(TerrainPatch* patch, uint16 x, uint16 z);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user