diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index e1b884734..acfff13ad 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -28,6 +28,7 @@ TextureCube SkyLightTexture : register(t__SRV__); Buffer ShadowsBuffer : register(t__SRV__); Texture2D ShadowMap : register(t__SRV__); Texture3D VolumetricFogTexture : register(t__SRV__); +Texture2D PreIntegratedGF : register(t__SRV__); @4// Forward Shading: Utilities // Public accessors for lighting data, use them as data binding might change but those methods will remain. LightData GetDirectionalLight() { return DirectionalLight; } @@ -108,7 +109,8 @@ void PS_Forward( // Calculate 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 // Screen Space Reflections @@ -124,7 +126,7 @@ void PS_Forward( if (hit.z > 0) { 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 @@ -136,13 +138,13 @@ void PS_Forward( if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas)) { 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 - light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a; + light.rgb += reflections.rgb * GetReflectionSpecularLighting(PreIntegratedGF, ViewPos, gBuffer); #endif // Add lighting @@ -158,7 +160,8 @@ void PS_Forward( #else float fogSceneDistance = gBuffer.ViewPos.z; #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) { diff --git a/Source/Engine/Graphics/Materials/MaterialShader.h b/Source/Engine/Graphics/Materials/MaterialShader.h index bb68520c0..9c01cf2d0 100644 --- a/Source/Engine/Graphics/Materials/MaterialShader.h +++ b/Source/Engine/Graphics/Materials/MaterialShader.h @@ -10,7 +10,7 @@ /// /// Current materials shader version. /// -#define MATERIAL_GRAPH_VERSION 179 +#define MATERIAL_GRAPH_VERSION 180 class Material; class GPUShader; diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index 19f2042f4..bf8e92e79 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -10,9 +10,11 @@ #if USE_EDITOR #include "Engine/Renderer/Lightmaps.h" #endif +#include "Engine/Content/Content.h" #include "Engine/Graphics/GPUContext.h" #include "Engine/Level/Scene/Lightmap.h" #include "Engine/Level/Actors/EnvironmentProbe.h" +#include "Engine/Renderer/ReflectionsPass.h" void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span& cb, int32& srv) { @@ -26,6 +28,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, SpanBindSR(volumetricFogTextureRegisterIndex, volumetricFogTexture); @@ -100,9 +104,12 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, SpanUnBindSR(envProbeShaderRegisterIndex); } + // TODO: find a better way to find this texture (eg. cache GPUTextureView* handle within ForwardShading cache for a whole frame) + static AssetReference PreIntegratedGF = Content::LoadAsyncInternal(PRE_INTEGRATED_GF_ASSET_NAME); + params.GPUContext->BindSR(preIntegratedGFRegisterIndex, PreIntegratedGF->GetTexture()); // Set local lights data.LocalLightsCount = 0; diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h index 54b91af23..5eab262ce 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h @@ -25,10 +25,9 @@ struct ForwardShadingFeature : MaterialShaderFeature { enum { MaxLocalLights = 4 }; - enum { SRVs = 5 }; + enum { SRVs = 6 }; - PACK_STRUCT(struct Data - { + PACK_STRUCT(struct Data { ShaderLightData DirectionalLight; ShaderLightData SkyLight; ShaderEnvProbeData EnvironmentProbe; @@ -76,8 +75,7 @@ struct GlobalIlluminationFeature : MaterialShaderFeature { enum { SRVs = 3 }; - PACK_STRUCT(struct Data - { + PACK_STRUCT(struct Data { DynamicDiffuseGlobalIlluminationPass::ConstantsData DDGI; }); @@ -92,13 +90,10 @@ struct SDFReflectionsFeature : MaterialShaderFeature { enum { SRVs = 7 }; - PACK_STRUCT(struct Data - { + PACK_STRUCT(struct Data { GlobalSignDistanceFieldPass::ConstantsData GlobalSDF; GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas; - }); - - + }); static bool Bind(MaterialShader::BindParameters& params, Span& cb, int32& srv); #if USE_EDITOR diff --git a/Source/Shaders/Reflections.shader b/Source/Shaders/Reflections.shader index c257ca35b..a7ec44638 100644 --- a/Source/Shaders/Reflections.shader +++ b/Source/Shaders/Reflections.shader @@ -76,18 +76,8 @@ float4 PS_CombinePass(Quad_VS2PS input) : SV_Target0 // Sample reflections buffer float3 reflections = SAMPLE_RT(Reflections, input.TexCoord).rgb; - // Calculate specular color - float3 specularColor = GetSpecularColor(gBuffer); - // Calculate reflection color - float3 V = normalize(gBufferData.ViewPos - gBuffer.WorldPos); - 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; + reflections *= GetReflectionSpecularLighting(PreIntegratedGF, gBufferData.ViewPos, gBuffer); return float4(reflections, 0); } diff --git a/Source/Shaders/ReflectionsCommon.hlsl b/Source/Shaders/ReflectionsCommon.hlsl index 4abf295c6..26ae965d6 100644 --- a/Source/Shaders/ReflectionsCommon.hlsl +++ b/Source/Shaders/ReflectionsCommon.hlsl @@ -4,6 +4,7 @@ #define __REFLECTIONS_COMMON__ #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) #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). float3 GetReflectionSpecularLighting(float3 viewPos, GBufferSample gBuffer) { - // Calculate reflection color - float3 specularColor = GetSpecularColor(gBuffer); + // Calculate reflection color float3 V = normalize(viewPos - gBuffer.WorldPos); float NoV = saturate(dot(gBuffer.Normal, V)); + float3 specularColor = GetSpecularColor(gBuffer); float3 reflections = EnvBRDFApprox(specularColor, gBuffer.Roughness, NoV); - - // Apply specular occlusion - float roughnessSq = gBuffer.Roughness * gBuffer.Roughness; - reflections *= GetSpecularOcclusion(NoV, roughnessSq, gBuffer.AO); + + // Apply specular occlusion + float roughnessSq = gBuffer.Roughness * gBuffer.Roughness; + 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; } diff --git a/Source/Shaders/SSR.shader b/Source/Shaders/SSR.shader index 3a7f52f7c..f2c863dfd 100644 --- a/Source/Shaders/SSR.shader +++ b/Source/Shaders/SSR.shader @@ -81,13 +81,8 @@ float4 PS_CombinePass(Quad_VS2PS input) : SV_Target0 // Sample reflections buffer float3 reflections = SAMPLE_RT(Texture1, input.TexCoord).rgb; - // Calculate specular color - float3 specularColor = GetSpecularColor(gBuffer); - // Calculate reflection color - float3 V = normalize(gBufferData.ViewPos - gBuffer.WorldPos); - float NoV = saturate(dot(gBuffer.Normal, V)); - light.rgb += reflections * EnvBRDF(Texture2, specularColor, gBuffer.Roughness, NoV) * gBuffer.AO; + light.rgb += reflections * GetReflectionSpecularLighting(Texture2, gBufferData.ViewPos, gBuffer); } return light;