Fix various rendering elements with Reversed Z enabled and simplify code
#2684
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user