Add Global Illumination sampling option to transparent materials (eg. particles)

This commit is contained in:
2022-07-14 14:28:42 +02:00
parent 4cc7bb96f5
commit 0d8ebd332e
10 changed files with 113 additions and 2 deletions
@@ -97,6 +97,11 @@ float4 PS_Forward(PixelInput input) : SV_Target0
light += GetLighting(ViewPos, localLight, gBuffer, shadowMask, true, isSpotLight);
}
// Calculate lighting from Global Illumination
#if USE_GI
light += GetGlobalIlluminationLighting(gBuffer);
#endif
// Calculate reflections
#if USE_REFLECTIONS
float3 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness).rgb;
@@ -0,0 +1,23 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
@0// Global Illumination: Defines
#define USE_GI 1
@1// Global Illumination: Includes
#include "./Flax/GI/DDGI.hlsl"
#include "./Flax/LightingCommon.hlsl"
@2// Global Illumination: Constants
DDGIData DDGI;
@3// Global Illumination: Resources
Texture2D<snorm float4> ProbesState : register(t__SRV__);
Texture2D<float4> ProbesDistance : register(t__SRV__);
Texture2D<float4> ProbesIrradiance : register(t__SRV__);
@4// Global Illumination: Utilities
float4 GetGlobalIlluminationLighting(GBufferSample gBuffer)
{
float3 irradiance = SampleDDGIIrradiance(DDGI, ProbesState, ProbesDistance, ProbesIrradiance, gBuffer.WorldPos, gBuffer.Normal);
float3 diffuseColor = GetDiffuseColor(gBuffer);
float3 diffuse = Diffuse_Lambert(diffuseColor);
return float4(diffuse * irradiance, saturate(length(irradiance)));
}
@5// Global Illumination: Shaders
Binary file not shown.
@@ -94,6 +94,9 @@ namespace FlaxEditor.Windows.Assets
[EditorOrder(220), DefaultValue(true), EditorDisplay("Transparency"), Tooltip("Enables distortion effect when rendering.")]
public bool EnableDistortion;
[EditorOrder(224), DefaultValue(false), EditorDisplay("Transparency"), Tooltip("Enables sampling Global Illumination in material (eg. light probes or volumetric lightmap).")]
public bool EnableGlobalIllumination;
[EditorOrder(225), DefaultValue(false), EditorDisplay("Transparency"), Tooltip("Enables refraction offset based on the difference between the per-pixel normal and the per-vertex normal. Useful for large water-like surfaces.")]
public bool PixelNormalOffsetRefraction;
@@ -156,6 +159,7 @@ namespace FlaxEditor.Windows.Assets
EnableScreenSpaceReflections = (info.FeaturesFlags & MaterialFeaturesFlags.ScreenSpaceReflections) != 0;
EnableFog = (info.FeaturesFlags & MaterialFeaturesFlags.DisableFog) == 0;
EnableDistortion = (info.FeaturesFlags & MaterialFeaturesFlags.DisableDistortion) == 0;
EnableGlobalIllumination = (info.FeaturesFlags & MaterialFeaturesFlags.GlobalIllumination) != 0;
PixelNormalOffsetRefraction = (info.FeaturesFlags & MaterialFeaturesFlags.PixelNormalOffsetRefraction) != 0;
InputWorldSpaceNormal = (info.FeaturesFlags & MaterialFeaturesFlags.InputWorldSpaceNormal) != 0;
DitheredLODTransition = (info.FeaturesFlags & MaterialFeaturesFlags.DitheredLODTransition) != 0;
@@ -196,6 +200,8 @@ namespace FlaxEditor.Windows.Assets
info.FeaturesFlags |= MaterialFeaturesFlags.DisableFog;
if (!EnableDistortion)
info.FeaturesFlags |= MaterialFeaturesFlags.DisableDistortion;
if (EnableGlobalIllumination)
info.FeaturesFlags |= MaterialFeaturesFlags.GlobalIllumination;
if (PixelNormalOffsetRefraction)
info.FeaturesFlags |= MaterialFeaturesFlags.PixelNormalOffsetRefraction;
if (InputWorldSpaceNormal)
@@ -64,6 +64,8 @@ void ForwardMaterialShader::Bind(BindParameters& params)
int32 srv = 2;
// Setup features
if (_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination)
GlobalIlluminationFeature::Bind(params, cb, srv);
ForwardShadingFeature::Bind(params, cb, srv);
// Setup parameters
@@ -277,6 +277,11 @@ API_ENUM(Attributes="Flags") enum class MaterialFeaturesFlags : uint32
/// The flag used to enable high-quality reflections based on the screen space raytracing. Useful for large water-like surfaces. The Forward Pass materials option.
/// </summary>
ScreenSpaceReflections = 1 << 10,
/// <summary>
/// The flag used to enable sampling Global Illumination in material (eg. light probes or volumetric lightmap). The Forward Pass materials option.
/// </summary>
GlobalIllumination = 1 << 11,
};
DECLARE_ENUM_OPERATORS(MaterialFeaturesFlags);
@@ -154,6 +154,48 @@ bool LightmapFeature::Bind(MaterialShader::BindParameters& params, Span<byte>& c
return useLightmap;
}
bool GlobalIlluminationFeature::Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv)
{
auto& data = *(Data*)cb.Get();
ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data));
bool useGI = false;
if (params.RenderContext.View.Flags & ViewFlags::GI)
{
switch (params.RenderContext.List->Settings.GlobalIllumination.Mode)
{
case GlobalIlluminationMode::DDGI:
{
DynamicDiffuseGlobalIlluminationPass::BindingData bindingDataDDGI;
if (!DynamicDiffuseGlobalIlluminationPass::Instance()->Get(params.RenderContext.Buffers, bindingDataDDGI))
{
useGI = true;
// Bind DDGI data
data.DDGI = bindingDataDDGI.Constants;
params.GPUContext->BindSR(srv + 0, bindingDataDDGI.ProbesState);
params.GPUContext->BindSR(srv + 1, bindingDataDDGI.ProbesDistance);
params.GPUContext->BindSR(srv + 2, bindingDataDDGI.ProbesIrradiance);
}
break;
}
}
}
if (!useGI)
{
// Unbind SRVs to prevent issues
data.DDGI.CascadesCount = 0;
data.DDGI.FallbackIrradiance = Float3::Zero;
params.GPUContext->UnBindSR(srv + 0);
params.GPUContext->UnBindSR(srv + 1);
params.GPUContext->UnBindSR(srv + 2);
}
cb = Span<byte>(cb.Get() + sizeof(Data), cb.Length() - sizeof(Data));
srv += SRVs;
return useGI;
}
#if USE_EDITOR
void ForwardShadingFeature::Generate(GeneratorData& data)
@@ -176,6 +218,11 @@ void LightmapFeature::Generate(GeneratorData& data)
data.Template = TEXT("Features/Lightmap.hlsl");
}
void GlobalIlluminationFeature::Generate(GeneratorData& data)
{
data.Template = TEXT("Features/GlobalIllumination.hlsl");
}
void DistortionFeature::Generate(GeneratorData& data)
{
data.Template = TEXT("Features/Distortion.hlsl");
@@ -5,6 +5,7 @@
#include "MaterialShader.h"
#include "Engine/Core/Math/Rectangle.h"
#include "Engine/Core/Types/Span.h"
#include "Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h"
// Material shader features are plugin-based functionalities that are reusable between different material domains.
struct MaterialShaderFeature
@@ -74,6 +75,22 @@ struct LightmapFeature : MaterialShaderFeature
#endif
};
// Material shader feature that adds Global Illumination sampling feature (light probes).
struct GlobalIlluminationFeature : MaterialShaderFeature
{
enum { SRVs = 3 };
PACK_STRUCT(struct Data
{
DynamicDiffuseGlobalIlluminationPass::ConstantsData DDGI;
});
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
{
@@ -64,6 +64,8 @@ void ParticleMaterialShader::Bind(BindParameters& params)
int32 srv = 2;
// Setup features
if (_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination)
GlobalIlluminationFeature::Bind(params, cb, srv);
ForwardShadingFeature::Bind(params, cb, srv);
// Setup parameters
@@ -197,6 +197,8 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
ADD_FEATURE(DeferredShadingFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0)
ADD_FEATURE(DistortionFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != 0)
ADD_FEATURE(GlobalIlluminationFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
ADD_FEATURE(ForwardShadingFeature);
break;
@@ -209,6 +211,8 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
case MaterialDomain::Particle:
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0)
ADD_FEATURE(DistortionFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != 0)
ADD_FEATURE(GlobalIlluminationFeature);
ADD_FEATURE(ForwardShadingFeature);
break;
case MaterialDomain::Deformable: