Fix Forward shading to match Deferred in fog and reflections rendering
#3717
This commit is contained in:
@@ -28,6 +28,7 @@ TextureCube SkyLightTexture : register(t__SRV__);
|
|||||||
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
||||||
Texture2D<float> ShadowMap : register(t__SRV__);
|
Texture2D<float> ShadowMap : register(t__SRV__);
|
||||||
Texture3D VolumetricFogTexture : register(t__SRV__);
|
Texture3D VolumetricFogTexture : register(t__SRV__);
|
||||||
|
Texture2D PreIntegratedGF : register(t__SRV__);
|
||||||
@4// Forward Shading: Utilities
|
@4// Forward Shading: Utilities
|
||||||
// Public accessors for lighting data, use them as data binding might change but those methods will remain.
|
// Public accessors for lighting data, use them as data binding might change but those methods will remain.
|
||||||
LightData GetDirectionalLight() { return DirectionalLight; }
|
LightData GetDirectionalLight() { return DirectionalLight; }
|
||||||
@@ -108,7 +109,8 @@ void PS_Forward(
|
|||||||
|
|
||||||
// Calculate reflections
|
// Calculate reflections
|
||||||
#if USE_REFLECTIONS
|
#if USE_REFLECTIONS
|
||||||
float3 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness).rgb;
|
float4 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness);
|
||||||
|
reflections.rgb *= reflections.a;
|
||||||
|
|
||||||
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
|
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
|
||||||
// Screen Space Reflections
|
// Screen Space Reflections
|
||||||
@@ -124,7 +126,7 @@ void PS_Forward(
|
|||||||
if (hit.z > 0)
|
if (hit.z > 0)
|
||||||
{
|
{
|
||||||
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
||||||
reflections = lerp(reflections, screenColor, hit.z);
|
reflections.rgb = lerp(reflections.rgb, screenColor, hit.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to software tracing if possible
|
// Fallback to software tracing if possible
|
||||||
@@ -136,13 +138,13 @@ void PS_Forward(
|
|||||||
if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas))
|
if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas))
|
||||||
{
|
{
|
||||||
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
||||||
reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z);
|
reflections.rgb = lerp(surfaceAtlas, float4(screenColor, 1), hit.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a;
|
light.rgb += reflections.rgb * GetReflectionSpecularLighting(PreIntegratedGF, ViewPos, gBuffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add lighting
|
// Add lighting
|
||||||
@@ -158,7 +160,8 @@ void PS_Forward(
|
|||||||
#else
|
#else
|
||||||
float fogSceneDistance = gBuffer.ViewPos.z;
|
float fogSceneDistance = gBuffer.ViewPos.z;
|
||||||
#endif
|
#endif
|
||||||
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0, fogSceneDistance);
|
float fogSkipDistance = max(ExponentialHeightFog.VolumetricFogMaxDistance - 100, 0);
|
||||||
|
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, fogSkipDistance, fogSceneDistance);
|
||||||
|
|
||||||
if (ExponentialHeightFog.VolumetricFogMaxDistance > 0)
|
if (ExponentialHeightFog.VolumetricFogMaxDistance > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current materials shader version.
|
/// Current materials shader version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#define MATERIAL_GRAPH_VERSION 179
|
#define MATERIAL_GRAPH_VERSION 180
|
||||||
|
|
||||||
class Material;
|
class Material;
|
||||||
class GPUShader;
|
class GPUShader;
|
||||||
|
|||||||
@@ -10,9 +10,11 @@
|
|||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
#include "Engine/Renderer/Lightmaps.h"
|
#include "Engine/Renderer/Lightmaps.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "Engine/Content/Content.h"
|
||||||
#include "Engine/Graphics/GPUContext.h"
|
#include "Engine/Graphics/GPUContext.h"
|
||||||
#include "Engine/Level/Scene/Lightmap.h"
|
#include "Engine/Level/Scene/Lightmap.h"
|
||||||
#include "Engine/Level/Actors/EnvironmentProbe.h"
|
#include "Engine/Level/Actors/EnvironmentProbe.h"
|
||||||
|
#include "Engine/Renderer/ReflectionsPass.h"
|
||||||
|
|
||||||
void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv)
|
void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv)
|
||||||
{
|
{
|
||||||
@@ -26,6 +28,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
|||||||
const int32 shadowsBufferRegisterIndex = srv + 2;
|
const int32 shadowsBufferRegisterIndex = srv + 2;
|
||||||
const int32 shadowMapShaderRegisterIndex = srv + 3;
|
const int32 shadowMapShaderRegisterIndex = srv + 3;
|
||||||
const int32 volumetricFogTextureRegisterIndex = srv + 4;
|
const int32 volumetricFogTextureRegisterIndex = srv + 4;
|
||||||
|
const int32 preIntegratedGFRegisterIndex = srv + 5;
|
||||||
const bool canUseShadow = view.Pass != DrawPass::Depth;
|
const bool canUseShadow = view.Pass != DrawPass::Depth;
|
||||||
|
|
||||||
// Set fog input
|
// Set fog input
|
||||||
@@ -47,6 +50,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
|||||||
data.ExponentialHeightFog.FogCutoffDistance = 0.1f;
|
data.ExponentialHeightFog.FogCutoffDistance = 0.1f;
|
||||||
data.ExponentialHeightFog.StartDistance = 0.0f;
|
data.ExponentialHeightFog.StartDistance = 0.0f;
|
||||||
data.ExponentialHeightFog.ApplyDirectionalInscattering = 0.0f;
|
data.ExponentialHeightFog.ApplyDirectionalInscattering = 0.0f;
|
||||||
|
data.ExponentialHeightFog.VolumetricFogMaxDistance = -1.0f;
|
||||||
}
|
}
|
||||||
params.GPUContext->BindSR(volumetricFogTextureRegisterIndex, volumetricFogTexture);
|
params.GPUContext->BindSR(volumetricFogTextureRegisterIndex, volumetricFogTexture);
|
||||||
|
|
||||||
@@ -100,9 +104,12 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
|||||||
}
|
}
|
||||||
if (noEnvProbe)
|
if (noEnvProbe)
|
||||||
{
|
{
|
||||||
data.EnvironmentProbe.Data1 = Float4::Zero;
|
Platform::MemoryClear(&data.EnvironmentProbe, sizeof(data.EnvironmentProbe));
|
||||||
params.GPUContext->UnBindSR(envProbeShaderRegisterIndex);
|
params.GPUContext->UnBindSR(envProbeShaderRegisterIndex);
|
||||||
}
|
}
|
||||||
|
// TODO: find a better way to find this texture (eg. cache GPUTextureView* handle within ForwardShading cache for a whole frame)
|
||||||
|
static AssetReference<Texture> PreIntegratedGF = Content::LoadAsyncInternal<Texture>(PRE_INTEGRATED_GF_ASSET_NAME);
|
||||||
|
params.GPUContext->BindSR(preIntegratedGFRegisterIndex, PreIntegratedGF->GetTexture());
|
||||||
|
|
||||||
// Set local lights
|
// Set local lights
|
||||||
data.LocalLightsCount = 0;
|
data.LocalLightsCount = 0;
|
||||||
|
|||||||
@@ -25,10 +25,9 @@ struct ForwardShadingFeature : MaterialShaderFeature
|
|||||||
{
|
{
|
||||||
enum { MaxLocalLights = 4 };
|
enum { MaxLocalLights = 4 };
|
||||||
|
|
||||||
enum { SRVs = 5 };
|
enum { SRVs = 6 };
|
||||||
|
|
||||||
PACK_STRUCT(struct Data
|
PACK_STRUCT(struct Data {
|
||||||
{
|
|
||||||
ShaderLightData DirectionalLight;
|
ShaderLightData DirectionalLight;
|
||||||
ShaderLightData SkyLight;
|
ShaderLightData SkyLight;
|
||||||
ShaderEnvProbeData EnvironmentProbe;
|
ShaderEnvProbeData EnvironmentProbe;
|
||||||
@@ -76,8 +75,7 @@ struct GlobalIlluminationFeature : MaterialShaderFeature
|
|||||||
{
|
{
|
||||||
enum { SRVs = 3 };
|
enum { SRVs = 3 };
|
||||||
|
|
||||||
PACK_STRUCT(struct Data
|
PACK_STRUCT(struct Data {
|
||||||
{
|
|
||||||
DynamicDiffuseGlobalIlluminationPass::ConstantsData DDGI;
|
DynamicDiffuseGlobalIlluminationPass::ConstantsData DDGI;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -92,13 +90,10 @@ struct SDFReflectionsFeature : MaterialShaderFeature
|
|||||||
{
|
{
|
||||||
enum { SRVs = 7 };
|
enum { SRVs = 7 };
|
||||||
|
|
||||||
PACK_STRUCT(struct Data
|
PACK_STRUCT(struct Data {
|
||||||
{
|
|
||||||
GlobalSignDistanceFieldPass::ConstantsData GlobalSDF;
|
GlobalSignDistanceFieldPass::ConstantsData GlobalSDF;
|
||||||
GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas;
|
GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv);
|
static bool Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv);
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|||||||
@@ -76,18 +76,8 @@ float4 PS_CombinePass(Quad_VS2PS input) : SV_Target0
|
|||||||
// Sample reflections buffer
|
// Sample reflections buffer
|
||||||
float3 reflections = SAMPLE_RT(Reflections, input.TexCoord).rgb;
|
float3 reflections = SAMPLE_RT(Reflections, input.TexCoord).rgb;
|
||||||
|
|
||||||
// Calculate specular color
|
|
||||||
float3 specularColor = GetSpecularColor(gBuffer);
|
|
||||||
|
|
||||||
// Calculate reflection color
|
// Calculate reflection color
|
||||||
float3 V = normalize(gBufferData.ViewPos - gBuffer.WorldPos);
|
reflections *= GetReflectionSpecularLighting(PreIntegratedGF, gBufferData.ViewPos, gBuffer);
|
||||||
float NoV = saturate(dot(gBuffer.Normal, V));
|
|
||||||
reflections *= EnvBRDF(PreIntegratedGF, specularColor, gBuffer.Roughness, NoV);
|
|
||||||
|
|
||||||
// Apply specular occlusion
|
|
||||||
float roughnessSq = gBuffer.Roughness * gBuffer.Roughness;
|
|
||||||
float specularOcclusion = GetSpecularOcclusion(NoV, roughnessSq, gBuffer.AO);
|
|
||||||
reflections *= specularOcclusion;
|
|
||||||
|
|
||||||
return float4(reflections, 0);
|
return float4(reflections, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define __REFLECTIONS_COMMON__
|
#define __REFLECTIONS_COMMON__
|
||||||
|
|
||||||
#include "./Flax/GBufferCommon.hlsl"
|
#include "./Flax/GBufferCommon.hlsl"
|
||||||
|
#include "./Flax/BRDF.hlsl"
|
||||||
|
|
||||||
// Hit depth (view space) threshold to detect if sky was hit (value above it where 1.0f is default)
|
// 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
|
#define REFLECTIONS_HIT_THRESHOLD 0.9f
|
||||||
@@ -48,15 +49,29 @@ float4 SampleReflectionProbe(float3 viewPos, TextureCube probe, ProbeData data,
|
|||||||
// Calculates the reflective environment lighting to multiply the raw reflection color for the specular light (eg. from Env Probe or SSR).
|
// Calculates the reflective environment lighting to multiply the raw reflection color for the specular light (eg. from Env Probe or SSR).
|
||||||
float3 GetReflectionSpecularLighting(float3 viewPos, GBufferSample gBuffer)
|
float3 GetReflectionSpecularLighting(float3 viewPos, GBufferSample gBuffer)
|
||||||
{
|
{
|
||||||
// Calculate reflection color
|
// Calculate reflection color
|
||||||
float3 specularColor = GetSpecularColor(gBuffer);
|
|
||||||
float3 V = normalize(viewPos - gBuffer.WorldPos);
|
float3 V = normalize(viewPos - gBuffer.WorldPos);
|
||||||
float NoV = saturate(dot(gBuffer.Normal, V));
|
float NoV = saturate(dot(gBuffer.Normal, V));
|
||||||
|
float3 specularColor = GetSpecularColor(gBuffer);
|
||||||
float3 reflections = EnvBRDFApprox(specularColor, gBuffer.Roughness, NoV);
|
float3 reflections = EnvBRDFApprox(specularColor, gBuffer.Roughness, NoV);
|
||||||
|
|
||||||
// Apply specular occlusion
|
// Apply specular occlusion
|
||||||
float roughnessSq = gBuffer.Roughness * gBuffer.Roughness;
|
float roughnessSq = gBuffer.Roughness * gBuffer.Roughness;
|
||||||
reflections *= GetSpecularOcclusion(NoV, roughnessSq, gBuffer.AO);
|
reflections *= GetSpecularOcclusion(NoV, roughnessSq, gBuffer.AO);
|
||||||
|
|
||||||
|
return reflections;
|
||||||
|
}
|
||||||
|
float3 GetReflectionSpecularLighting(Texture2D preIntegratedGF, float3 viewPos, GBufferSample gBuffer)
|
||||||
|
{
|
||||||
|
// Calculate reflection color
|
||||||
|
float3 V = normalize(viewPos - gBuffer.WorldPos);
|
||||||
|
float NoV = saturate(dot(gBuffer.Normal, V));
|
||||||
|
float3 specularColor = GetSpecularColor(gBuffer);
|
||||||
|
float3 reflections = EnvBRDF(preIntegratedGF, specularColor, gBuffer.Roughness, NoV);
|
||||||
|
|
||||||
|
// Apply specular occlusion
|
||||||
|
float roughnessSq = gBuffer.Roughness * gBuffer.Roughness;
|
||||||
|
reflections *= GetSpecularOcclusion(NoV, roughnessSq, gBuffer.AO);
|
||||||
|
|
||||||
return reflections;
|
return reflections;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,13 +81,8 @@ float4 PS_CombinePass(Quad_VS2PS input) : SV_Target0
|
|||||||
// Sample reflections buffer
|
// Sample reflections buffer
|
||||||
float3 reflections = SAMPLE_RT(Texture1, input.TexCoord).rgb;
|
float3 reflections = SAMPLE_RT(Texture1, input.TexCoord).rgb;
|
||||||
|
|
||||||
// Calculate specular color
|
|
||||||
float3 specularColor = GetSpecularColor(gBuffer);
|
|
||||||
|
|
||||||
// Calculate reflection color
|
// Calculate reflection color
|
||||||
float3 V = normalize(gBufferData.ViewPos - gBuffer.WorldPos);
|
light.rgb += reflections * GetReflectionSpecularLighting(Texture2, gBufferData.ViewPos, gBuffer);
|
||||||
float NoV = saturate(dot(gBuffer.Normal, V));
|
|
||||||
light.rgb += reflections * EnvBRDF(Texture2, specularColor, gBuffer.Roughness, NoV) * gBuffer.AO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return light;
|
return light;
|
||||||
|
|||||||
Reference in New Issue
Block a user