Optimize Global Surface Atlas objects lighting to be less frequent with caching for static lights and objects
This commit is contained in:
@@ -41,6 +41,8 @@ void DirectionalLight::Draw(RenderContext& renderContext)
|
||||
data.ShadowsMode = ShadowsMode;
|
||||
data.CascadeCount = CascadeCount;
|
||||
data.ContactShadowsLength = ContactShadowsLength;
|
||||
data.StaticFlags = GetStaticFlags();
|
||||
data.ID = GetID();
|
||||
renderContext.List->DirectionalLights.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,8 @@ void PointLight::Draw(RenderContext& renderContext)
|
||||
data.ContactShadowsLength = ContactShadowsLength;
|
||||
data.IndirectLightingIntensity = IndirectLightingIntensity;
|
||||
data.IESTexture = IESTexture ? IESTexture->GetTexture() : nullptr;
|
||||
data.StaticFlags = GetStaticFlags();
|
||||
data.ID = GetID();
|
||||
renderContext.List->PointLights.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ void SkyLight::Draw(RenderContext& renderContext)
|
||||
data.IndirectLightingIntensity = IndirectLightingIntensity;
|
||||
data.Radius = GetScaledRadius();
|
||||
data.Image = GetSource();
|
||||
data.StaticFlags = GetStaticFlags();
|
||||
data.ID = GetID();
|
||||
renderContext.List->SkyLights.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +186,8 @@ void SpotLight::Draw(RenderContext& renderContext)
|
||||
data.IESTexture = IESTexture ? IESTexture->GetTexture() : nullptr;
|
||||
Float3::Transform(Float3::Up, GetOrientation(), data.UpVector);
|
||||
data.OuterConeAngle = outerConeAngle;
|
||||
data.StaticFlags = GetStaticFlags();
|
||||
data.ID = GetID();
|
||||
renderContext.List->SpotLights.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,8 @@ struct GlobalSurfaceAtlasTile : RectPack<GlobalSurfaceAtlasTile, uint16>
|
||||
struct GlobalSurfaceAtlasObject
|
||||
{
|
||||
uint64 LastFrameUsed;
|
||||
uint64 LastFrameDirty;
|
||||
uint64 LastFrameUpdated;
|
||||
uint64 LightingUpdateFrame; // Index of the frame to update lighting for this object (calculated when object gets dirty or overriden by dynamic lights)
|
||||
Actor* Actor;
|
||||
GlobalSurfaceAtlasTile* Tiles[6];
|
||||
float Radius;
|
||||
@@ -120,6 +121,12 @@ struct GlobalSurfaceAtlasObject
|
||||
}
|
||||
};
|
||||
|
||||
struct GlobalSurfaceAtlasLight
|
||||
{
|
||||
uint64 LastFrameUsed = 0;
|
||||
uint64 LastFrameUpdated = 0;
|
||||
};
|
||||
|
||||
class GlobalSurfaceAtlasCustomBuffer : public RenderBuffers::CustomBuffer, public ISceneRenderingListener
|
||||
{
|
||||
public:
|
||||
@@ -139,6 +146,7 @@ public:
|
||||
GlobalSurfaceAtlasPass::BindingData Result;
|
||||
GlobalSurfaceAtlasTile* AtlasTiles = nullptr; // TODO: optimize with a single allocation for atlas tiles
|
||||
Dictionary<void*, GlobalSurfaceAtlasObject> Objects;
|
||||
Dictionary<Guid, GlobalSurfaceAtlasLight> Lights;
|
||||
|
||||
// Cached data to be reused during RasterizeActor
|
||||
uint64 CurrentFrame;
|
||||
@@ -160,6 +168,7 @@ public:
|
||||
LastFrameAtlasDefragmentation = Engine::FrameCount;
|
||||
SAFE_DELETE(AtlasTiles);
|
||||
Objects.Clear();
|
||||
Lights.Clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE void Clear()
|
||||
@@ -194,7 +203,13 @@ public:
|
||||
if (object)
|
||||
{
|
||||
// Dirty object to redraw
|
||||
object->LastFrameDirty = 0;
|
||||
object->LastFrameUpdated = 0;
|
||||
}
|
||||
GlobalSurfaceAtlasLight* light = Lights.TryGet(a->GetID());
|
||||
if (light)
|
||||
{
|
||||
// Dirty light to redraw
|
||||
light->LastFrameUpdated = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,12 +286,20 @@ bool GlobalSurfaceAtlasPass::setupResources()
|
||||
if (_psClear->Init(psDesc))
|
||||
return true;
|
||||
}
|
||||
psDesc.DepthTestEnable = false;
|
||||
psDesc.DepthWriteEnable = false;
|
||||
psDesc.DepthFunc = ComparisonFunc::Never;
|
||||
if (!_psClearLighting)
|
||||
{
|
||||
_psClearLighting = device->CreatePipelineState();
|
||||
psDesc.VS = shader->GetVS("VS_Atlas");
|
||||
psDesc.PS = shader->GetPS("PS_ClearLighting");
|
||||
if (_psClearLighting->Init(psDesc))
|
||||
return true;
|
||||
}
|
||||
if (!_psDirectLighting0)
|
||||
{
|
||||
_psDirectLighting0 = device->CreatePipelineState();
|
||||
psDesc.DepthTestEnable = false;
|
||||
psDesc.DepthWriteEnable = false;
|
||||
psDesc.DepthFunc = ComparisonFunc::Never;
|
||||
psDesc.BlendMode = BlendingMode::Add;
|
||||
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RGB;
|
||||
psDesc.PS = shader->GetPS("PS_Lighting", 0);
|
||||
@@ -300,6 +323,7 @@ bool GlobalSurfaceAtlasPass::setupResources()
|
||||
void GlobalSurfaceAtlasPass::OnShaderReloading(Asset* obj)
|
||||
{
|
||||
SAFE_DELETE_GPU_RESOURCE(_psClear);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psClearLighting);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting0);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting1);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psIndirectLighting);
|
||||
@@ -317,6 +341,7 @@ void GlobalSurfaceAtlasPass::Dispose()
|
||||
SAFE_DELETE(_vertexBuffer);
|
||||
SAFE_DELETE_GPU_RESOURCE(_culledObjectsSizeBuffer);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psClear);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psClearLighting);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting0);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting1);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psIndirectLighting);
|
||||
@@ -744,14 +769,6 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
if (surfaceAtlasData.Objects.Count() != 0)
|
||||
{
|
||||
PROFILE_GPU_CPU("Direct Lighting");
|
||||
|
||||
// Copy emissive light into the final direct lighting atlas
|
||||
// TODO: test perf diff when manually copying only dirty object tiles and dirty light tiles together with indirect lighting
|
||||
{
|
||||
PROFILE_GPU_CPU("Copy Emissive");
|
||||
context->CopyTexture(surfaceAtlasData.AtlasLighting, 0, 0, 0, 0, surfaceAtlasData.AtlasEmissive, 0);
|
||||
}
|
||||
|
||||
context->SetViewportAndScissors(Viewport(0, 0, (float)resolution, (float)resolution));
|
||||
context->SetRenderTarget(surfaceAtlasData.AtlasLighting->View());
|
||||
context->BindSR(0, surfaceAtlasData.AtlasGBuffer0->View());
|
||||
@@ -767,8 +784,114 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
data.GlobalSDF = bindingDataSDF.Constants;
|
||||
data.GlobalSurfaceAtlas = result.Constants;
|
||||
|
||||
// Collect objects to update lighting this frame (dirty objects and dirty lights)
|
||||
bool allLightingDirty = false;
|
||||
for (auto& light : renderContext.List->DirectionalLights)
|
||||
{
|
||||
GlobalSurfaceAtlasLight& lightData = surfaceAtlasData.Lights[light.ID];
|
||||
lightData.LastFrameUsed = currentFrame;
|
||||
uint32 redrawFramesCount = (light.StaticFlags & StaticFlags::Lightmap) ? 120 : 4;
|
||||
if (surfaceAtlasData.CurrentFrame - lightData.LastFrameUpdated < (redrawFramesCount + (light.ID.D & redrawFramesCount)))
|
||||
continue;
|
||||
lightData.LastFrameUpdated = currentFrame;
|
||||
|
||||
// Mark all objects to shade
|
||||
allLightingDirty = true;
|
||||
}
|
||||
if (renderContext.View.Flags & ViewFlags::GI && (renderContext.List->DirectionalLights.Count() != 1 || renderContext.List->DirectionalLights[0].StaticFlags & StaticFlags::Lightmap))
|
||||
{
|
||||
switch (renderContext.List->Settings.GlobalIllumination.Mode)
|
||||
{
|
||||
case GlobalIlluminationMode::DDGI:
|
||||
{
|
||||
DynamicDiffuseGlobalIlluminationPass::BindingData bindingDataDDGI;
|
||||
if (!DynamicDiffuseGlobalIlluminationPass::Instance()->Get(renderContext.Buffers, bindingDataDDGI))
|
||||
{
|
||||
GlobalSurfaceAtlasLight& lightData = surfaceAtlasData.Lights[Guid(0, 0, 0, 1)];
|
||||
lightData.LastFrameUsed = currentFrame;
|
||||
uint32 redrawFramesCount = 4; // GI Bounce redraw minimum frequency
|
||||
if (surfaceAtlasData.CurrentFrame - lightData.LastFrameUpdated < redrawFramesCount)
|
||||
break;
|
||||
lightData.LastFrameUpdated = currentFrame;
|
||||
|
||||
// Mark all objects to shade
|
||||
allLightingDirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& light : renderContext.List->PointLights)
|
||||
{
|
||||
GlobalSurfaceAtlasLight& lightData = surfaceAtlasData.Lights[light.ID];
|
||||
lightData.LastFrameUsed = currentFrame;
|
||||
uint32 redrawFramesCount = (light.StaticFlags & StaticFlags::Lightmap) ? 120 : 4;
|
||||
if (surfaceAtlasData.CurrentFrame - lightData.LastFrameUpdated < (redrawFramesCount + (light.ID.D & redrawFramesCount)))
|
||||
continue;
|
||||
lightData.LastFrameUpdated = currentFrame;
|
||||
|
||||
if (!allLightingDirty)
|
||||
{
|
||||
// Mark objects to shade
|
||||
for (auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
auto& object = e.Value;
|
||||
Float3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
if (lightToObject.LengthSquared() >= Math::Square(object.Radius + light.Radius))
|
||||
continue;
|
||||
object.LightingUpdateFrame = currentFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& light : renderContext.List->SpotLights)
|
||||
{
|
||||
GlobalSurfaceAtlasLight& lightData = surfaceAtlasData.Lights[light.ID];
|
||||
lightData.LastFrameUsed = currentFrame;
|
||||
uint32 redrawFramesCount = (light.StaticFlags & StaticFlags::Lightmap) ? 120 : 4;
|
||||
if (surfaceAtlasData.CurrentFrame - lightData.LastFrameUpdated < (redrawFramesCount + (light.ID.D & redrawFramesCount)))
|
||||
continue;
|
||||
lightData.LastFrameUpdated = currentFrame;
|
||||
|
||||
if (!allLightingDirty)
|
||||
{
|
||||
// Mark objects to shade
|
||||
for (auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
auto& object = e.Value;
|
||||
Float3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
if (lightToObject.LengthSquared() >= Math::Square(object.Radius + light.Radius))
|
||||
continue;
|
||||
object.LightingUpdateFrame = currentFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy emissive light into the final direct lighting atlas
|
||||
{
|
||||
PROFILE_GPU_CPU("Copy Emissive");
|
||||
_vertexBuffer->Clear();
|
||||
for (const auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
const auto& object = e.Value;
|
||||
if (!allLightingDirty && object.LightingUpdateFrame != currentFrame)
|
||||
continue;
|
||||
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)
|
||||
{
|
||||
auto* tile = object.Tiles[tileIndex];
|
||||
if (!tile)
|
||||
continue;
|
||||
VB_WRITE_TILE(tile);
|
||||
}
|
||||
}
|
||||
if (_vertexBuffer->Data.Count() != 0)
|
||||
{
|
||||
context->BindSR(7, surfaceAtlasData.AtlasEmissive);
|
||||
context->SetState(_psClearLighting);
|
||||
VB_DRAW();
|
||||
}
|
||||
}
|
||||
|
||||
// Shade object tiles influenced by lights to calculate direct lighting
|
||||
// TODO: reduce redraw frequency for static lights (StaticFlags::Lightmap)
|
||||
for (auto& light : renderContext.List->DirectionalLights)
|
||||
{
|
||||
// Collect tiles to shade
|
||||
@@ -776,6 +899,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
for (const auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
const auto& object = e.Value;
|
||||
if (!allLightingDirty && object.LightingUpdateFrame != currentFrame)
|
||||
continue;
|
||||
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)
|
||||
{
|
||||
auto* tile = object.Tiles[tileIndex];
|
||||
@@ -784,8 +909,11 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
VB_WRITE_TILE(tile);
|
||||
}
|
||||
}
|
||||
if (_vertexBuffer->Data.Count() == 0)
|
||||
continue;
|
||||
|
||||
// Draw draw light
|
||||
PROFILE_GPU_CPU("Directional Light");
|
||||
const bool useShadow = CanRenderShadow(renderContext.View, light);
|
||||
// TODO: test perf/quality when using Shadow Map for directional light (ShadowsPass::Instance()->LastDirLightShadowMap) instead of Global SDF trace
|
||||
light.SetupLightData(&data.Light, useShadow);
|
||||
@@ -802,6 +930,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
for (const auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
const auto& object = e.Value;
|
||||
if (!allLightingDirty && object.LightingUpdateFrame != currentFrame)
|
||||
continue;
|
||||
Float3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
if (lightToObject.LengthSquared() >= Math::Square(object.Radius + light.Radius))
|
||||
continue;
|
||||
@@ -813,8 +943,11 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
VB_WRITE_TILE(tile);
|
||||
}
|
||||
}
|
||||
if (_vertexBuffer->Data.Count() == 0)
|
||||
continue;
|
||||
|
||||
// Draw draw light
|
||||
PROFILE_GPU_CPU("Point Light");
|
||||
const bool useShadow = CanRenderShadow(renderContext.View, light);
|
||||
light.SetupLightData(&data.Light, useShadow);
|
||||
data.Light.Color *= light.IndirectLightingIntensity;
|
||||
@@ -830,6 +963,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
for (const auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
const auto& object = e.Value;
|
||||
if (!allLightingDirty && object.LightingUpdateFrame != currentFrame)
|
||||
continue;
|
||||
Float3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
if (lightToObject.LengthSquared() >= Math::Square(object.Radius + light.Radius))
|
||||
continue;
|
||||
@@ -841,8 +976,11 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
VB_WRITE_TILE(tile);
|
||||
}
|
||||
}
|
||||
if (_vertexBuffer->Data.Count() == 0)
|
||||
continue;
|
||||
|
||||
// Draw draw light
|
||||
PROFILE_GPU_CPU("Spot Light");
|
||||
const bool useShadow = CanRenderShadow(renderContext.View, light);
|
||||
light.SetupLightData(&data.Light, useShadow);
|
||||
data.Light.Color *= light.IndirectLightingIntensity;
|
||||
@@ -851,9 +989,17 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
context->SetState(_psDirectLighting1);
|
||||
VB_DRAW();
|
||||
}
|
||||
|
||||
// Remove unused lights
|
||||
for (auto it = surfaceAtlasData.Lights.Begin(); it.IsNotEnd(); ++it)
|
||||
{
|
||||
if (it->Value.LastFrameUsed != currentFrame)
|
||||
surfaceAtlasData.Lights.Remove(it);
|
||||
}
|
||||
|
||||
// Draw draw indirect light from Global Illumination
|
||||
if (renderContext.View.Flags & ViewFlags::GI)
|
||||
{
|
||||
// Draw draw indirect light from Global Illumination
|
||||
switch (renderContext.List->Settings.GlobalIllumination.Mode)
|
||||
{
|
||||
case GlobalIlluminationMode::DDGI:
|
||||
@@ -865,6 +1011,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
for (const auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
const auto& object = e.Value;
|
||||
if (!allLightingDirty && object.LightingUpdateFrame != currentFrame)
|
||||
continue;
|
||||
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)
|
||||
{
|
||||
auto* tile = object.Tiles[tileIndex];
|
||||
@@ -873,6 +1021,9 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
VB_WRITE_TILE(tile);
|
||||
}
|
||||
}
|
||||
if (_vertexBuffer->Data.Count() == 0)
|
||||
break;
|
||||
PROFILE_GPU_CPU("DDGI");
|
||||
data.DDGI = bindingDataDDGI.Constants;
|
||||
context->BindSR(5, bindingDataDDGI.ProbesState);
|
||||
context->BindSR(6, bindingDataDDGI.ProbesDistance);
|
||||
@@ -1065,7 +1216,7 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
|
||||
// Redraw objects from time-to-time (dynamic objects can be animated, static objects can have textures streamed)
|
||||
uint32 redrawFramesCount = actor->HasStaticFlag(StaticFlags::Lightmap) ? 120 : 4;
|
||||
if (surfaceAtlasData.CurrentFrame - object->LastFrameDirty >= (redrawFramesCount + (actor->GetID().D & redrawFramesCount)))
|
||||
if (surfaceAtlasData.CurrentFrame - object->LastFrameUpdated >= (redrawFramesCount + (actor->GetID().D & redrawFramesCount)))
|
||||
dirty = true;
|
||||
|
||||
// Mark object as used
|
||||
@@ -1076,7 +1227,8 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
object->Radius = (float)actorObjectBounds.Radius;
|
||||
if (dirty || GLOBAL_SURFACE_ATLAS_DEBUG_FORCE_REDRAW_TILES)
|
||||
{
|
||||
object->LastFrameDirty = surfaceAtlasData.CurrentFrame;
|
||||
object->LastFrameUpdated = surfaceAtlasData.CurrentFrame;
|
||||
object->LightingUpdateFrame = surfaceAtlasData.CurrentFrame;
|
||||
_dirtyObjectsBuffer.Add(actorObject);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ private:
|
||||
bool _supported = false;
|
||||
AssetReference<Shader> _shader;
|
||||
GPUPipelineState* _psClear = nullptr;
|
||||
GPUPipelineState* _psClearLighting = nullptr;
|
||||
GPUPipelineState* _psDirectLighting0 = nullptr;
|
||||
GPUPipelineState* _psDirectLighting1 = nullptr;
|
||||
GPUPipelineState* _psIndirectLighting = nullptr;
|
||||
|
||||
@@ -34,6 +34,7 @@ struct RendererDirectionalLightData
|
||||
float ShadowsSharpness;
|
||||
float VolumetricScatteringIntensity;
|
||||
|
||||
StaticFlags StaticFlags;
|
||||
float IndirectLightingIntensity;
|
||||
int8 CastVolumetricShadow : 1;
|
||||
int8 RenderedVolumetricFog : 1;
|
||||
@@ -43,6 +44,8 @@ struct RendererDirectionalLightData
|
||||
float ContactShadowsLength;
|
||||
ShadowsCastingMode ShadowsMode;
|
||||
|
||||
Guid ID;
|
||||
|
||||
void SetupLightData(LightData* data, bool useShadow) const;
|
||||
};
|
||||
|
||||
@@ -76,11 +79,13 @@ struct RendererSpotLightData
|
||||
float IndirectLightingIntensity;
|
||||
ShadowsCastingMode ShadowsMode;
|
||||
|
||||
StaticFlags StaticFlags;
|
||||
int8 CastVolumetricShadow : 1;
|
||||
int8 RenderedVolumetricFog : 1;
|
||||
int8 UseInverseSquaredFalloff : 1;
|
||||
|
||||
GPUTexture* IESTexture;
|
||||
Guid ID;
|
||||
|
||||
void SetupLightData(LightData* data, bool useShadow) const;
|
||||
};
|
||||
@@ -111,11 +116,13 @@ struct RendererPointLightData
|
||||
float IndirectLightingIntensity;
|
||||
ShadowsCastingMode ShadowsMode;
|
||||
|
||||
StaticFlags StaticFlags;
|
||||
int8 CastVolumetricShadow : 1;
|
||||
int8 RenderedVolumetricFog : 1;
|
||||
int8 UseInverseSquaredFalloff : 1;
|
||||
|
||||
GPUTexture* IESTexture;
|
||||
Guid ID;
|
||||
|
||||
void SetupLightData(LightData* data, bool useShadow) const;
|
||||
};
|
||||
@@ -131,10 +138,12 @@ struct RendererSkyLightData
|
||||
Float3 AdditiveColor;
|
||||
float IndirectLightingIntensity;
|
||||
|
||||
StaticFlags StaticFlags;
|
||||
int8 CastVolumetricShadow : 1;
|
||||
int8 RenderedVolumetricFog : 1;
|
||||
|
||||
CubeTexture* Image;
|
||||
Guid ID;
|
||||
|
||||
void SetupLightData(LightData* data, bool useShadow) const;
|
||||
};
|
||||
@@ -211,7 +220,6 @@ struct DrawBatch
|
||||
class RenderListAllocation
|
||||
{
|
||||
public:
|
||||
|
||||
static FLAXENGINE_API void* Allocate(uintptr size);
|
||||
static FLAXENGINE_API void Free(void* ptr, uintptr size);
|
||||
|
||||
@@ -222,7 +230,6 @@ public:
|
||||
uintptr _size;
|
||||
|
||||
public:
|
||||
|
||||
FORCE_INLINE Data()
|
||||
{
|
||||
}
|
||||
@@ -329,7 +336,7 @@ struct DrawCallsList
|
||||
/// </summary>
|
||||
API_CLASS(Sealed) class FLAXENGINE_API RenderList : public ScriptingObject
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE(RenderList);
|
||||
DECLARE_SCRIPTING_TYPE(RenderList);
|
||||
|
||||
/// <summary>
|
||||
/// Allocates the new renderer list object or reuses already allocated one.
|
||||
@@ -349,7 +356,6 @@ DECLARE_SCRIPTING_TYPE(RenderList);
|
||||
static void CleanupCache();
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// All scenes for rendering.
|
||||
/// </summary>
|
||||
@@ -458,11 +464,9 @@ public:
|
||||
Float3 FrustumCornersVs[8];
|
||||
|
||||
private:
|
||||
|
||||
DynamicVertexBuffer _instanceBuffer;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Blends the postprocessing settings into the final options.
|
||||
/// </summary>
|
||||
@@ -527,7 +531,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Init cache for given task
|
||||
/// </summary>
|
||||
@@ -540,7 +543,6 @@ public:
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Adds the draw call to the draw lists.
|
||||
/// </summary>
|
||||
|
||||
@@ -62,6 +62,22 @@ void PS_Clear(out float4 Light : SV_Target0, out float4 RT0 : SV_Target1, out fl
|
||||
RT2 = float4(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef _PS_ClearLighting
|
||||
|
||||
Buffer<float4> GlobalSurfaceAtlasObjects : register(t4);
|
||||
Texture2D Texture : register(t7);
|
||||
|
||||
// Pixel shader for Global Surface Atlas clearing
|
||||
META_PS(true, FEATURE_LEVEL_SM5)
|
||||
float4 PS_ClearLighting(AtlasVertexOutput input) : SV_Target
|
||||
{
|
||||
GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(GlobalSurfaceAtlasObjects, input.TileAddress);
|
||||
float2 atlasUV = input.TileUV * tile.AtlasRectUV.zw + tile.AtlasRectUV.xy;
|
||||
return Texture.Sample(SamplerPointClamp, atlasUV);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _PS_Lighting
|
||||
|
||||
#include "./Flax/GBuffer.hlsl"
|
||||
@@ -79,7 +95,7 @@ Texture3D<float> GlobalSDFTex : register(t5);
|
||||
Texture3D<float> GlobalSDFMip : register(t6);
|
||||
#endif
|
||||
|
||||
// Pixel shader for Global Surface Atlas shading with direct light contribution
|
||||
// Pixel shader for Global Surface Atlas shading
|
||||
META_PS(true, FEATURE_LEVEL_SM5)
|
||||
META_PERMUTATION_1(RADIAL_LIGHT=0)
|
||||
META_PERMUTATION_1(RADIAL_LIGHT=1)
|
||||
|
||||
Reference in New Issue
Block a user