Various fixes and improvements for large worlds rendering

This commit is contained in:
Wojtek Figat
2022-06-28 20:26:01 +02:00
parent b1640515c4
commit 27d266546e
18 changed files with 80 additions and 70 deletions

Binary file not shown.

BIN
Content/Shaders/Sky.flax (Stored with Git LFS)

Binary file not shown.

View File

@@ -19,6 +19,8 @@
PACK_STRUCT(struct Data {
Matrix WVP;
Float3 ViewOffset;
float Padding;
GBufferData GBuffer;
AtmosphericFogData Fog;
});
@@ -178,6 +180,7 @@ void Sky::DrawFog(GPUContext* context, RenderContext& renderContext, GPUTextureV
// Setup constants data
Data data;
GBufferPass::SetInputs(renderContext.View, data.GBuffer);
data.ViewOffset = renderContext.View.Origin + GetPosition();
InitConfig(data.Fog);
data.Fog.AtmosphericFogSunPower *= SunLight ? SunLight->Brightness : 1.0f;
bool useSpecularLight = (renderContext.View.Flags & ViewFlags::SpecularLight) != 0;
@@ -216,6 +219,7 @@ void Sky::ApplySky(GPUContext* context, RenderContext& renderContext, const Matr
Matrix::Multiply(world, renderContext.View.Frustum.GetMatrix(), m);
Matrix::Transpose(m, data.WVP);
GBufferPass::SetInputs(renderContext.View, data.GBuffer);
data.ViewOffset = renderContext.View.Origin + GetPosition();
InitConfig(data.Fog);
//data.Fog.AtmosphericFogSunPower *= SunLight ? SunLight->Brightness : 1.0f;
bool useSpecularLight = (renderContext.View.Flags & ViewFlags::SpecularLight) != 0;

View File

@@ -37,6 +37,15 @@ float SkyLight::GetScaledRadius() const
return _radius * _transform.Scale.MaxValue();
}
CubeTexture* SkyLight::GetSource() const
{
if (Mode == Modes::CaptureScene)
return _bakedProbe;
if (Mode == Modes::CustomTexture)
return CustomTexture.Get();
return nullptr;
}
void SkyLight::Bake(float timeout)
{
#if COMPILE_WITH_PROBES_BAKING

View File

@@ -63,7 +63,6 @@ public:
/// <summary>
/// Gets the radius.
/// </summary>
/// <returns>The value.</returns>
API_PROPERTY(Attributes="EditorOrder(29), DefaultValue(1000000.0f), Limit(0), EditorDisplay(\"Light\")")
FORCE_INLINE float GetRadius() const
{
@@ -73,8 +72,7 @@ public:
/// <summary>
/// Sets the radius.
/// </summary>
/// <param name="value">The value.</param>
void SetRadius(float value);
API_PROPERTY() void SetRadius(float value);
/// <summary>
/// Gets the scaled radius of the sky light.
@@ -84,15 +82,7 @@ public:
/// <summary>
/// Gets the light source texture.
/// </summary>
/// <returns>The cube texture.</returns>
CubeTexture* GetSource() const
{
if (Mode == Modes::CaptureScene)
return _bakedProbe;
if (Mode == Modes::CustomTexture)
return CustomTexture.Get();
return nullptr;
}
CubeTexture* GetSource() const;
public:
/// <summary>

View File

@@ -232,20 +232,18 @@ void StaticModel::Draw(RenderContext& renderContext)
const DrawPass drawModes = (DrawPass)(DrawModes & renderContext.View.Pass);
if (!Model || !Model->IsLoaded() || !Model->CanBeRendered() || drawModes == DrawPass::None)
return;
Matrix world;
renderContext.View.GetWorldMatrix(_transform, world);
if (renderContext.View.Pass == DrawPass::GlobalSDF)
{
GlobalSignDistanceFieldPass::Instance()->RasterizeModelSDF(this, Model->SDF, world, _box);
GlobalSignDistanceFieldPass::Instance()->RasterizeModelSDF(this, Model->SDF, _transform, _box);
return;
}
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
{
GlobalSurfaceAtlasPass::Instance()->RasterizeActor(this, this, _sphere, world, Model->LODs.Last().GetBox());
GlobalSurfaceAtlasPass::Instance()->RasterizeActor(this, this, _sphere, _transform, Model->LODs.Last().GetBox());
return;
}
Matrix world;
renderContext.View.GetWorldMatrix(_transform, world);
GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, world);
// Flush vertex colors if need to

View File

@@ -1282,8 +1282,7 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
// Calculate object bounds size in the view
OrientedBoundingBox viewBounds(object->Bounds);
viewBounds.Transform(tile->ViewMatrix);
Float3 viewExtent;
viewExtent = viewBounds.Transformation.LocalToWorldVector(viewBounds.Extents);
Float3 viewExtent = viewBounds.Transformation.LocalToWorldVector(viewBounds.Extents);
tile->ViewBoundsSize = viewExtent.GetAbsolute() * 2.0f;
// Per-tile data

View File

@@ -80,7 +80,7 @@ public:
void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output);
// 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 Matrix& 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);
private:
#if COMPILE_WITH_DEV_ENV

View File

@@ -173,6 +173,7 @@ public:
int32 Resolution = 0;
GPUTexture* Texture = nullptr;
GPUTexture* TextureMip = nullptr;
Vector3 Origin = Vector3::Zero;
Array<CascadeData, FixedAllocation<4>> Cascades;
HashSet<ScriptingTypeHandle> ObjectTypes;
HashSet<GPUTexture*> SDFTextures;
@@ -431,7 +432,6 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
}
desc.Width = resolutionMip * cascadesCount;
desc.Height = desc.Depth = resolutionMip;
for (auto& cascade : sdfData.Cascades)
{
GPUTexture*& texture = sdfData.TextureMip;
if (texture && texture->Width() != desc.Width)
@@ -446,6 +446,13 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
return true;
}
}
uint64 memoryUsage = sdfData.Texture->GetMemoryUsage() + sdfData.TextureMip->GetMemoryUsage();
LOG(Info, "Global SDF memory usage: {0} MB", memoryUsage / 1024 / 1024);
}
if (sdfData.Origin != renderContext.View.Origin)
{
sdfData.Origin = renderContext.View.Origin;
updated = true;
}
GPUTexture* tmpMip = nullptr;
if (updated)
@@ -456,23 +463,20 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
cascade.NonEmptyChunks.Clear();
cascade.StaticChunks.Clear();
}
uint64 memoryUsage = sdfData.Texture->GetMemoryUsage();
context->ClearUA(sdfData.Texture, Float4::One);
memoryUsage += sdfData.TextureMip->GetMemoryUsage();
context->ClearUA(sdfData.TextureMip, Float4::One);
LOG(Info, "Global SDF memory usage: {0} MB", memoryUsage / 1024 / 1024);
}
for (SceneRendering* scene : renderContext.List->Scenes)
sdfData.ListenSceneRendering(scene);
// Calculate origin for Global SDF by shifting it towards the view direction to account for better view frustum coverage
Float3 viewOrigin = renderContext.View.Position;
Float3 viewPosition = renderContext.View.Position;
{
Float3 viewDirection = renderContext.View.Direction;
const float cascade0Distance = distanceExtent * cascadesDistanceScales[0];
const Vector2 viewRayHit = CollisionsHelper::LineHitsBox(viewOrigin, viewOrigin + viewDirection * (cascade0Distance * 2.0f), viewOrigin - cascade0Distance, viewOrigin + cascade0Distance);
const Vector2 viewRayHit = CollisionsHelper::LineHitsBox(viewPosition, viewPosition + viewDirection * (cascade0Distance * 2.0f), viewPosition - cascade0Distance, viewPosition + cascade0Distance);
const float viewOriginOffset = (float)viewRayHit.Y * cascade0Distance * 0.6f;
viewOrigin += viewDirection * viewOriginOffset;
viewPosition += viewDirection * viewOriginOffset;
}
// Rasterize world geometry into Global SDF
@@ -499,7 +503,7 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
const float cascadeVoxelSize = cascadeMaxDistance / (float)resolution;
const float cascadeChunkSize = cascadeVoxelSize * GLOBAL_SDF_RASTERIZE_CHUNK_SIZE;
static_assert(GLOBAL_SDF_RASTERIZE_CHUNK_SIZE % GLOBAL_SDF_RASTERIZE_MIP_FACTOR == 0, "Adjust chunk size to match the mip factor scale.");
const Float3 center = Float3::Floor(viewOrigin / cascadeChunkSize) * cascadeChunkSize;
const Float3 center = Float3::Floor(viewPosition / cascadeChunkSize) * cascadeChunkSize;
//const Float3 center = Float3::Zero;
BoundingBox cascadeBounds(center - cascadeDistance, center + cascadeDistance);
// TODO: add scene detail scale factor to PostFx settings (eg. to increase or decrease scene details and quality)
@@ -533,11 +537,14 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
_sdfData = &sdfData;
{
PROFILE_CPU_NAMED("Draw");
BoundingBox cascadeBoundsWorld = cascadeBounds;
cascadeBoundsWorld.Minimum += sdfData.Origin;
cascadeBoundsWorld.Maximum += sdfData.Origin;
for (SceneRendering* scene : renderContext.List->Scenes)
{
for (const auto& e : scene->Actors)
{
if (viewMask & e.LayerMask && e.Bounds.Radius >= minObjectRadius && CollisionsHelper::BoxIntersectsSphere(cascadeBounds, e.Bounds))
if (viewMask & e.LayerMask && e.Bounds.Radius >= minObjectRadius && CollisionsHelper::BoxIntersectsSphere(cascadeBoundsWorld, e.Bounds))
{
e.Actor->Draw(renderContext);
}
@@ -578,7 +585,6 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
// TODO: don't stall with UAV barrier on D3D12/Vulkan if UAVs don't change between dispatches
}
}
// TODO: rasterize models into global sdf relative to the cascade origin to prevent fp issues on large worlds
{
PROFILE_GPU_CPU("Rasterize Chunks");
@@ -838,7 +844,7 @@ void GlobalSignDistanceFieldPass::RenderDebug(RenderContext& renderContext, GPUC
context->DrawFullscreenTriangle();
}
void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBase::SDFData& sdf, const Matrix& localToWorld, const BoundingBox& objectBounds)
void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBase::SDFData& sdf, const Transform& localToWorld, const BoundingBox& objectBounds)
{
if (!sdf.Texture || sdf.Texture->ResidentMipLevels() == 0)
return;
@@ -846,15 +852,16 @@ void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBas
// Setup object data
BoundingBox objectBoundsCascade;
const float objectMargin = _voxelSize * GLOBAL_SDF_RASTERIZE_CHUNK_MARGIN;
Vector3::Clamp(objectBounds.Minimum - objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Minimum);
Vector3::Clamp(objectBounds.Minimum - _sdfData->Origin - objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Minimum);
Vector3::Subtract(objectBoundsCascade.Minimum, _cascadeBounds.Minimum, objectBoundsCascade.Minimum);
Vector3::Clamp(objectBounds.Maximum + objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Maximum);
Vector3::Clamp(objectBounds.Maximum - _sdfData->Origin + objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Maximum);
Vector3::Subtract(objectBoundsCascade.Maximum, _cascadeBounds.Minimum, objectBoundsCascade.Maximum);
const float chunkSize = _voxelSize * GLOBAL_SDF_RASTERIZE_CHUNK_SIZE;
Int3 objectChunkMin(objectBoundsCascade.Minimum / chunkSize);
Int3 objectChunkMax(objectBoundsCascade.Maximum / chunkSize);
Matrix worldToLocal, volumeToWorld;
Matrix::Invert(localToWorld, worldToLocal);
Matrix localToWorldM, worldToLocal, volumeToWorld;
Matrix::Transformation(localToWorld.Scale, localToWorld.Orientation, localToWorld.Translation - _sdfData->Origin, localToWorldM);
Matrix::Invert(localToWorldM, worldToLocal);
BoundingBox localVolumeBounds(sdf.LocalBoundsMin, sdf.LocalBoundsMax);
Float3 volumeLocalBoundsExtent = localVolumeBounds.GetSize() * 0.5f;
Matrix worldToVolume = worldToLocal * Matrix::Translation(-(localVolumeBounds.Minimum + volumeLocalBoundsExtent));
@@ -862,7 +869,7 @@ void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBas
// Pick the SDF mip for the cascade
int32 mipLevelIndex = 1;
float worldUnitsPerVoxel = sdf.WorldUnitsPerVoxel * localToWorld.GetScaleVector().MaxValue() * 2;
float worldUnitsPerVoxel = sdf.WorldUnitsPerVoxel * localToWorld.Scale.MaxValue() * 2;
while (_voxelSize > worldUnitsPerVoxel && mipLevelIndex < sdf.Texture->MipLevels())
{
mipLevelIndex++;
@@ -925,7 +932,7 @@ void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBas
}
}
void GlobalSignDistanceFieldPass::RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Matrix& localToWorld, const BoundingBox& objectBounds, const Float4& localToUV)
void GlobalSignDistanceFieldPass::RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Transform& localToWorld, const BoundingBox& objectBounds, const Float4& localToUV)
{
if (!heightfield || heightfield->ResidentMipLevels() == 0)
return;
@@ -933,9 +940,9 @@ void GlobalSignDistanceFieldPass::RasterizeHeightfield(Actor* actor, GPUTexture*
// Setup object data
BoundingBox objectBoundsCascade;
const float objectMargin = _voxelSize * GLOBAL_SDF_RASTERIZE_CHUNK_MARGIN;
Vector3::Clamp(objectBounds.Minimum - objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Minimum);
Vector3::Clamp(objectBounds.Minimum - _sdfData->Origin - objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Minimum);
Vector3::Subtract(objectBoundsCascade.Minimum, _cascadeBounds.Minimum, objectBoundsCascade.Minimum);
Vector3::Clamp(objectBounds.Maximum + objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Maximum);
Vector3::Clamp(objectBounds.Maximum - _sdfData->Origin + objectMargin, _cascadeBounds.Minimum, _cascadeBounds.Maximum, objectBoundsCascade.Maximum);
Vector3::Subtract(objectBoundsCascade.Maximum, _cascadeBounds.Minimum, objectBoundsCascade.Maximum);
const float chunkSize = _voxelSize * GLOBAL_SDF_RASTERIZE_CHUNK_SIZE;
const Int3 objectChunkMin(objectBoundsCascade.Minimum / chunkSize);
@@ -944,10 +951,11 @@ void GlobalSignDistanceFieldPass::RasterizeHeightfield(Actor* actor, GPUTexture*
// Add object data for the GPU buffer
uint16 objectIndex = _objectsBufferCount++;
ObjectRasterizeData objectData;
Matrix worldToLocal;
Matrix::Invert(localToWorld, worldToLocal);
Matrix localToWorldM, worldToLocal;
Matrix::Transformation(localToWorld.Scale, localToWorld.Orientation, localToWorld.Translation - _sdfData->Origin, localToWorldM);
Matrix::Invert(localToWorldM, worldToLocal);
Matrix::Transpose(worldToLocal, objectData.WorldToVolume);
Matrix::Transpose(localToWorld, objectData.VolumeToWorld);
Matrix::Transpose(localToWorldM, objectData.VolumeToWorld);
objectData.VolumeToUVWMul = Float3(localToUV.X, 1.0f, localToUV.Y);
objectData.VolumeToUVWAdd = Float3(localToUV.Z, 0.0f, localToUV.W);
objectData.MipOffset = (float)_cascadeIndex * 0.5f; // Use lower-quality mip for far cascades

View File

@@ -76,9 +76,9 @@ public:
void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output);
// Rasterize Model SDF into the Global SDF. Call it from actor Draw() method during DrawPass::GlobalSDF.
void RasterizeModelSDF(Actor* actor, const ModelBase::SDFData& sdf, const Matrix& localToWorld, const BoundingBox& objectBounds);
void RasterizeModelSDF(Actor* actor, const ModelBase::SDFData& sdf, const Transform& localToWorld, const BoundingBox& objectBounds);
void RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Matrix& localToWorld, const BoundingBox& objectBounds, const Float4& localToUV);
void RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Transform& localToWorld, const BoundingBox& objectBounds, const Float4& localToUV);
private:
#if COMPILE_WITH_DEV_ENV

View File

@@ -512,7 +512,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext)
context->ResetRenderTarget();
context->ResetSR();
context->FlushState();
// Custom Post Processing
renderContext.List->RunMaterialPostFxPass(context, renderContext, MaterialPostFxLocation::AfterPostProcessingPass, frameBuffer, tempBuffer);
renderContext.List->RunCustomPostFxPass(context, renderContext, PostProcessEffectLocation::Default, frameBuffer, tempBuffer);

View File

@@ -257,6 +257,7 @@ void ShadowsPass::Prepare(RenderContext& renderContext, GPUContext* context)
shadowView.ModelLODBias = view.ModelLODBias + view.ShadowModelLODBias;
shadowView.ModelLODDistanceFactor = view.ModelLODDistanceFactor * view.ShadowModelLODDistanceFactor;
shadowView.Pass = DrawPass::Depth;
shadowView.Origin = view.Origin;
_shadowContext.List = &_shadowCache;
}

View File

@@ -152,7 +152,8 @@ void ShadowsOfMordor::Builder::onJobRender(GPUContext* context)
auto chunkSize = terrain->GetChunkSize();
const auto heightmap = patch->Heightmap.Get()->GetTexture();
const Matrix& world = chunk->GetWorld();
Matrix world;
chunk->GetTransform().GetWorld(world);
Matrix::Transpose(world, shaderData.WorldMatrix);
shaderData.LightmapArea = chunk->Lightmap.UVsArea;
shaderData.TerrainChunkSizeLOD0 = TERRAIN_UNITS_PER_VERTEX * chunkSize;

View File

@@ -512,7 +512,6 @@ void Terrain::Draw(RenderContext& renderContext)
const float chunkSize = TERRAIN_UNITS_PER_VERTEX * (float)_chunkSize;
const float posToUV = 0.25f / chunkSize;
Float4 localToUV(posToUV, posToUV, 0.0f, 0.0f);
Matrix localToWorld;
for (const TerrainPatch* patch : _patches)
{
if (!patch->Heightmap)
@@ -522,8 +521,7 @@ void Terrain::Draw(RenderContext& renderContext)
patchTransform.Orientation = Quaternion::Identity;
patchTransform.Scale = Float3(1.0f, patch->_yHeight, 1.0f);
patchTransform = _transform.LocalToWorld(patchTransform);
patchTransform.GetWorld(localToWorld);
GlobalSignDistanceFieldPass::Instance()->RasterizeHeightfield(this, patch->Heightmap->GetTexture(), localToWorld, patch->_bounds, localToUV);
GlobalSignDistanceFieldPass::Instance()->RasterizeHeightfield(this, patch->Heightmap->GetTexture(), patchTransform, patch->_bounds, localToUV);
}
return;
}
@@ -533,16 +531,17 @@ void Terrain::Draw(RenderContext& renderContext)
{
if (!patch->Heightmap)
continue;
Matrix worldToLocal;
Matrix localToWorld, worldToLocal;
BoundingSphere chunkSphere;
BoundingBox localBounds;
for (int32 chunkIndex = 0; chunkIndex < TerrainPatch::CHUNKS_COUNT; chunkIndex++)
{
TerrainChunk* chunk = &patch->Chunks[chunkIndex];
Matrix::Invert(chunk->GetWorld(), worldToLocal);
chunk->GetTransform().GetWorld(localToWorld); // TODO: large-worlds
Matrix::Invert(localToWorld, worldToLocal);
BoundingBox::Transform(chunk->GetBounds(), worldToLocal, localBounds);
BoundingSphere::FromBox(chunk->GetBounds(), chunkSphere);
GlobalSurfaceAtlasPass::Instance()->RasterizeActor(this, chunk, chunkSphere, chunk->GetWorld(), localBounds, 1 << 2, false);
GlobalSurfaceAtlasPass::Instance()->RasterizeActor(this, chunk, chunkSphere, chunk->GetTransform(), localBounds, 1 << 2, false);
}
}
return;

View File

@@ -86,7 +86,7 @@ void TerrainChunk::Draw(const RenderContext& renderContext) const
return;
drawCall.InstanceCount = 1;
drawCall.Material = _cachedDrawMaterial;
drawCall.World = _world;
renderContext.View.GetWorldMatrix(_transform, drawCall.World);
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.Terrain.Patch = _patch;
drawCall.Terrain.HeightmapUVScaleBias = _heightmapUVScaleBias;
@@ -142,7 +142,7 @@ void TerrainChunk::Draw(const RenderContext& renderContext, MaterialBase* materi
return;
drawCall.InstanceCount = 1;
drawCall.Material = material;
drawCall.World = _world;
renderContext.View.GetWorldMatrix(_transform, drawCall.World);
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.Terrain.Patch = _patch;
drawCall.Terrain.HeightmapUVScaleBias = _heightmapUVScaleBias;
@@ -214,8 +214,7 @@ void TerrainChunk::UpdateTransform()
localTransform.Translation = _patch->_offset + Vector3(_x * size, _patch->_yOffset, _z * size);
localTransform.Orientation = Quaternion::Identity;
localTransform.Scale = Vector3(1.0f, _patch->_yHeight, 1.0f);
localTransform = terrainTransform.LocalToWorld(localTransform);
localTransform.GetWorld(_world);
_transform = terrainTransform.LocalToWorld(localTransform);
}
void TerrainChunk::CacheNeighbors()

View File

@@ -4,6 +4,7 @@
#include "Engine/Core/Math/BoundingBox.h"
#include "Engine/Core/Math/Matrix.h"
#include "Engine/Core/Math/Transform.h"
#include "Engine/Serialization/ISerializable.h"
#include "Engine/Content/Assets/MaterialBase.h"
#include "Engine/Level/Scene/Lightmap.h"
@@ -26,7 +27,7 @@ private:
TerrainPatch* _patch;
uint16 _x, _z;
Float4 _heightmapUVScaleBias;
Matrix _world;
Transform _transform;
BoundingBox _bounds;
Vector3 _boundsCenter;
float _perInstanceRandom;
@@ -85,11 +86,11 @@ public:
}
/// <summary>
/// Gets the chunk world matrix transform.
/// Gets the chunk transformation (world to local).
/// </summary>
FORCE_INLINE const Matrix& GetWorld() const
FORCE_INLINE const Transform& GetTransform() const
{
return _world;
return _transform;
}
/// <summary>

View File

@@ -238,9 +238,9 @@ float4 PS_Debug(Quad_VS2PS input) : SV_Target
float zSlice = 0.6f;
float mip = 0;
uint cascade = 0;
float distance01 = GlobalSDFTex[cascade].SampleLevel(SamplerLinearClamp, float3(input.TexCoord, zSlice), mip).x;
//float distance01 = GlobalSDFTex[cascade].SampleLevel(SamplerLinearClamp, float3((input.TexCoord.x + cascade) / (float)GlobalSDF.CascadesCount, input.TexCoord.y, zSlice), mip).x;
//float distance01 = GlobalSDFMip[cascade].SampleLevel(SamplerLinearClamp, float3(input.TexCoord, zSlice), mip).x;
float distance01 = GlobalSDFTex.SampleLevel(SamplerLinearClamp, float3(input.TexCoord, zSlice), mip).x;
//float distance01 = GlobalSDFTex.SampleLevel(SamplerLinearClamp, float3((input.TexCoord.x + cascade) / (float)GlobalSDF.CascadesCount, input.TexCoord.y, zSlice), mip).x;
//float distance01 = GlobalSDFMip.SampleLevel(SamplerLinearClamp, float3(input.TexCoord, zSlice), mip).x;
float distance = distance01 * GlobalSDF.CascadePosDistance[cascade].w;
if (abs(distance) < 1)
return float4(1, 0, 0, 1);

View File

@@ -8,6 +8,8 @@
META_CB_BEGIN(0, Data)
float4x4 WVP;
float3 ViewOffset;
float Padding;
GBufferData GBuffer;
AtmosphericFogData AtmosphericFog;
META_CB_END
@@ -51,8 +53,7 @@ GBufferOutput PS_Sky(MaterialInput input)
float3 vsPos = GetViewPos(gBufferData, uv, LinearZ2DeviceDepth(gBufferData, 1));
float3 wsPos = mul(float4(vsPos, 1), gBufferData.InvViewMatrix).xyz;
float3 viewVector = wsPos - gBufferData.ViewPos;
float sceneDepth = length(viewVector);
float4 color = GetAtmosphericFog(AtmosphericFog, gBufferData.ViewFar, gBufferData.ViewPos, viewVector, sceneDepth, float3(0, 0, 0));
float4 color = GetAtmosphericFog(AtmosphericFog, gBufferData.ViewFar, wsPos + ViewOffset, gBufferData.ViewPos + ViewOffset);
// Pack GBuffer
output.Light = color;