Fix artifacts due to light shape culling and use depth test to improve perf
This commit is contained in:
@@ -337,14 +337,14 @@ void RenderTools::ComputePitch(PixelFormat format, int32 width, int32 height, ui
|
||||
case PixelFormat::ASTC_8x8_UNorm_sRGB:
|
||||
case PixelFormat::ASTC_10x10_UNorm:
|
||||
case PixelFormat::ASTC_10x10_UNorm_sRGB:
|
||||
{
|
||||
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
|
||||
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
|
||||
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
|
||||
rowPitch = nbw * 16; // All ASTC blocks use 128 bits
|
||||
slicePitch = rowPitch * nbh;
|
||||
}
|
||||
break;
|
||||
{
|
||||
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
|
||||
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
|
||||
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
|
||||
rowPitch = nbw * 16; // All ASTC blocks use 128 bits
|
||||
slicePitch = rowPitch * nbh;
|
||||
}
|
||||
break;
|
||||
case PixelFormat::R8G8_B8G8_UNorm:
|
||||
case PixelFormat::G8R8_G8B8_UNorm:
|
||||
ASSERT(PixelFormatExtensions::IsPacked(format));
|
||||
@@ -590,7 +590,7 @@ void RenderTools::CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10
|
||||
void RenderTools::ComputeSphereModelDrawMatrix(const RenderView& view, const Float3& position, float radius, Matrix& resultWorld, bool& resultIsViewInside)
|
||||
{
|
||||
// Construct world matrix
|
||||
constexpr float sphereModelScale = 0.0202f; // Manually tweaked for 'Engine/Models/Sphere'
|
||||
constexpr float sphereModelScale = 0.0205f; // Manually tweaked for 'Engine/Models/Sphere' with some slack
|
||||
const float scaling = radius * sphereModelScale;
|
||||
resultWorld = Matrix::Identity;
|
||||
resultWorld.M11 = scaling;
|
||||
@@ -601,10 +601,7 @@ void RenderTools::ComputeSphereModelDrawMatrix(const RenderView& view, const Flo
|
||||
resultWorld.M43 = position.Z;
|
||||
|
||||
// Check if view is inside the sphere
|
||||
float viewToCenter = Float3::Distance(view.Position, position);
|
||||
//if (radius + viewToCenter > view.Far)
|
||||
// radius = view.Far - viewToCenter; // Clamp radius
|
||||
resultIsViewInside = viewToCenter - radius < 5.0f; // Manually tweaked bias
|
||||
resultIsViewInside = Float3::DistanceSquared(view.Position, position) < Math::Square(radius * 1.1f); // Manually tweaked bias
|
||||
}
|
||||
|
||||
int32 MipLevelsCount(int32 width, bool useMipLevels)
|
||||
|
||||
@@ -31,20 +31,18 @@ bool LightPass::Init()
|
||||
{
|
||||
// Create pipeline states
|
||||
_psLightDir.CreatePipelineStates();
|
||||
_psLightPointNormal.CreatePipelineStates();
|
||||
_psLightPointInverted.CreatePipelineStates();
|
||||
_psLightSpotNormal.CreatePipelineStates();
|
||||
_psLightSpotInverted.CreatePipelineStates();
|
||||
_psLightSkyNormal = GPUDevice::Instance->CreatePipelineState();
|
||||
_psLightSkyInverted = GPUDevice::Instance->CreatePipelineState();
|
||||
_psLightPoint.CreatePipelineStates();
|
||||
_psLightPointInside.CreatePipelineStates();
|
||||
_psLightSpot.CreatePipelineStates();
|
||||
_psLightSpotInside.CreatePipelineStates();
|
||||
_psLightSky = GPUDevice::Instance->CreatePipelineState();
|
||||
_psLightSkyInside = GPUDevice::Instance->CreatePipelineState();
|
||||
|
||||
// Load assets
|
||||
_shader = Content::LoadAsyncInternal<Shader>(TEXT("Shaders/Lights"));
|
||||
_sphereModel = Content::LoadAsyncInternal<Model>(TEXT("Engine/Models/Sphere"));
|
||||
if (_shader == nullptr || _sphereModel == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if COMPILE_WITH_DEV_ENV
|
||||
_shader.Get()->OnReloading.Bind<LightPass, &LightPass::OnShaderReloading>(this);
|
||||
@@ -90,46 +88,50 @@ bool LightPass::setupResources()
|
||||
if (_psLightDir.Create(psDesc, shader, "PS_Directional"))
|
||||
return true;
|
||||
}
|
||||
if (!_psLightPointNormal.IsValid() || !_psLightPointInverted.IsValid())
|
||||
if (!_psLightPoint.IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultNoDepth;
|
||||
psDesc.BlendMode = BlendingMode::Add;
|
||||
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RGB;
|
||||
psDesc.VS = shader->GetVS("VS_Model");
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
if (_psLightPointInverted.Create(psDesc, shader, "PS_Point"))
|
||||
return true;
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
psDesc.DepthEnable = true;
|
||||
if (_psLightPointNormal.Create(psDesc, shader, "PS_Point"))
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
if (_psLightPoint.Create(psDesc, shader, "PS_Point"))
|
||||
return true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Greater;
|
||||
psDesc.CullMode = CullMode::Inverted;
|
||||
if (_psLightPointInside.Create(psDesc, shader, "PS_Point"))
|
||||
return true;
|
||||
}
|
||||
if (!_psLightSpotNormal.IsValid() || !_psLightSpotInverted.IsValid())
|
||||
if (!_psLightSpot.IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultNoDepth;
|
||||
psDesc.BlendMode = BlendingMode::Add;
|
||||
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RGB;
|
||||
psDesc.VS = shader->GetVS("VS_Model");
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
if (_psLightSpotInverted.Create(psDesc, shader, "PS_Spot"))
|
||||
return true;
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
psDesc.DepthEnable = true;
|
||||
if (_psLightSpotNormal.Create(psDesc, shader, "PS_Spot"))
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
if (_psLightSpot.Create(psDesc, shader, "PS_Spot"))
|
||||
return true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Greater;
|
||||
psDesc.CullMode = CullMode::Inverted;
|
||||
if (_psLightSpotInside.Create(psDesc, shader, "PS_Spot"))
|
||||
return true;
|
||||
}
|
||||
if (!_psLightSkyNormal->IsValid() || !_psLightSkyInverted->IsValid())
|
||||
if (!_psLightSky->IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultNoDepth;
|
||||
psDesc.BlendMode = BlendingMode::Add;
|
||||
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RGB;
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
psDesc.VS = shader->GetVS("VS_Model");
|
||||
psDesc.PS = shader->GetPS("PS_Sky");
|
||||
if (_psLightSkyNormal->Init(psDesc))
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
if (_psLightSky->Init(psDesc))
|
||||
return true;
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
if (_psLightSkyInverted->Init(psDesc))
|
||||
psDesc.DepthFunc = ComparisonFunc::Greater;
|
||||
psDesc.CullMode = CullMode::Inverted;
|
||||
if (_psLightSkyInside->Init(psDesc))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -143,12 +145,12 @@ void LightPass::Dispose()
|
||||
|
||||
// Cleanup
|
||||
_psLightDir.Delete();
|
||||
_psLightPointNormal.Delete();
|
||||
_psLightPointInverted.Delete();
|
||||
_psLightSpotNormal.Delete();
|
||||
_psLightSpotInverted.Delete();
|
||||
SAFE_DELETE_GPU_RESOURCE(_psLightSkyNormal);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psLightSkyInverted);
|
||||
_psLightPoint.Delete();
|
||||
_psLightPointInside.Delete();
|
||||
_psLightSpot.Delete();
|
||||
_psLightSpotInside.Delete();
|
||||
SAFE_DELETE_GPU_RESOURCE(_psLightSky);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psLightSkyInside);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psClearDiffuse);
|
||||
_sphereModel = nullptr;
|
||||
}
|
||||
@@ -298,7 +300,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
|
||||
context->BindCB(0, cb0);
|
||||
context->BindCB(1, cb1);
|
||||
int32 permutationIndex = (disableSpecular ? 1 : 0) + (useIES ? 2 : 0);
|
||||
context->SetState((isViewInside ? _psLightPointInverted : _psLightPointNormal).Get(permutationIndex));
|
||||
context->SetState((isViewInside ? _psLightPointInside : _psLightPoint).Get(permutationIndex));
|
||||
sphereMesh.Render(context);
|
||||
}
|
||||
|
||||
@@ -341,7 +343,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
|
||||
context->BindCB(0, cb0);
|
||||
context->BindCB(1, cb1);
|
||||
int32 permutationIndex = (disableSpecular ? 1 : 0) + (useIES ? 2 : 0);
|
||||
context->SetState((isViewInside ? _psLightSpotInverted : _psLightSpotNormal).Get(permutationIndex));
|
||||
context->SetState((isViewInside ? _psLightSpotInside : _psLightSpot).Get(permutationIndex));
|
||||
sphereMesh.Render(context);
|
||||
}
|
||||
|
||||
@@ -400,7 +402,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
|
||||
context->UpdateCB(cb0, &perLight);
|
||||
context->BindCB(0, cb0);
|
||||
context->BindCB(1, cb1);
|
||||
context->SetState(isViewInside ? _psLightSkyInverted : _psLightSkyNormal);
|
||||
context->SetState(isViewInside ? _psLightSkyInside : _psLightSky);
|
||||
sphereMesh.Render(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,12 @@ class LightPass : public RendererPass<LightPass>
|
||||
private:
|
||||
AssetReference<Shader> _shader;
|
||||
GPUPipelineStatePermutationsPs<2> _psLightDir;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightPointNormal;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightPointInverted;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightSpotNormal;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightSpotInverted;
|
||||
GPUPipelineState* _psLightSkyNormal = nullptr;
|
||||
GPUPipelineState* _psLightSkyInverted = nullptr;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightPoint;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightPointInside;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightSpot;
|
||||
GPUPipelineStatePermutationsPs<4> _psLightSpotInside;
|
||||
GPUPipelineState* _psLightSky = nullptr;
|
||||
GPUPipelineState* _psLightSkyInside = nullptr;
|
||||
GPUPipelineState* _psClearDiffuse = nullptr;
|
||||
AssetReference<Model> _sphereModel;
|
||||
PixelFormat _shadowMaskFormat;
|
||||
@@ -44,12 +44,12 @@ private:
|
||||
void OnShaderReloading(Asset* obj)
|
||||
{
|
||||
_psLightDir.Release();
|
||||
_psLightPointNormal.Release();
|
||||
_psLightPointInverted.Release();
|
||||
_psLightSpotNormal.Release();
|
||||
_psLightSpotInverted.Release();
|
||||
_psLightSkyNormal->ReleaseGPU();
|
||||
_psLightSkyInverted->ReleaseGPU();
|
||||
_psLightPoint.Release();
|
||||
_psLightPointInside.Release();
|
||||
_psLightSpot.Release();
|
||||
_psLightSpotInside.Release();
|
||||
_psLightSky->ReleaseGPU();
|
||||
_psLightSkyInside->ReleaseGPU();
|
||||
invalidateResources();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
#include "Engine/Level/Actors/EnvironmentProbe.h"
|
||||
|
||||
PACK_STRUCT(struct Data {
|
||||
ShaderEnvProbeData PData;
|
||||
Matrix WVP;
|
||||
ShaderGBufferData GBuffer;
|
||||
});
|
||||
|
||||
#if GENERATE_GF_CACHE
|
||||
|
||||
// This code below (PreIntegratedGF namespace) is based on many Siggraph presentations about BRDF shading:
|
||||
@@ -239,13 +245,6 @@ namespace PreIntegratedGF
|
||||
|
||||
class Model;
|
||||
|
||||
ReflectionsPass::ReflectionsPass()
|
||||
: _psProbeNormal(nullptr)
|
||||
, _psProbeInverted(nullptr)
|
||||
, _psCombinePass(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
String ReflectionsPass::ToString() const
|
||||
{
|
||||
return TEXT("ReflectionsPass");
|
||||
@@ -254,15 +253,13 @@ String ReflectionsPass::ToString() const
|
||||
bool ReflectionsPass::Init()
|
||||
{
|
||||
#if GENERATE_GF_CACHE
|
||||
|
||||
// Generate cache
|
||||
PreIntegratedGF::Generate();
|
||||
|
||||
#endif
|
||||
|
||||
// Create pipeline states
|
||||
_psProbeNormal = GPUDevice::Instance->CreatePipelineState();
|
||||
_psProbeInverted = GPUDevice::Instance->CreatePipelineState();
|
||||
_psProbe = GPUDevice::Instance->CreatePipelineState();
|
||||
_psProbeInside = GPUDevice::Instance->CreatePipelineState();
|
||||
_psCombinePass = GPUDevice::Instance->CreatePipelineState();
|
||||
|
||||
// Load assets
|
||||
@@ -294,17 +291,19 @@ bool ReflectionsPass::setupResources()
|
||||
|
||||
// Create pipeline stages
|
||||
GPUPipelineState::Description psDesc;
|
||||
if (!_psProbeNormal->IsValid() || !_psProbeInverted->IsValid())
|
||||
if (!_psProbe->IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultNoDepth;
|
||||
psDesc.BlendMode = BlendingMode::AlphaBlend;
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
psDesc.VS = shader->GetVS("VS_Model");
|
||||
psDesc.PS = shader->GetPS("PS_EnvProbe");
|
||||
if (_psProbeNormal->Init(psDesc))
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
psDesc.DepthEnable = true;
|
||||
if (_psProbe->Init(psDesc))
|
||||
return true;
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
if (_psProbeInverted->Init(psDesc))
|
||||
psDesc.DepthFunc = ComparisonFunc::Greater;
|
||||
psDesc.CullMode = CullMode::Inverted;
|
||||
if (_psProbeInside->Init(psDesc))
|
||||
return true;
|
||||
}
|
||||
psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle;
|
||||
@@ -326,8 +325,8 @@ void ReflectionsPass::Dispose()
|
||||
RendererPass::Dispose();
|
||||
|
||||
// Cleanup
|
||||
SAFE_DELETE_GPU_RESOURCE(_psProbeNormal);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psProbeInverted);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psProbe);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psProbeInside);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psCombinePass);
|
||||
_shader = nullptr;
|
||||
_sphereModel = nullptr;
|
||||
@@ -416,7 +415,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
|
||||
context->UpdateCB(cb, &data);
|
||||
context->BindCB(0, cb);
|
||||
context->BindSR(4, probe.Texture);
|
||||
context->SetState(isViewInside ? _psProbeInverted : _psProbeNormal);
|
||||
context->SetState(isViewInside ? _psProbeInside : _psProbe);
|
||||
sphereMesh.Render(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,30 +16,15 @@
|
||||
class ReflectionsPass : public RendererPass<ReflectionsPass>
|
||||
{
|
||||
private:
|
||||
|
||||
PACK_STRUCT(struct Data {
|
||||
ShaderEnvProbeData PData;
|
||||
Matrix WVP;
|
||||
ShaderGBufferData GBuffer;
|
||||
});
|
||||
|
||||
AssetReference<Shader> _shader;
|
||||
GPUPipelineState* _psProbeNormal;
|
||||
GPUPipelineState* _psProbeInverted;
|
||||
GPUPipelineState* _psCombinePass;
|
||||
GPUPipelineState* _psProbe = nullptr;
|
||||
GPUPipelineState* _psProbeInside = nullptr;
|
||||
GPUPipelineState* _psCombinePass = nullptr;
|
||||
|
||||
AssetReference<Model> _sphereModel;
|
||||
AssetReference<Texture> _preIntegratedGF;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Init
|
||||
/// </summary>
|
||||
ReflectionsPass();
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Perform reflections pass rendering for the input task.
|
||||
/// </summary>
|
||||
@@ -48,7 +33,6 @@ public:
|
||||
void Render(RenderContext& renderContext, GPUTextureView* lightBuffer);
|
||||
|
||||
public:
|
||||
|
||||
// [RendererPass]
|
||||
String ToString() const override;
|
||||
bool Init() override;
|
||||
@@ -56,15 +40,14 @@ public:
|
||||
#if COMPILE_WITH_DEV_ENV
|
||||
void OnShaderReloading(Asset* obj)
|
||||
{
|
||||
_psProbeNormal->ReleaseGPU();
|
||||
_psProbeInverted->ReleaseGPU();
|
||||
_psProbe->ReleaseGPU();
|
||||
_psProbeInside->ReleaseGPU();
|
||||
_psCombinePass->ReleaseGPU();
|
||||
invalidateResources();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
// [RendererPass]
|
||||
bool setupResources() override;
|
||||
};
|
||||
|
||||
@@ -446,7 +446,9 @@ bool ShadowsPass::Init()
|
||||
// Create pipeline states
|
||||
_psShadowDir.CreatePipelineStates();
|
||||
_psShadowPoint.CreatePipelineStates();
|
||||
_psShadowPointInside.CreatePipelineStates();
|
||||
_psShadowSpot.CreatePipelineStates();
|
||||
_psShadowSpotInside.CreatePipelineStates();
|
||||
|
||||
// Load assets
|
||||
_shader = Content::LoadAsyncInternal<Shader>(TEXT("Shaders/Shadows"));
|
||||
@@ -496,27 +498,40 @@ bool ShadowsPass::setupResources()
|
||||
|
||||
// Create pipeline stages
|
||||
GPUPipelineState::Description psDesc;
|
||||
if (!_psShadowPoint.IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultNoDepth;
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
psDesc.VS = shader->GetVS("VS_Model");
|
||||
if (_psShadowPoint.Create(psDesc, shader, "PS_PointLight"))
|
||||
return true;
|
||||
}
|
||||
if (!_psShadowDir.IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle;
|
||||
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RG;
|
||||
if (_psShadowDir.Create(psDesc, shader, "PS_DirLight"))
|
||||
return true;
|
||||
}
|
||||
if (!_psShadowPoint.IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultNoDepth;
|
||||
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RG;
|
||||
psDesc.VS = shader->GetVS("VS_Model");
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
if (_psShadowPoint.Create(psDesc, shader, "PS_PointLight"))
|
||||
return true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Greater;
|
||||
psDesc.CullMode = CullMode::Inverted;
|
||||
if (_psShadowPointInside.Create(psDesc, shader, "PS_PointLight"))
|
||||
return true;
|
||||
}
|
||||
if (!_psShadowSpot.IsValid())
|
||||
{
|
||||
psDesc = GPUPipelineState::Description::DefaultNoDepth;
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RG;
|
||||
psDesc.VS = shader->GetVS("VS_Model");
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.CullMode = CullMode::Normal;
|
||||
if (_psShadowSpot.Create(psDesc, shader, "PS_SpotLight"))
|
||||
return true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Greater;
|
||||
psDesc.CullMode = CullMode::Inverted;
|
||||
if (_psShadowSpotInside.Create(psDesc, shader, "PS_SpotLight"))
|
||||
return true;
|
||||
}
|
||||
if (_psDepthClear == nullptr)
|
||||
{
|
||||
@@ -994,7 +1009,9 @@ void ShadowsPass::Dispose()
|
||||
// Cleanup
|
||||
_psShadowDir.Delete();
|
||||
_psShadowPoint.Delete();
|
||||
_psShadowPointInside.Delete();
|
||||
_psShadowSpot.Delete();
|
||||
_psShadowSpotInside.Delete();
|
||||
_shader = nullptr;
|
||||
_sphereModel = nullptr;
|
||||
SAFE_DELETE_GPU_RESOURCE(_psDepthClear);
|
||||
@@ -1072,7 +1089,6 @@ void ShadowsPass::SetupShadows(RenderContext& renderContext, RenderContextBatch&
|
||||
}
|
||||
if (shadows.StaticAtlasTiles && (float)shadows.StaticAtlasPixelsUsed / (shadows.StaticAtlasTiles->Width * shadows.StaticAtlasTiles->Height) < SHADOWS_MAX_STATIC_ATLAS_CAPACITY_TO_DEFRAG)
|
||||
{
|
||||
float app = (float)shadows.StaticAtlasPixelsUsed / (shadows.StaticAtlasTiles->Width * shadows.StaticAtlasTiles->Height);
|
||||
// Defragment static shadow atlas if it failed to insert any light but it's still should have space
|
||||
bool anyStaticFailed = false;
|
||||
for (auto& e : shadows.Lights)
|
||||
@@ -1478,12 +1494,12 @@ void ShadowsPass::RenderShadowMask(RenderContextBatch& renderContextBatch, Rende
|
||||
sperLight.TemporalTime = renderContext.List->Setup.UseTemporalAAJitter ? RenderTools::ComputeTemporalTime() : 0.0f;
|
||||
sperLight.ContactShadowsDistance = light.ShadowsDistance;
|
||||
sperLight.ContactShadowsLength = EnumHasAnyFlags(view.Flags, ViewFlags::ContactShadows) ? light.ContactShadowsLength : 0.0f;
|
||||
bool isViewInside;
|
||||
if (isLocalLight)
|
||||
{
|
||||
// Calculate world view projection matrix for the light sphere
|
||||
Matrix world, wvp;
|
||||
bool isInside;
|
||||
RenderTools::ComputeSphereModelDrawMatrix(renderContext.View, light.Position, ((RenderLocalLightData&)light).Radius, world, isInside);
|
||||
RenderTools::ComputeSphereModelDrawMatrix(renderContext.View, light.Position, ((RenderLocalLightData&)light).Radius, world, isViewInside);
|
||||
Matrix::Multiply(world, view.ViewProjection(), wvp);
|
||||
Matrix::Transpose(wvp, sperLight.WVP);
|
||||
}
|
||||
@@ -1498,12 +1514,12 @@ void ShadowsPass::RenderShadowMask(RenderContextBatch& renderContextBatch, Rende
|
||||
context->SetRenderTarget(shadowMask);
|
||||
if (light.IsPointLight)
|
||||
{
|
||||
context->SetState(_psShadowPoint.Get(permutationIndex));
|
||||
context->SetState((isViewInside ? _psShadowPointInside : _psShadowPoint).Get(permutationIndex));
|
||||
_sphereModel->LODs.Get()[0].Meshes.Get()[0].Render(context);
|
||||
}
|
||||
else if (light.IsSpotLight)
|
||||
{
|
||||
context->SetState(_psShadowSpot.Get(permutationIndex));
|
||||
context->SetState((isViewInside ? _psShadowSpotInside : _psShadowSpot).Get(permutationIndex));
|
||||
_sphereModel->LODs.Get()[0].Meshes.Get()[0].Render(context);
|
||||
}
|
||||
else //if (light.IsDirectionalLight)
|
||||
|
||||
@@ -21,7 +21,9 @@ private:
|
||||
GPUPipelineState* _psDepthCopy = nullptr;
|
||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowDir;
|
||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowPoint;
|
||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowPointInside;
|
||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowSpot;
|
||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowSpotInside;
|
||||
PixelFormat _shadowMapFormat; // Cached on initialization
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user