Fix various rendering elements with Reversed Z enabled and simplify code

#2684
This commit is contained in:
2026-05-11 18:26:21 +02:00
parent 7f2ba7a81e
commit 0c1af2f243
52 changed files with 225 additions and 191 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -4,7 +4,7 @@
"Major": 1,
"Minor": 13,
"Revision": 0,
"Build": 7002
"Build": 7003
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
@@ -50,6 +50,10 @@
#endif
#include "FlaxEngine.Gen.h"
#ifndef REVERSE_Z
#define REVERSE_Z 0
#endif
Dictionary<String, CookAssetsStep::ProcessAssetFunc> CookAssetsStep::AssetProcessors;
void IBuildCache::InvalidateCacheShaders()
@@ -233,11 +237,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
LOG(Info, "{0} option has been modified.", TEXT("ShadersGenerateDebugData"));
invalidateShaders = true;
}
bool reverseZ = false;
#if REVERSE_Z
reverseZ = true;
#endif
if (reverseZ != Settings.Global.ShadersReverseZ)
if (REVERSE_Z != Settings.Global.ShadersReverseZ)
{
LOG(Info, "{0} option has been modified.", TEXT("ShadersReverseZ"));
invalidateShaders = true;
@@ -1085,6 +1085,7 @@ bool CookAssetsStep::Perform(CookingData& data)
{
cache.Settings.Global.ShadersNoOptimize = buildSettings->ShadersNoOptimize;
cache.Settings.Global.ShadersGenerateDebugData = buildSettings->ShadersGenerateDebugData;
cache.Settings.Global.ShadersReverseZ = REVERSE_Z;
cache.Settings.Global.StreamingSettingsAssetId = gameSettings->Streaming;
cache.Settings.Global.ShadersVersion = GPU_SHADER_CACHE_VERSION;
cache.Settings.Global.MaterialGraphVersion = MATERIAL_GRAPH_VERSION;
+1 -9
View File
@@ -139,19 +139,11 @@ namespace FlaxEditor.Gizmo
DrawSelectionDepth(context, renderContext.Task, customDepth);
_actors.Clear();
var near = renderContext.View.Near;
var far = renderContext.View.Far;
var projection = renderContext.View.Projection;
// Render outline
_material.SetParameterValue("OutlineColor0", _color0);
_material.SetParameterValue("OutlineColor1", _color1);
_material.SetParameterValue("CustomDepth", customDepth);
#if REVERSE_Z
_material.SetParameterValue("ViewInfo", new Float4(1.0f / projection.M11, 1.0f / projection.M22, -near / (far - near), (far * near) / (far - near) / far));
#else
_material.SetParameterValue("ViewInfo", new Float4(1.0f / projection.M11, 1.0f / projection.M22, far / (far - near), -(far * near) / (far - near) / far));
#endif
_material.SetParameterValue("ViewInfo", renderContext.View.ViewInfo);
Renderer.DrawPostFxMaterial(context, ref renderContext, _material, output, input.View());
// Cleanup
+24 -1
View File
@@ -629,6 +629,17 @@ public:
uint32 GetHash(const BlendingMode& key);
// Temp defines to put them into ComparisonFunc enum conditionally
#if REVERSE_Z
#define REVERSE_Z_COMP_DEFAULT 5
#define REVERSE_Z_COMP_DEFAULT_INV 2
#define REVERSE_Z_COMP_DEFAULT_EQ 7
#else
#define REVERSE_Z_COMP_DEFAULT 2
#define REVERSE_Z_COMP_DEFAULT_INV 5
#define REVERSE_Z_COMP_DEFAULT_EQ 4
#endif
/// <summary>
/// Comparison function modes
/// </summary>
@@ -651,9 +662,21 @@ API_ENUM() enum class ComparisonFunc : byte
// Always pass the comparison.
Always = 8,
API_ENUM(Attributes="HideInEditor") MAX
API_ENUM(Attributes="HideInEditor") MAX,
// Default comparision when rendering scene objects (Less or Greater).
API_ENUM(Attributes="HideInEditor") Default = REVERSE_Z_COMP_DEFAULT,
// Default comparision when rendering scene objects inverted (Greater or Less).
API_ENUM(Attributes="HideInEditor") DefaultInv = REVERSE_Z_COMP_DEFAULT_INV,
// Default comparision when rendering scene objects with equal (LessEqual or GreaterEqual).
API_ENUM(Attributes="HideInEditor") DefaultEqual = REVERSE_Z_COMP_DEFAULT_EQ,
};
// Remove temp defines to plug conditional value into the enum
#undef REVERSE_Z_COMP_DEFAULT
#undef REVERSE_Z_COMP_DEFAULT_INV
#undef REVERSE_Z_COMP_DEFAULT_EQ
/// <summary>
/// Rendering quality levels.
/// </summary>
+7 -7
View File
@@ -15,13 +15,13 @@
#endif
#if REVERSE_Z
#define GPU_DEPTH_MIN_VALUE 1.0f
#define GPU_DEPTH_MAX_VALUE 0.0f
#define GPU_DEPTH_BOUNDS_SWAP(min, max) max, min
#define GPU_DEPTH_RANGE_MIN 1.0f
#define GPU_DEPTH_RANGE_MAX 0.0f
#define GPU_DEPTH_RANGE_BOUNDS(min, max) max, min
#else
#define GPU_DEPTH_MIN_VALUE 0.0f
#define GPU_DEPTH_MAX_VALUE 1.0f
#define GPU_DEPTH_BOUNDS_SWAP(min, max) min, max
#define GPU_DEPTH_RANGE_MIN 0.0f
#define GPU_DEPTH_RANGE_MAX 1.0f
#define GPU_DEPTH_RANGE_BOUNDS(min, max) min, max
#endif
class GPUConstantBuffer;
@@ -218,7 +218,7 @@ public:
/// <param name="depthBuffer">The depth buffer to clear.</param>
/// <param name="depthValue">The clear depth value.</param>
/// <param name="stencilValue">The clear stencil value.</param>
API_FUNCTION() virtual void ClearDepth(GPUTextureView* depthBuffer, float depthValue = GPU_DEPTH_MAX_VALUE, uint8 stencilValue = 0) = 0;
API_FUNCTION() virtual void ClearDepth(GPUTextureView* depthBuffer, float depthValue = GPU_DEPTH_RANGE_MAX, uint8 stencilValue = 0) = 0;
/// <summary>
/// Clears an unordered access buffer with a float value.
+3 -15
View File
@@ -160,11 +160,7 @@ GPUPipelineState::Description GPUPipelineState::Description::Default =
true, // DepthWriteEnable
true, // DepthClipEnable
false, // DepthBoundsEnable
#if REVERSE_Z
ComparisonFunc::Greater, // DepthFunc
#else
ComparisonFunc::Less, // DepthFunc
#endif
ComparisonFunc::Default, // DepthFunc
false, // StencilEnable
0xff, // StencilReadMask
0xff, // StencilWriteMask
@@ -189,11 +185,7 @@ GPUPipelineState::Description GPUPipelineState::Description::DefaultNoDepth =
false, // DepthWriteEnable
false, // DepthClipEnable
false, // DepthBoundsEnable
#if REVERSE_Z
ComparisonFunc::Greater, // DepthFunc
#else
ComparisonFunc::Less, // DepthFunc
#endif
ComparisonFunc::Default, // DepthFunc
false, // StencilEnable
0xff, // StencilReadMask
0xff, // StencilWriteMask
@@ -218,11 +210,7 @@ GPUPipelineState::Description GPUPipelineState::Description::DefaultFullscreenTr
false, // DepthWriteEnable
false, // DepthClipEnable
false, // DepthBoundsEnable
#if REVERSE_Z
ComparisonFunc::Greater, // DepthFunc
#else
ComparisonFunc::Less, // DepthFunc
#endif
ComparisonFunc::Default, // DepthFunc
false, // StencilEnable
0xff, // StencilReadMask
0xff, // StencilWriteMask
@@ -182,11 +182,7 @@ bool DeferredMaterialShader::Load()
// Motion Vectors pass
psDesc.DepthWriteEnable = false;
psDesc.DepthEnable = true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::GreaterEqual;
#else
psDesc.DepthFunc = ComparisonFunc::LessEqual;
#endif
psDesc.DepthFunc = ComparisonFunc::DefaultEqual;
psDesc.VS = _shader->GetVS("VS");
psDesc.PS = _shader->GetPS("PS_MotionVectors");
_cache.MotionVectors.Init(psDesc);
@@ -204,11 +200,7 @@ bool DeferredMaterialShader::Load()
psDesc.DepthClipEnable = false;
psDesc.DepthWriteEnable = true;
psDesc.DepthEnable = true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Greater;
#else
psDesc.DepthFunc = ComparisonFunc::Less;
#endif
psDesc.DepthFunc = ComparisonFunc::Default;
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::None;
psDesc.HS = nullptr;
psDesc.DS = nullptr;
@@ -185,11 +185,7 @@ bool ForwardMaterialShader::Load()
psDesc.DepthClipEnable = false;
psDesc.DepthWriteEnable = true;
psDesc.DepthEnable = true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Greater;
#else
psDesc.DepthFunc = ComparisonFunc::Less;
#endif
psDesc.DepthFunc = ComparisonFunc::Default;
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::None;
psDesc.HS = nullptr;
psDesc.DS = nullptr;
@@ -189,11 +189,7 @@ bool TerrainMaterialShader::Load()
psDesc.DepthClipEnable = false;
psDesc.DepthWriteEnable = true;
psDesc.DepthEnable = true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Greater;
#else
psDesc.DepthFunc = ComparisonFunc::Less;
#endif
psDesc.DepthFunc = ComparisonFunc::Default;
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::None;
psDesc.HS = nullptr;
psDesc.DS = nullptr;
@@ -47,6 +47,8 @@ API_ENUM() enum class GPUSamplerCompareFunction
Never = 0,
/// <summary>If the source data is less than the destination data, the comparison passes.</summary>
Less = 1,
/// <summary>If the source data is greater than the destination data, the comparison passes.</summary>
Greater = 2,
API_ENUM(Attributes="HideInEditor") MAX
};
@@ -25,6 +25,7 @@
bool EnableNvapi = false;
#endif
#if COMPILE_WITH_AGS
#define AGS_EXCLUDE_DIRECTX_12
#include <ThirdParty/AGS/amd_ags.h>
#include "Engine/Engine/Globals.h"
#include "FlaxEngine.Gen.h"
@@ -757,7 +758,11 @@ bool GPUDeviceDX11::Init()
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
#if REVERSE_Z
samplerDesc.ComparisonFunc = D3D11_COMPARISON_GREATER;
#else
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
#endif
// Linear Clamp
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
@@ -77,6 +77,9 @@ bool GPUSamplerDX11::OnInit()
case GPUSamplerCompareFunction::Less:
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS;
break;
case GPUSamplerCompareFunction::Greater:
samplerDesc.ComparisonFunc = D3D11_COMPARISON_GREATER;
break;
default:
return true;
}
@@ -155,10 +155,15 @@ RootSignatureDX12::RootSignatureDX12()
InitSampler(2, D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_WRAP);
// Point Wrap
InitSampler(3, D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_WRAP);
#if REVERSE_Z
auto comparisionFunc = D3D12_COMPARISON_FUNC_GREATER;
#else
auto comparisionFunc = D3D12_COMPARISON_FUNC_LESS;
#endif
// Shadow
InitSampler(4, D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_COMPARISON_FUNC_LESS_EQUAL);
InitSampler(4, D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, comparisionFunc);
// Shadow PCF
InitSampler(5, D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_COMPARISON_FUNC_LESS_EQUAL);
InitSampler(5, D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, comparisionFunc);
// Init
_desc.NumParameters = ARRAY_COUNT(_parameters);
@@ -77,6 +77,9 @@ bool GPUSamplerDX12::OnInit()
case GPUSamplerCompareFunction::Less:
samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_LESS;
break;
case GPUSamplerCompareFunction::Greater:
samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_GREATER;
break;
default:
return true;
}
@@ -136,7 +136,7 @@ bool GPUTextureDX12::OnInit()
else if (useDSV)
{
clearValue.Format = _dxgiFormatDSV;
clearValue.DepthStencil.Depth = 1.0f;
clearValue.DepthStencil.Depth = GPU_DEPTH_RANGE_MAX;
clearValue.DepthStencil.Stencil = 0;
clearValuePtr = &clearValue;
}
@@ -797,7 +797,7 @@ HelperResourcesVulkan::HelperResourcesVulkan(GPUDeviceVulkan* device)
Platform::MemoryClear(_staticSamplers, sizeof(_staticSamplers));
}
void InitSampler(VkSamplerCreateInfo& createInfo, bool supportsMirrorClampToEdge, GPUSamplerFilter filter, GPUSamplerAddressMode addressU, GPUSamplerAddressMode addressV, GPUSamplerAddressMode addressW, GPUSamplerCompareFunction compareFunction)
void InitSampler(VkSamplerCreateInfo& createInfo, bool supportsMirrorClampToEdge, GPUSamplerFilter filter, GPUSamplerAddressMode addressU, GPUSamplerAddressMode addressV, GPUSamplerAddressMode addressW, GPUSamplerCompareFunction compareFunction = GPUSamplerCompareFunction::Never)
{
createInfo.magFilter = RenderToolsVulkan::ToVulkanMagFilterMode(filter);
createInfo.minFilter = RenderToolsVulkan::ToVulkanMinFilterMode(filter);
@@ -826,27 +826,33 @@ VkSampler* HelperResourcesVulkan::GetStaticSamplers()
createInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
// Linear Clamp
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Never);
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp);
VALIDATE_VULKAN_RESULT(vkCreateSampler(_device->Device, &createInfo, nullptr, &_staticSamplers[0]));
// Point Clamp
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Never);
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp);
VALIDATE_VULKAN_RESULT(vkCreateSampler(_device->Device, &createInfo, nullptr, &_staticSamplers[1]));
// Linear Wrap
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap, GPUSamplerCompareFunction::Never);
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap);
VALIDATE_VULKAN_RESULT(vkCreateSampler(_device->Device, &createInfo, nullptr, &_staticSamplers[2]));
// Point Wrap
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Point, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap, GPUSamplerCompareFunction::Never);
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Point, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap, GPUSamplerAddressMode::Wrap);
VALIDATE_VULKAN_RESULT(vkCreateSampler(_device->Device, &createInfo, nullptr, &_staticSamplers[3]));
#if REVERSE_Z
auto comparisionFunc = GPUSamplerCompareFunction::Greater;
#else
auto comparisionFunc = GPUSamplerCompareFunction::Less;
#endif
// Shadow
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Less);
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, comparisionFunc);
VALIDATE_VULKAN_RESULT(vkCreateSampler(_device->Device, &createInfo, nullptr, &_staticSamplers[4]));
// Shadow PCF
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Less);
InitSampler(createInfo, supportsMirrorClampToEdge, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, GPUSamplerAddressMode::Clamp, comparisionFunc);
VALIDATE_VULKAN_RESULT(vkCreateSampler(_device->Device, &createInfo, nullptr, &_staticSamplers[5]));
}
return _staticSamplers;
@@ -283,11 +283,14 @@ public:
VkCompareOp result;
switch (samplerComparisonFunction)
{
case GPUSamplerCompareFunction::Never:
result = VK_COMPARE_OP_NEVER;
break;
case GPUSamplerCompareFunction::Less:
result = VK_COMPARE_OP_LESS;
break;
case GPUSamplerCompareFunction::Never:
result = VK_COMPARE_OP_NEVER;
case GPUSamplerCompareFunction::Greater:
result = VK_COMPARE_OP_GREATER;
break;
default:
CRASH;
@@ -636,18 +636,22 @@ bool GPUDeviceWebGPU::Init()
// Create default resources
auto samplerDesc = GPUSamplerDescription::New();
#define INIT_SAMPLER(slot, filter, addressMode, compare) \
#define INIT_SAMPLER(slot, filter, addressMode) \
DefaultSamplers[slot] = New<GPUSamplerWebGPU>(this); \
samplerDesc.Filter = filter; \
samplerDesc.AddressU = samplerDesc.AddressV = samplerDesc.AddressW = addressMode; \
samplerDesc.ComparisonFunction = compare; \
DefaultSamplers[slot]->Init(samplerDesc)
INIT_SAMPLER(0, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Never);
INIT_SAMPLER(1, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Never);
INIT_SAMPLER(2, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Wrap, GPUSamplerCompareFunction::Never);
INIT_SAMPLER(3, GPUSamplerFilter::Point, GPUSamplerAddressMode::Wrap, GPUSamplerCompareFunction::Never);
INIT_SAMPLER(4, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Less);
INIT_SAMPLER(5, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Less);
INIT_SAMPLER(0, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp);
INIT_SAMPLER(1, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp);
INIT_SAMPLER(2, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Wrap);
INIT_SAMPLER(3, GPUSamplerFilter::Point, GPUSamplerAddressMode::Wrap);
#if REVERSE_Z
samplerDesc.ComparisonFunction = GPUSamplerCompareFunction::Greater;
#else
samplerDesc.ComparisonFunction = GPUSamplerCompareFunction::Less;
#endif
INIT_SAMPLER(4, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp);
INIT_SAMPLER(5, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp);
#undef INIT_SAMPLER
{
WGPUBufferDescriptor bufferDesc = WGPU_BUFFER_DESCRIPTOR_INIT;
@@ -27,6 +27,8 @@ WGPUCompareFunction ToCompareFunction(GPUSamplerCompareFunction value)
return WGPUCompareFunction_Undefined; // Disabled comparision
case GPUSamplerCompareFunction::Less:
return WGPUCompareFunction_Less;
case GPUSamplerCompareFunction::Greater:
return WGPUCompareFunction_Greater;
default:
return WGPUCompareFunction_Undefined;
}
@@ -536,7 +536,7 @@ void AmbientOcclusionPass::Render(RenderContext& renderContext)
}
// Apply
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(GPU_DEPTH_MIN_VALUE, RenderTools::GetDepthBounds(renderContext.View, aoSettings.FadeOutDistance, false)));
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(GPU_DEPTH_RANGE_MIN, RenderTools::GetDepthBounds(renderContext.View, aoSettings.FadeOutDistance, false)));
context->BindSR(SSAO_TEXTURE_SLOT0, m_finalResults->ViewArray());
context->SetViewportAndScissors((float)m_sizeX, (float)m_sizeY);
context->SetState(settings.SkipHalfPixels ? _psApplyHalf : _psApply);
+6 -14
View File
@@ -90,11 +90,7 @@ bool LightPass::setupResources()
psDesc.CullMode = CullMode::Normal;
if (_psLightLocal.Create(psDesc, shader, "PS_LocalLight"))
return true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Less;
#else
psDesc.DepthFunc = ComparisonFunc::Greater;
#endif
psDesc.DepthFunc = ComparisonFunc::DefaultInv;
psDesc.CullMode = CullMode::Inverted;
if (_psLightLocalInside.Create(psDesc, shader, "PS_LocalLight"))
return true;
@@ -111,11 +107,7 @@ bool LightPass::setupResources()
psDesc.CullMode = CullMode::Normal;
if (_psLightSky->Init(psDesc))
return true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Less;
#else
psDesc.DepthFunc = ComparisonFunc::Greater;
#endif
psDesc.DepthFunc = ComparisonFunc::DefaultInv;
psDesc.CullMode = CullMode::Inverted;
if (_psLightSkyInside->Init(psDesc))
return true;
@@ -283,7 +275,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
if (_depthBounds)
{
Float2 minMaxDepth = RenderTools::GetDepthBounds(view, BoundingSphere(light.Position, light.Radius));
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(minMaxDepth.X, minMaxDepth.Y));
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(minMaxDepth.X, minMaxDepth.Y));
}
context->UpdateCB(cb0, &perLight);
context->BindCB(0, cb0);
@@ -331,7 +323,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
if (_depthBounds)
{
Float2 minMaxDepth = RenderTools::GetDepthBounds(view, BoundingSphere(light.Position, light.Radius));
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(minMaxDepth.X, minMaxDepth.Y));
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(minMaxDepth.X, minMaxDepth.Y));
}
context->UpdateCB(cb0, &perLight);
context->BindCB(0, cb0);
@@ -365,7 +357,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
// Calculate lighting
if (_depthBounds)
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(GPU_DEPTH_MIN_VALUE, RenderTools::DepthBoundMaxBackground));
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(GPU_DEPTH_RANGE_MIN, RenderTools::DepthBoundMaxBackground));
context->UpdateCB(cb0, &perLight);
context->BindCB(0, cb0);
context->BindCB(1, cb1);
@@ -398,7 +390,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
if (_depthBounds)
{
Float2 minMaxDepth = RenderTools::GetDepthBounds(view, BoundingSphere(light.Position, light.Radius));
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(minMaxDepth.X, minMaxDepth.Y));
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(minMaxDepth.X, minMaxDepth.Y));
}
context->UpdateCB(cb0, &perLight);
context->BindCB(0, cb0);
+2 -2
View File
@@ -347,7 +347,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
// Setup depth bounds (if device supports it)
if (_depthBounds)
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(minMaxDepth.X, minMaxDepth.Y));
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(minMaxDepth.X, minMaxDepth.Y));
// Pack probe properties buffer
probe.SetShaderData(data.PData);
@@ -417,7 +417,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
if (_depthBounds)
{
context->SetRenderTarget(depthBufferRTV, lightBuffer);
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(GPU_DEPTH_MIN_VALUE, RenderTools::DepthBoundMaxBackground));
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(GPU_DEPTH_RANGE_MIN, RenderTools::DepthBoundMaxBackground));
}
else
context->SetRenderTarget(lightBuffer);
+13 -21
View File
@@ -536,11 +536,7 @@ bool ShadowsPass::setupResources()
psDesc.CullMode = CullMode::Normal;
if (_psShadowPoint.Create(psDesc, shader, psLocalLight))
return true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Less;
#else
psDesc.DepthFunc = ComparisonFunc::Greater;
#endif
psDesc.DepthFunc = ComparisonFunc::DefaultInv;
psDesc.CullMode = CullMode::Inverted;
if (_psShadowPointInside.Create(psDesc, shader, psLocalLight))
return true;
@@ -555,11 +551,7 @@ bool ShadowsPass::setupResources()
psDesc.CullMode = CullMode::Normal;
if (_psShadowSpot.Create(psDesc, shader, psLocalLight, 8))
return true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Less;
#else
psDesc.DepthFunc = ComparisonFunc::Greater;
#endif
psDesc.DepthFunc = ComparisonFunc::DefaultInv;
psDesc.CullMode = CullMode::Inverted;
if (_psShadowSpotInside.Create(psDesc, shader, psLocalLight, 8))
return true;
@@ -967,14 +959,14 @@ void ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& render
{
Float3 frustumCornersCs[8] =
{
Float3(-1.0f, 1.0f, 0.0f),
Float3(1.0f, 1.0f, 0.0f),
Float3(1.0f, -1.0f, 0.0f),
Float3(-1.0f, -1.0f, 0.0f),
Float3(-1.0f, 1.0f, 1.0f),
Float3(1.0f, 1.0f, 1.0f),
Float3(1.0f, -1.0f, 1.0f),
Float3(-1.0f, -1.0f, 1.0f),
Float3(-1.0f, 1.0f, GPU_DEPTH_RANGE_MIN),
Float3(1.0f, 1.0f, GPU_DEPTH_RANGE_MIN),
Float3(1.0f, -1.0f, GPU_DEPTH_RANGE_MIN),
Float3(-1.0f, -1.0f, GPU_DEPTH_RANGE_MIN),
Float3(-1.0f, 1.0f, GPU_DEPTH_RANGE_MAX),
Float3(1.0f, 1.0f, GPU_DEPTH_RANGE_MAX),
Float3(1.0f, -1.0f, GPU_DEPTH_RANGE_MAX),
Float3(-1.0f, -1.0f, GPU_DEPTH_RANGE_MAX),
};
Matrix invProjectionMatrix;
Matrix::Invert(renderContext.View.NonJitteredProjection, invProjectionMatrix);
@@ -1147,7 +1139,7 @@ void ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& render
void ShadowsPass::ClearShadowMapTile(GPUContext* context, GPUConstantBuffer* quadShaderCB, QuadShaderData& quadShaderData) const
{
// Color.r is used by PS_DepthClear in Quad shader to clear depth
quadShaderData.Color = GPU_DEPTH_MAX_VALUE;
quadShaderData.Color = GPU_DEPTH_RANGE_MAX;
context->UpdateCB(quadShaderCB, &quadShaderData);
context->BindCB(0, quadShaderCB);
@@ -1749,8 +1741,8 @@ void ShadowsPass::RenderShadowMask(RenderContextBatch& renderContextBatch, Rende
if (light.IsPointLight || light.IsSpotLight)
minMaxDepth = RenderTools::GetDepthBounds(view, BoundingSphere(light.Position, ((RenderLocalLightData&)light).Radius));
else //if (light.IsDirectionalLight)
minMaxDepth = Float2(GPU_DEPTH_MIN_VALUE, RenderTools::DepthBoundMaxBackground);
context->SetDepthBounds(GPU_DEPTH_BOUNDS_SWAP(minMaxDepth.X, minMaxDepth.Y));
minMaxDepth = Float2(GPU_DEPTH_RANGE_MIN, RenderTools::DepthBoundMaxBackground);
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(minMaxDepth.X, minMaxDepth.Y));
}
if (light.IsPointLight)
{
+2 -2
View File
@@ -60,7 +60,7 @@ RenderCacheVSOutput VS_RenderCacheModel(ModelInput input)
float2 lightmapUV = input.LightmapUV * LightmapArea.zw + LightmapArea.xy;
lightmapUV.y = 1.0 - lightmapUV.y;
lightmapUV.xy = lightmapUV.xy * 2.0 - 1.0;
output.Position = float4(lightmapUV, 0, 1);
output.Position = float4(lightmapUV, DEPTH_RANGE_MIN, 1);
return output;
}
@@ -129,7 +129,7 @@ RenderCacheVSOutput VS_RenderCacheTerrain(TerrainVertexInput input)
float2 lightmapUV = input.TexCoord * LightmapArea.zw + LightmapArea.xy;
lightmapUV.y = 1.0 - lightmapUV.y;
lightmapUV.xy = lightmapUV.xy * 2.0 - 1.0;
output.Position = float4(lightmapUV, 0, 1);
output.Position = float4(lightmapUV, DEPTH_RANGE_MIN, 1);
return output;
}
+1 -1
View File
@@ -317,7 +317,7 @@ Quad_VS2GS VS_WriteToSlice(float2 position : POSITION0, float2 texCoord : TEXCOO
#if VULKAN
position.y = position.y * -1.0f;
#endif
output.Vertex.Position = float4(position, 0, 1);
output.Vertex.Position = float4(position, DEPTH_RANGE_MIN, 1);
output.Vertex.TexCoord = texCoord;
output.LayerIndex = layerIndex;
return output;
+10 -6
View File
@@ -25,13 +25,17 @@
#define REVERSE_Z 0
#endif
#if REVERSE_Z
#define DEPTH_MIN_VALUE 1
#define DEPTH_MAX_VALUE 0
//#define DEPTH_CMP(l, r) l > r
#define DEPTH_RANGE_MIN 1
#define DEPTH_RANGE_MAX 0
#define DEPTH_CMP(l, r) (l > r)
#define DEPTH_DIFF(l, r) (r - l)
#define DEPTH_01(d) (1 - d)
#else
#define DEPTH_MIN_VALUE 0
#define DEPTH_MAX_VALUE 1
//#define DEPTH_CMP(l, r) l < r
#define DEPTH_RANGE_MIN 0
#define DEPTH_RANGE_MAX 1
#define DEPTH_CMP(l, r) (l < r)
#define DEPTH_DIFF(l, r) (l - r)
#define DEPTH_01(d) (d)
#endif
// Feature levels
+1 -5
View File
@@ -41,11 +41,7 @@ float4 PS(VS2PS input) : SV_Target
{
float sceneDepthDeviceZ = SceneDepthTexture.Load(int3(input.Position.xy, 0)).r;
float interpolatedDeviceZ = input.Position.z;
#if REVERSE_Z
clip(interpolatedDeviceZ - sceneDepthDeviceZ);
#else
clip(sceneDepthDeviceZ - interpolatedDeviceZ);
#endif
clip(DEPTH_DIFF(sceneDepthDeviceZ, interpolatedDeviceZ));
}
#endif
+1 -1
View File
@@ -59,7 +59,7 @@ float4 PS_DebugView(Quad_VS2PS input) : SV_Target
{
case View_Mode_Diffuse: result = gBuffer.Color; break;
case View_Mode_Normals: result = gBuffer.Normal * 0.5 + 0.5; break;
case View_Mode_Depth: result = gBuffer.ViewPos.z / GBuffer.ViewFar; break;
case View_Mode_Depth: result = pow(gBuffer.ViewPos.z / GBuffer.ViewFar, 0.6); break;
case View_Mode_AmbientOcclusion: result = gBuffer.AO; break;
case View_Mode_Metalness: result = gBuffer.Metalness; break;
case View_Mode_Rougness: result = gBuffer.Roughness; break;
+4 -3
View File
@@ -147,7 +147,7 @@ float4 SampleGlobalSurfaceAtlasTile(const GlobalSurfaceAtlasData data, GlobalSur
// Calculate bilinear weights
float2 bilinearWeightsUV = frac(atlasUV * data.Resolution + 0.5f);
float4 bilinearWeights;
bilinearWeights.x = (1.0 - bilinearWeightsUV.x) * (bilinearWeightsUV.y);
bilinearWeights.x = (1 - bilinearWeightsUV.x) * (bilinearWeightsUV.y);
bilinearWeights.y = (bilinearWeightsUV.x) * (bilinearWeightsUV.y);
bilinearWeights.z = (bilinearWeightsUV.x) * (1 - bilinearWeightsUV.y);
bilinearWeights.w = (1 - bilinearWeightsUV.x) * (1 - bilinearWeightsUV.y);
@@ -159,8 +159,9 @@ float4 SampleGlobalSurfaceAtlasTile(const GlobalSurfaceAtlasData data, GlobalSur
UNROLL
for (uint i = 0; i < 4; i++)
{
depthVisibility[i] = 1.0f - saturate((abs(tileDepth - tileZ[i]) - depthThreshold) / (0.5f * depthThreshold));
if (tileZ[i] >= 1.0f)
float z = DEPTH_01(tileZ[i]);
depthVisibility[i] = 1.0f - saturate((abs(tileDepth - z) - depthThreshold) / (0.5f * depthThreshold));
if (z >= 1.0f)
depthVisibility[i] = 0.0f;
}
float sampleWeight = dot(depthVisibility, bilinearWeights);
+2 -2
View File
@@ -43,7 +43,7 @@ META_VS(true, FEATURE_LEVEL_SM5)
AtlasVertexOutput VS_Atlas(AtlasVertexInput input)
{
AtlasVertexOutput output;
output.Position = float4(input.Position, 1, 1);
output.Position = float4(input.Position, DEPTH_RANGE_MAX, 1);
output.TileUV = input.TileUV;
output.TileAddress = input.TileAddress;
return output;
@@ -143,7 +143,7 @@ float4 PS_Lighting(AtlasVertexOutput input) : SV_Target
}
// Reconstruct world-space position manually (from uv+depth within a tile)
float tileDepth = SampleZ(atlasUV);
float tileDepth = DEPTH_01(SampleZ(atlasUV));
float3 tileSpacePos = float3(input.TileUV.x - 0.5f, 0.5f - input.TileUV.y, tileDepth);
float3 gBufferTilePos = tileSpacePos * tile.ViewBoundsSize;
float4x4 tileLocalToWorld = Inverse(tile.WorldToLocal);
+2 -2
View File
@@ -31,7 +31,7 @@ VS2PS VS(Render2DVertex input)
if ((int)input.CustomDataAndClipOrigin.y & RENDER2D_FEATURE_VERTEX_SNAPPING)
input.Position = (float2)(int2)input.Position;
output.Position = PROJECT_POINT(float4(input.Position, 0, 1), ViewProjection);
output.Position = PROJECT_POINT(float4(input.Position, DEPTH_RANGE_MIN, 1), ViewProjection);
output.Color = input.Color;
output.TexCoord = input.TexCoord;
output.ClipOriginAndPos = float4(input.CustomDataAndClipOrigin.zw, input.Position);
@@ -126,7 +126,7 @@ float4 PS_Downscale(Quad_VS2PS input) : SV_Target0
{
float2 boundsPos = input.TexCoord * Bounds.zw + Bounds.xy;
float4 clipPos = PROJECT_POINT(float4(boundsPos, 0, 1), ViewProjection);
float4 clipPos = PROJECT_POINT(float4(boundsPos, DEPTH_RANGE_MIN, 1), ViewProjection);
clipPos.xy /= clipPos.w;
float2 uvPos = ClipToUv(clipPos.xy);
+8
View File
@@ -28,11 +28,19 @@ float PS_HalfDepth(Quad_VS2PS input)
// Load 4 depth values (2x2 quad)
float4 depths = TextureGatherDepth(Input, input.TexCoord);
#if REVERSE_Z
#if HZB_CLOSEST
return max(depths.x, max(depths.y, max(depths.z, depths.w)));
#else
return min(depths.x, min(depths.y, min(depths.z, depths.w)));
#endif
#else
#if HZB_CLOSEST
return min(depths.x, min(depths.y, min(depths.z, depths.w)));
#else
return max(depths.x, max(depths.y, max(depths.z, depths.w)));
#endif
#endif
}
// Pixel Shader for 5-tap gaussian blur
+2 -2
View File
@@ -19,7 +19,7 @@ META_VS(true, FEATURE_LEVEL_ES2)
Quad_VS2PS VS(float2 Position : POSITION0, float2 TexCoord : TEXCOORD0)
{
Quad_VS2PS output;
output.Position = float4(Position, 0, 1);
output.Position = float4(Position, DEPTH_RANGE_MIN, 1);
output.TexCoord = TexCoord;
return output;
}
@@ -29,7 +29,7 @@ META_VS(true, FEATURE_LEVEL_ES2)
MaterialVertexOutput VS_PostFx(float2 Position : POSITION0, float2 TexCoord : TEXCOORD0)
{
MaterialVertexOutput output;
output.Position = float4(Position, 0, 1);
output.Position = float4(Position, DEPTH_RANGE_MIN, 1);
output.WorldPosition = output.Position.xyz;
output.TexCoord = TexCoord;
return output;
+3 -3
View File
@@ -1127,7 +1127,7 @@ META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VaryingsEdge VS_Edge(float2 Position : POSITION0, float2 TexCoord : TEXCOORD0)
{
VaryingsEdge output;
output.Position = float4(Position, 0, 1);
output.Position = float4(Position, DEPTH_RANGE_MIN, 1);
output.TexCoord = TexCoord;
SMAAEdgeDetectionVS(TexCoord, output.Offsets);
return output;
@@ -1162,7 +1162,7 @@ META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VaryingsBlend VS_Blend(float2 Position : POSITION0, float2 TexCoord : TEXCOORD0)
{
VaryingsBlend output;
output.Position = float4(Position.xy, 0, 1);
output.Position = float4(Position.xy, DEPTH_RANGE_MIN, 1);
output.TexCoord = TexCoord;
output.PixCoord = output.TexCoord * SMAA_RT_METRICS.zw;
SMAABlendingWeightCalculationVS(TexCoord, output.PixCoord, output.Offsets);
@@ -1204,7 +1204,7 @@ META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VaryingsNeighbor VS_Neighbor(float2 Position : POSITION0, float2 TexCoord : TEXCOORD0)
{
VaryingsNeighbor output;
output.Position = float4(Position, 0, 1);
output.Position = float4(Position, DEPTH_RANGE_MIN, 1);
output.TexCoord = TexCoord;
SMAANeighborhoodBlendingVS(TexCoord, output.Offset);
return output;
+4 -5
View File
@@ -6,6 +6,9 @@
#include "./Flax/MonteCarlo.hlsl"
#include "./Flax/GBufferCommon.hlsl"
#if SSR_USE_HZB
#if REVERSE_Z
#define FFX_SSSR_INVERTED_DEPTH_RANGE 1
#endif
#include "./FlaxThirdParty/FidelityFX/ffx_sssr.h"
#endif
@@ -117,11 +120,7 @@ float3 TraceScreenSpaceReflection(
{
// Sample depth buffer and calculate depth difference
float currSample = SAMPLE_RT_DEPTH(depthBuffer, currOffset.xy);
#if FLAX_REVERSE_Z
depthDiff = currSample - currOffset.z;
#else
depthDiff = currOffset.z - currSample;
#endif
float depthDiff = DEPTH_DIFF(currOffset.z, currSample);
// Check intersection
if (depthDiff >= 0)
+1 -8
View File
@@ -74,15 +74,8 @@ float3 GetShadowPositionOffset(float offsetScale, float NoL, float3 normal)
float CalculateSubsurfaceOcclusion(float opacity, float sceneDepth, float shadowMapDepth)
{
// `sceneDepth` and `shadowMapDepth`are raw depths, so we have to flip them when reverse-z is enabled
#if REVERSE_Z
float thickness = max(shadowMapDepth - sceneDepth, 0);
#else
float thickness = max(sceneDepth - shadowMapDepth, 0);
#endif
float thickness = max(DEPTH_DIFF(sceneDepth, shadowMapDepth), 0);
float occlusion = 1 - saturate(thickness * lerp(1.0f, 100.0f, opacity));
#if REVERSE_Z
return shadowMapDepth < 0.01f ? 1 : occlusion;
#else
+24 -6
View File
@@ -24,8 +24,8 @@
#define SAMPLE_SHADOW_MAP(shadowMap, shadowUV, sceneDepth) shadowMap.SampleCmpLevelZero(ShadowSamplerLinear, shadowUV, sceneDepth)
#define SAMPLE_SHADOW_MAP_OFFSET(shadowMap, shadowUV, texelOffset, sceneDepth) shadowMap.SampleCmpLevelZero(ShadowSamplerLinear, shadowUV, sceneDepth, texelOffset)
#else
#define SAMPLE_SHADOW_MAP(shadowMap, shadowUV, sceneDepth) (sceneDepth < shadowMap.SampleLevel(SamplerLinearClamp, shadowUV, 0).r)
#define SAMPLE_SHADOW_MAP_OFFSET(shadowMap, shadowUV, texelOffset, sceneDepth) (sceneDepth < shadowMap.SampleLevel(SamplerLinearClamp, shadowUV, 0, texelOffset).r)
#define SAMPLE_SHADOW_MAP(shadowMap, shadowUV, sceneDepth) DEPTH_CMP(sceneDepth, shadowMap.SampleLevel(SamplerLinearClamp, shadowUV, 0).r)
#define SAMPLE_SHADOW_MAP_OFFSET(shadowMap, shadowUV, texelOffset, sceneDepth) (sceneDepth, shadowMap.SampleLevel(SamplerLinearClamp, shadowUV, 0, texelOffset).r)
#endif
#if defined(WGSL)
#define LOAD_SHADOW_MAP(shadowMap, shadowUV) SAMPLE_RT_DEPTH(shadowMap, shadowUV)
@@ -60,7 +60,11 @@ float2 GetLightShadowAtlasUV(ShadowData shadow, ShadowTileData shadowTile, float
{
// Project into shadow space (WorldToShadow is pre-multiplied to convert Clip Space to UV Space)
shadowPosition = mul(float4(samplePosition, 1.0f), shadowTile.WorldToShadow);
#if REVERSE_Z
shadowPosition.z += shadow.Bias;
#else
shadowPosition.z -= shadow.Bias;
#endif
shadowPosition.xyz /= shadowPosition.w;
// UV Space -> Atlas Tile UV Space
@@ -311,7 +315,12 @@ float SampleShadowMapPCSS(Texture2D<float> shadowMap, float2 shadowMapUV, float
sincos(rotationAngle, rotation.x, rotation.y);
// Search blockers
#if REVERSE_Z
float sceneDepthRev = 1 - sceneDepth;
float searchRadius = sourceAngle * saturate(sceneDepthRev - 0.02f) / sceneDepthRev;
#else
float searchRadius = sourceAngle * saturate(sceneDepth - 0.02f) / sceneDepth;
#endif
searchRadius = max(searchRadius, minRadius);
uint blockers = 0;
float avgBlockerDistance = 0.0f;
@@ -322,7 +331,7 @@ float SampleShadowMapPCSS(Texture2D<float> shadowMap, float2 shadowMapUV, float
offset = shadowMapUV + offset;
offset = clamp(offset, uvMin, uvMax);
float shadowMapDepth = LOAD_SHADOW_MAP(shadowMap, offset);
if (shadowMapDepth < sceneDepth)
if (DEPTH_CMP(shadowMapDepth, sceneDepth))
{
blockers++;
avgBlockerDistance += shadowMapDepth;
@@ -333,9 +342,14 @@ float SampleShadowMapPCSS(Texture2D<float> shadowMap, float2 shadowMapUV, float
avgBlockerDistance /= blockers;
// Calculate penumbra size
float penumbra = max(sceneDepth - avgBlockerDistance, 0.0);
#if defined(VULKAN)
sceneDepth *= lerp(1, 0.985f, saturate(penumbra * 4.0f)); // Fix shadow bias issues on Vulkan
float penumbra = max(DEPTH_DIFF(sceneDepth, avgBlockerDistance), 0.0);
#if VULKAN
// Fix shadow bias issues on Vulkan
#if REVERSE_Z
sceneDepth *= lerp(1, 1.025f, saturate(penumbra * 4.0f));
#else
sceneDepth *= lerp(1, 0.985f, saturate(penumbra * 4.0f));
#endif
#endif
float filterRadius = penumbra * sourceAngle;
filterRadius = max(filterRadius, minRadius); // Don't use too small filter near blockers to avoid jagged edges
@@ -348,7 +362,11 @@ float SampleShadowMapPCSS(Texture2D<float> shadowMap, float2 shadowMapUV, float
offset = SampleShadowPCSSRotate(offset, rotation);
offset = shadowMapUV + offset;
offset = clamp(offset, uvMin, uvMax);
#if REVERSE_Z
shadow += LOAD_SHADOW_MAP(shadowMap, offset) < sceneDepth;
#else
shadow += LOAD_SHADOW_MAP(shadowMap, offset) > sceneDepth;
#endif
}
return shadow / (float)SHADOWS_PCSS_SAMPLES;
}
+6 -1
View File
@@ -111,7 +111,12 @@ float3 FFX_SSSR_HierarchicalRaymarch(Texture2D depthBuffer, uint hzbMips, float
while (i < max_traversal_intersections && current_mip >= most_detailed_mip) {
float2 current_mip_position = current_mip_resolution * position.xy;
float surface_z = depthBuffer.Load(int3(current_mip_position, current_mip)).x;
if (position.z - surface_z > depthDiffError) overDiffError++; // Count number of times we were under the depth by more than the allowed error
#ifdef FFX_SSSR_INVERTED_DEPTH_RANGE
// Count number of times we were under the depth by more than the allowed error
if (surface_z - position.z > depthDiffError) overDiffError++;
#else
if (position.z - surface_z > depthDiffError) overDiffError++;
#endif
bool skipped_tile = FFX_SSSR_AdvanceRay(origin, direction, inv_direction, current_mip_position, current_mip_resolution_inv, floor_offset, uv_offset, surface_z, position, current_t);
++i;
if (!skipped_tile || current_mip < (int)hzbMips) // Never go too low depth resolution to avoid blocky artifacts
@@ -475,8 +475,8 @@ namespace Flax.Build.Bindings
// Check for end or next param
token = context.Tokenizer.ExpectAnyTokens(new[] { TokenType.Comma, TokenType.RightParent });
if (currentParam.DefaultValue != null && context.PreprocessorDefines.TryGetValue(currentParam.DefaultValue, out var defaultValueMacroValue))
currentParam.DefaultValue = defaultValueMacroValue; // Default value wrapped into preprocessor define (can be conditional)
if (currentParam.DefaultValue != null && context.PreprocessorDefines.TryGetValue(currentParam.DefaultValue, out var define))
currentParam.DefaultValue = define; // Default value wrapped into preprocessor define (can be conditional)
if (token.Type == TokenType.Comma)
{
parameters.Add(currentParam);
@@ -1218,6 +1218,7 @@ namespace Flax.Build.Bindings
token = context.Tokenizer.NextToken();
if (token.Type == TokenType.Equal)
{
// Rean enum value
token = context.Tokenizer.NextToken();
entry.Value = string.Empty;
while (token.Type != TokenType.EndOfFile &&
@@ -1227,6 +1228,10 @@ namespace Flax.Build.Bindings
entry.Value += token.Value;
token = context.Tokenizer.NextToken(true);
}
// Optionally swap with preprocessor define
if (context.PreprocessorDefines.TryGetValue(entry.Value, out var define))
entry.Value = define;
}
context.Tokenizer.PreviousToken();