diff --git a/Source/Engine/Core/Config.h b/Source/Engine/Core/Config.h index dc4d76290..d2b4d666d 100644 --- a/Source/Engine/Core/Config.h +++ b/Source/Engine/Core/Config.h @@ -41,6 +41,9 @@ // Enable/disable assertion for Engine low layers #define ENABLE_ASSERTION_LOW_LAYERS ENABLE_ASSERTION && (BUILD_DEBUG || FLAX_TESTS) +// Enable reverse z +#define FLAX_REVERSE_Z 1 + // Scripting API defines (see C++ scripting documentation for more info) #define API_ENUM(...) #define API_CLASS(...) diff --git a/Source/Engine/Graphics/RenderView.cpp b/Source/Engine/Graphics/RenderView.cpp index e03a22b3d..01b2219f2 100644 --- a/Source/Engine/Graphics/RenderView.cpp +++ b/Source/Engine/Graphics/RenderView.cpp @@ -64,7 +64,11 @@ void RenderView::Prepare(RenderContext& renderContext) void RenderView::PrepareCache(const RenderContext& renderContext, float width, float height, const Float2& temporalAAJitter, const RenderView* mainView) { // The same format used by the Flax common shaders and postFx materials - ViewInfo = Float4(1.0f / Projection.M11, 1.0f / Projection.M22, Near / (Far - Near), (Far * Near) / (Far - Near) / Far); +#if FLAX_REVERSE_Z + ViewInfo = Float4(1.0f / Projection.M11, 1.0f / Projection.M22, -Near / (Far - Near), (Far * Near) / (Far - Near) / Far); +#else + ViewInfo = Float4(1.0f / Projection.M11, 1.0f / Projection.M22, Far / (Far - Near), -(Far * Near) / (Far - Near) / Far); +#endif ScreenSize = Float4(width, height, 1.0f / width, 1.0f / height); TemporalAAJitter.Z = TemporalAAJitter.X; diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp index cf0df0f78..04dbbbc32 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp @@ -840,7 +840,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) " uint2 pixel = uv * ScreenSize.xy;\n" " float depth = {11}.Load(uint3(pixel, 0)).r;\n" - " float linearDepth = ViewInfo.w / (depth + ViewInfo.z) * ViewFar;\n" + " float linearDepth = ViewInfo.w / (depth - ViewInfo.z) * ViewFar;\n" " if (viewPos.z > linearDepth - {5} && viewPos.z < linearDepth + {5} + {10})\n" " {{\n" diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp index 808de0f7e..bd8777f64 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp @@ -144,7 +144,7 @@ void ParticleEmitterGPUGenerator::sampleSceneDepth(Node* caller, Value& value, B void ParticleEmitterGPUGenerator::linearizeSceneDepth(Node* caller, const Value& depth, Value& value) { - value = writeLocal(VariantType::Float, String::Format(TEXT("ViewInfo.w / ({0}.x + ViewInfo.z)"), depth.Value), caller); + value = writeLocal(VariantType::Float, String::Format(TEXT("ViewInfo.w / ({0}.x - ViewInfo.z)"), depth.Value), caller); } void ParticleEmitterGPUGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value) diff --git a/Source/Engine/Renderer/DepthOfFieldPass.cpp b/Source/Engine/Renderer/DepthOfFieldPass.cpp index 629f77d82..72e00eaee 100644 --- a/Source/Engine/Renderer/DepthOfFieldPass.cpp +++ b/Source/Engine/Renderer/DepthOfFieldPass.cpp @@ -277,8 +277,13 @@ void DepthOfFieldPass::Render(RenderContext& renderContext, GPUTexture*& frame, cbData.BokehTargetSize.Y = static_cast(bokehTargetHeight); // TODO: use projection matrix instead of this far and near stuff? - cbData.ProjectionAB.X = nearPlane / (farPlane - nearPlane); +#if FLAX_REVERSE_Z + cbData.ProjectionAB.X = -nearPlane / (farPlane - nearPlane); cbData.ProjectionAB.Y = (farPlane * nearPlane) / (farPlane - nearPlane); +#else + cbData.ProjectionAB.X = farPlane / (farPlane - nearPlane); + cbData.ProjectionAB.Y = -(farPlane * nearPlane) / (farPlane - nearPlane); +#endif auto cb = shader->GetCB(0); context->UpdateCB(cb, &cbData); diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp index 0ab853386..9b0a334e6 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp @@ -160,7 +160,7 @@ void MaterialGenerator::sampleSceneDepth(Node* caller, Value& value, Box* box) void MaterialGenerator::linearizeSceneDepth(Node* caller, const Value& depth, Value& value) { - value = writeLocal(VariantType::Float, String::Format(TEXT("ViewInfo.w / ({0}.x + ViewInfo.z)"), depth.Value), caller); + value = writeLocal(VariantType::Float, String::Format(TEXT("ViewInfo.w / ({0}.x - ViewInfo.z)"), depth.Value), caller); } void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value) diff --git a/Source/Shaders/DepthOfField.shader b/Source/Shaders/DepthOfField.shader index 00db90261..e666d3852 100644 --- a/Source/Shaders/DepthOfField.shader +++ b/Source/Shaders/DepthOfField.shader @@ -96,7 +96,7 @@ Texture2D Input1 : register(t1); // Converts z-buffer depth to linear view-space depth float LinearDepth(in float zBufferDepth) { - return ProjectionAB.y / (zBufferDepth + ProjectionAB.x); + return ProjectionAB.y / (zBufferDepth - ProjectionAB.x); } // Depth of Field depth blur generation (outputs linear depth + blur factor to R16G16 target) diff --git a/Source/Shaders/GBuffer.hlsl b/Source/Shaders/GBuffer.hlsl index bc7e7483c..0dd2c4457 100644 --- a/Source/Shaders/GBuffer.hlsl +++ b/Source/Shaders/GBuffer.hlsl @@ -27,13 +27,13 @@ Texture2D GBuffer3 : register(t4); // Linearize raw device depth float LinearizeZ(GBufferData gBuffer, float depth) { - return gBuffer.ViewInfo.w / (depth + gBuffer.ViewInfo.z); + return gBuffer.ViewInfo.w / (depth - gBuffer.ViewInfo.z); } // Convert linear depth to device depth float LinearZ2DeviceDepth(GBufferData gBuffer, float linearDepth) { - return ((gBuffer.ViewInfo.w / linearDepth) - gBuffer.ViewInfo.z); + return ((gBuffer.ViewInfo.w / linearDepth) + gBuffer.ViewInfo.z); } // Get view space position at given pixel coordinate with given device depth