Complete sdf reflections

This commit is contained in:
ExMatics HydrogenC
2024-06-18 21:25:12 +08:00
parent 5f939430ee
commit 9062c04ef0
9 changed files with 154 additions and 41 deletions

View File

@@ -53,6 +53,8 @@ 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

View File

@@ -100,15 +100,6 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
params.GPUContext->UnBindSR(envProbeShaderRegisterIndex);
}
// Bind sdf resources if using software reflections
if (!GlobalSignDistanceFieldPass::Instance()->Render(params.RenderContext, params.GPUContext, bindingDataSDF) &&
!GlobalSurfaceAtlasPass::Instance()->Render(params.RenderContext, params.GPUContext, bindingDataSurfaceAtlas))
{
useGlobalSurfaceAtlas = true;
data.GlobalSDF = bindingDataSDF.Constants;
data.GlobalSurfaceAtlas = bindingDataSurfaceAtlas.Constants;
}
// Set local lights
data.LocalLightsCount = 0;
const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius);
@@ -143,13 +134,13 @@ bool LightmapFeature::Bind(MaterialShader::BindParameters& params, Span<byte>& c
const bool useLightmap = EnumHasAnyFlags(params.RenderContext.View.Flags, ViewFlags::GI)
#if USE_EDITOR
&& EnableLightmapsUsage
&& EnableLightmapsUsage
#endif
&& drawCall.Surface.Lightmap != nullptr;
&& drawCall.Surface.Lightmap != nullptr;
if (useLightmap)
{
// Bind lightmap textures
GPUTexture *lightmap0, *lightmap1, *lightmap2;
GPUTexture* lightmap0, * lightmap1, * lightmap2;
drawCall.Features.Lightmap->GetTextures(&lightmap0, &lightmap1, &lightmap2);
params.GPUContext->BindSR(srv + 0, lightmap0);
params.GPUContext->BindSR(srv + 1, lightmap1);
@@ -207,6 +198,61 @@ 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 DDGI 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)
{
data.GlobalSDF.CascadesCount = 0;
// Unbind SRVs to prevent issues
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)
@@ -234,6 +280,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");

View File

@@ -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
{

View File

@@ -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

View File

@@ -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>

View File

@@ -199,6 +199,8 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
ADD_FEATURE(DistortionFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination))
ADD_FEATURE(GlobalIlluminationFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::ScreenSpaceReflections))
ADD_FEATURE(SDFReflectionsFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
ADD_FEATURE(ForwardShadingFeature);
break;