Merge branch 'HydrogenC-forward-software-refl'
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.
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.
@@ -125,6 +125,20 @@ void PS_Forward(
|
||||
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
||||
reflections = lerp(reflections, screenColor, hit.z);
|
||||
}
|
||||
|
||||
// Fallback to software tracing if possible
|
||||
#if USE_GLOBAL_SURFACE_ATLAS && CAN_USE_GLOBAL_SURFACE_ATLAS
|
||||
if (hit.z < REFLECTIONS_HIT_THRESHOLD)
|
||||
{
|
||||
float3 reflectWS = ScreenSpaceReflectionDirection(screenUV, gBuffer, ViewPos);
|
||||
float4 surfaceAtlas;
|
||||
if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas))
|
||||
{
|
||||
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
||||
reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
@0// SDF Reflections: Defines
|
||||
#define USE_GLOBAL_SURFACE_ATLAS 1
|
||||
@1// SDF Reflections: Includes
|
||||
#include "./Flax/GlobalSignDistanceField.hlsl"
|
||||
#include "./Flax/GI/GlobalSurfaceAtlas.hlsl"
|
||||
@2// SDF Reflections: Constants
|
||||
GlobalSDFData GlobalSDF;
|
||||
GlobalSurfaceAtlasData GlobalSurfaceAtlas;
|
||||
@3// SDF Reflections: Resources
|
||||
Texture3D<float> GlobalSDFTex : register(t__SRV__);
|
||||
Texture3D<float> GlobalSDFMip : register(t__SRV__);
|
||||
ByteAddressBuffer GlobalSurfaceAtlasChunks : register(t__SRV__);
|
||||
ByteAddressBuffer RWGlobalSurfaceAtlasCulledObjects : register(t__SRV__);
|
||||
Buffer<float4> GlobalSurfaceAtlasObjects : register(t__SRV__);
|
||||
Texture2D GlobalSurfaceAtlasDepth : register(t__SRV__);
|
||||
Texture2D GlobalSurfaceAtlasTex : register(t__SRV__);
|
||||
@4// SDF Reflections: Utilities
|
||||
bool TraceSDFSoftwareReflections(GBufferSample gBuffer, float3 reflectWS, out float4 surfaceAtlas)
|
||||
{
|
||||
GlobalSDFTrace sdfTrace;
|
||||
float maxDistance = GLOBAL_SDF_WORLD_SIZE;
|
||||
float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0];
|
||||
sdfTrace.Init(gBuffer.WorldPos + gBuffer.Normal * selfOcclusionBias, reflectWS, 0.0f, maxDistance);
|
||||
GlobalSDFHit sdfHit = RayTraceGlobalSDF(GlobalSDF, GlobalSDFTex, GlobalSDFMip, sdfTrace);
|
||||
if (sdfHit.IsHit())
|
||||
{
|
||||
float3 hitPosition = sdfHit.GetHitPosition(sdfTrace);
|
||||
float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit);
|
||||
surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@5// SDF Reflections: Shaders
|
||||
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.
BIN
Content/Shaders/SSR.flax
LFS
BIN
Content/Shaders/SSR.flax
LFS
Binary file not shown.
@@ -52,7 +52,11 @@ void ForwardMaterialShader::Bind(BindParameters& params)
|
||||
|
||||
// Setup features
|
||||
if ((_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != MaterialFeaturesFlags::None)
|
||||
{
|
||||
GlobalIlluminationFeature::Bind(params, cb, srv);
|
||||
if ((_info.FeaturesFlags & MaterialFeaturesFlags::ScreenSpaceReflections) != MaterialFeaturesFlags::None)
|
||||
SDFReflectionsFeature::Bind(params, cb, srv);
|
||||
}
|
||||
ForwardShadingFeature::Bind(params, cb, srv);
|
||||
|
||||
// Setup parameters
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/// <summary>
|
||||
/// Current materials shader version.
|
||||
/// </summary>
|
||||
#define MATERIAL_GRAPH_VERSION 162
|
||||
#define MATERIAL_GRAPH_VERSION 163
|
||||
|
||||
class Material;
|
||||
class GPUShader;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Engine/Graphics/Textures/GPUTexture.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Renderer/ShadowsPass.h"
|
||||
#include "Engine/Renderer/GlobalSignDistanceFieldPass.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Renderer/Lightmaps.h"
|
||||
#endif
|
||||
@@ -195,6 +196,58 @@ bool GlobalIlluminationFeature::Bind(MaterialShader::BindParameters& params, Spa
|
||||
return useGI;
|
||||
}
|
||||
|
||||
bool SDFReflectionsFeature::Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv)
|
||||
{
|
||||
auto& data = *(Data*)cb.Get();
|
||||
ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data));
|
||||
|
||||
bool useSDFReflections = false;
|
||||
if (EnumHasAnyFlags(params.RenderContext.View.Flags, ViewFlags::Reflections))
|
||||
{
|
||||
switch (params.RenderContext.List->Settings.ScreenSpaceReflections.TraceMode)
|
||||
{
|
||||
case ReflectionsTraceMode::SoftwareTracing:
|
||||
{
|
||||
GlobalSignDistanceFieldPass::BindingData bindingDataSDF;
|
||||
GlobalSurfaceAtlasPass::BindingData bindingDataSurfaceAtlas;
|
||||
if (!GlobalSignDistanceFieldPass::Instance()->Get(params.RenderContext.Buffers, bindingDataSDF) &&
|
||||
!GlobalSurfaceAtlasPass::Instance()->Get(params.RenderContext.Buffers, bindingDataSurfaceAtlas))
|
||||
{
|
||||
useSDFReflections = true;
|
||||
|
||||
// Bind SDF and Surface Atlas data
|
||||
data.GlobalSDF = bindingDataSDF.Constants;
|
||||
data.GlobalSurfaceAtlas = bindingDataSurfaceAtlas.Constants;
|
||||
params.GPUContext->BindSR(srv + 0, bindingDataSDF.Texture ? bindingDataSDF.Texture->ViewVolume() : nullptr);
|
||||
params.GPUContext->BindSR(srv + 1, bindingDataSDF.TextureMip ? bindingDataSDF.TextureMip->ViewVolume() : nullptr);
|
||||
params.GPUContext->BindSR(srv + 2, bindingDataSurfaceAtlas.Chunks ? bindingDataSurfaceAtlas.Chunks->View() : nullptr);
|
||||
params.GPUContext->BindSR(srv + 3, bindingDataSurfaceAtlas.CulledObjects ? bindingDataSurfaceAtlas.CulledObjects->View() : nullptr);
|
||||
params.GPUContext->BindSR(srv + 4, bindingDataSurfaceAtlas.Objects ? bindingDataSurfaceAtlas.Objects->View() : nullptr);
|
||||
params.GPUContext->BindSR(srv + 5, bindingDataSurfaceAtlas.AtlasDepth->View());
|
||||
params.GPUContext->BindSR(srv + 6, bindingDataSurfaceAtlas.AtlasLighting->View());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!useSDFReflections)
|
||||
{
|
||||
// Unbind SRVs to prevent issues
|
||||
data.GlobalSDF.CascadesCount = 0;
|
||||
params.GPUContext->UnBindSR(srv + 0);
|
||||
params.GPUContext->UnBindSR(srv + 1);
|
||||
params.GPUContext->UnBindSR(srv + 2);
|
||||
params.GPUContext->UnBindSR(srv + 3);
|
||||
params.GPUContext->UnBindSR(srv + 4);
|
||||
params.GPUContext->UnBindSR(srv + 5);
|
||||
params.GPUContext->UnBindSR(srv + 6);
|
||||
}
|
||||
|
||||
cb = Span<byte>(cb.Get() + sizeof(Data), cb.Length() - sizeof(Data));
|
||||
srv += SRVs;
|
||||
return useSDFReflections;
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void ForwardShadingFeature::Generate(GeneratorData& data)
|
||||
@@ -222,6 +275,11 @@ void GlobalIlluminationFeature::Generate(GeneratorData& data)
|
||||
data.Template = TEXT("Features/GlobalIllumination.hlsl");
|
||||
}
|
||||
|
||||
void SDFReflectionsFeature::Generate(GeneratorData& data)
|
||||
{
|
||||
data.Template = TEXT("Features/SDFReflections.hlsl");
|
||||
}
|
||||
|
||||
void DistortionFeature::Generate(GeneratorData& data)
|
||||
{
|
||||
data.Template = TEXT("Features/Distortion.hlsl");
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "Engine/Core/Math/Rectangle.h"
|
||||
#include "Engine/Core/Types/Span.h"
|
||||
#include "Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h"
|
||||
#include "Engine/Renderer/GlobalSignDistanceFieldPass.h"
|
||||
#include "Engine/Renderer/GI/GlobalSurfaceAtlasPass.h"
|
||||
|
||||
// Material shader features are plugin-based functionalities that are reusable between different material domains.
|
||||
struct MaterialShaderFeature
|
||||
@@ -91,6 +93,25 @@ struct GlobalIlluminationFeature : MaterialShaderFeature
|
||||
#endif
|
||||
};
|
||||
|
||||
// Material shader feature that adds SDF Reflections feature (software reflections).
|
||||
struct SDFReflectionsFeature : MaterialShaderFeature
|
||||
{
|
||||
enum { SRVs = 7 };
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
GlobalSignDistanceFieldPass::ConstantsData GlobalSDF;
|
||||
GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas;
|
||||
});
|
||||
|
||||
|
||||
|
||||
static bool Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv);
|
||||
#if USE_EDITOR
|
||||
static void Generate(GeneratorData& data);
|
||||
#endif
|
||||
};
|
||||
|
||||
// Material shader feature that adds distortion vectors rendering pass.
|
||||
struct DistortionFeature : MaterialShaderFeature
|
||||
{
|
||||
|
||||
@@ -360,6 +360,17 @@ void GlobalSurfaceAtlasPass::Dispose()
|
||||
_shader = nullptr;
|
||||
}
|
||||
|
||||
bool GlobalSurfaceAtlasPass::Get(const RenderBuffers* buffers, BindingData& result)
|
||||
{
|
||||
auto* surfaceAtlasData = buffers ? buffers->FindCustomBuffer<GlobalSurfaceAtlasCustomBuffer>(TEXT("GlobalSurfaceAtlas")) : nullptr;
|
||||
if (surfaceAtlasData && surfaceAtlasData->LastFrameUsed + 1 >= Engine::FrameCount) // Allow to use Surface Atlas from the previous frame (not used currently)
|
||||
{
|
||||
result = surfaceAtlasData->Result;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* context, BindingData& result)
|
||||
{
|
||||
// Skip if not supported
|
||||
|
||||
@@ -65,6 +65,14 @@ private:
|
||||
void* _currentActorObject;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the Global Surface Atlas (only if enabled in Graphics Settings).
|
||||
/// </summary>
|
||||
/// <param name="buffers">The rendering context buffers.</param>
|
||||
/// <param name="result">The result Global Surface Atlas data for binding to the shaders.</param>
|
||||
/// <returns>True if there is no valid Global Surface Atlas rendered during this frame, otherwise false.</returns>
|
||||
bool Get(const RenderBuffers* buffers, BindingData& result);
|
||||
|
||||
/// <summary>
|
||||
/// Renders the Global Surface Atlas.
|
||||
/// </summary>
|
||||
|
||||
@@ -188,40 +188,46 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
|
||||
{
|
||||
case MaterialDomain::Surface:
|
||||
if (materialInfo.TessellationMode != TessellationMethod::None)
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
if (materialInfo.BlendMode == MaterialBlendMode::Opaque)
|
||||
ADD_FEATURE(MotionVectorsFeature);
|
||||
ADD_FEATURE(MotionVectorsFeature);
|
||||
if (materialInfo.BlendMode == MaterialBlendMode::Opaque)
|
||||
ADD_FEATURE(LightmapFeature);
|
||||
ADD_FEATURE(LightmapFeature);
|
||||
if (materialInfo.BlendMode == MaterialBlendMode::Opaque)
|
||||
ADD_FEATURE(DeferredShadingFeature);
|
||||
ADD_FEATURE(DeferredShadingFeature);
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == MaterialFeaturesFlags::None)
|
||||
ADD_FEATURE(DistortionFeature);
|
||||
ADD_FEATURE(DistortionFeature);
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination))
|
||||
ADD_FEATURE(GlobalIlluminationFeature);
|
||||
{
|
||||
ADD_FEATURE(GlobalIlluminationFeature);
|
||||
|
||||
// SDF Reflections is only valid when both GI and SSR is enabled
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::ScreenSpaceReflections))
|
||||
ADD_FEATURE(SDFReflectionsFeature);
|
||||
}
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
break;
|
||||
case MaterialDomain::Terrain:
|
||||
if (materialInfo.TessellationMode != TessellationMethod::None)
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
ADD_FEATURE(LightmapFeature);
|
||||
ADD_FEATURE(DeferredShadingFeature);
|
||||
break;
|
||||
case MaterialDomain::Particle:
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == MaterialFeaturesFlags::None)
|
||||
ADD_FEATURE(DistortionFeature);
|
||||
ADD_FEATURE(DistortionFeature);
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination))
|
||||
ADD_FEATURE(GlobalIlluminationFeature);
|
||||
ADD_FEATURE(GlobalIlluminationFeature);
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
break;
|
||||
case MaterialDomain::Deformable:
|
||||
if (materialInfo.TessellationMode != TessellationMethod::None)
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
if (materialInfo.BlendMode == MaterialBlendMode::Opaque)
|
||||
ADD_FEATURE(DeferredShadingFeature);
|
||||
ADD_FEATURE(DeferredShadingFeature);
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -708,7 +714,7 @@ void MaterialGenerator::ProcessGroupMath(Box* box, Node* node, Value& value)
|
||||
{
|
||||
switch (node->TypeID)
|
||||
{
|
||||
// Vector Transform
|
||||
// Vector Transform
|
||||
case 30:
|
||||
{
|
||||
// Get input vector
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
#include "./Flax/GBufferCommon.hlsl"
|
||||
|
||||
// Hit depth (view space) threshold to detect if sky was hit (value above it where 1.0f is default)
|
||||
#define REFLECTIONS_HIT_THRESHOLD 0.9f
|
||||
|
||||
float GetSpecularOcclusion(float NoV, float roughnessSq, float ao)
|
||||
{
|
||||
return saturate(pow(NoV + ao, roughnessSq) - 1 + ao);
|
||||
|
||||
@@ -129,17 +129,17 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0
|
||||
float mip = clamp(log2(intersectionCircleRadius * TraceSizeMax), 0.0, MaxColorMiplevel);
|
||||
float3 sampleColor = Texture0.SampleLevel(SamplerLinearClamp, screenHit.xy, mip).rgb;
|
||||
result = float4(sampleColor, screenHit.z);
|
||||
if (screenHit.z >= 0.9f)
|
||||
if (screenHit.z >= REFLECTIONS_HIT_THRESHOLD)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate reflection direction (the same TraceScreenSpaceReflection)
|
||||
float3 reflectWS = ScreenSpaceReflectionDirection(input.TexCoord, gBuffer, gBufferData.ViewPos, TemporalEffect, TemporalTime, BRDFBias);
|
||||
|
||||
// Fallback to Global SDF and Global Surface Atlas tracing
|
||||
#if USE_GLOBAL_SURFACE_ATLAS && CAN_USE_GLOBAL_SURFACE_ATLAS
|
||||
// Calculate reflection direction (the same TraceScreenSpaceReflection)
|
||||
float3 reflectWS = ScreenSpaceReflectionDirection(input.TexCoord, gBuffer, gBufferData.ViewPos, TemporalEffect, TemporalTime, BRDFBias);
|
||||
|
||||
GlobalSDFTrace sdfTrace;
|
||||
float maxDistance = 100000;
|
||||
float maxDistance = GLOBAL_SDF_WORLD_SIZE;
|
||||
float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0];
|
||||
sdfTrace.Init(gBuffer.WorldPos + gBuffer.Normal * selfOcclusionBias, reflectWS, 0.0f, maxDistance);
|
||||
GlobalSDFHit sdfHit = RayTraceGlobalSDF(GlobalSDF, GlobalSDFTex, GlobalSDFMip, sdfTrace);
|
||||
|
||||
Reference in New Issue
Block a user