From 85f351663bbc7074030b757e3be093fc4e3fd51c Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Thu, 14 Jul 2022 09:21:09 +0200 Subject: [PATCH] Add Transparent Lighting Modes for material with option to use non-directional shading --- .../Editor/Windows/Assets/MaterialWindow.cs | 7 ++- Source/Engine/Content/Assets/Material.cpp | 10 ++++ .../Content/Upgraders/ShaderAssetUpgrader.h | 47 ++++++++++++---- .../ContentImporters/CreateMaterial.cpp | 4 +- Source/Engine/Graphics/MaterialInfo.cs | 3 ++ .../Engine/Graphics/Materials/MaterialInfo.h | 54 +++++++++++++++++-- .../Graphics/Materials/MaterialParams.cpp | 36 ++++++++++++- .../Materials/MaterialShaderFeatures.cpp | 6 +-- .../Graphics/Shaders/Cache/ShaderStorage.h | 49 ++++++++++++++++- Source/Shaders/GI/GlobalSurfaceAtlas.shader | 2 +- Source/Shaders/Lighting.hlsl | 35 ++++++------ Source/Shaders/LightingCommon.hlsl | 10 ++++ Source/Shaders/Lights.shader | 20 +++---- Source/Shaders/ShadowsSampling.hlsl | 23 ++++++-- 14 files changed, 254 insertions(+), 52 deletions(-) diff --git a/Source/Editor/Windows/Assets/MaterialWindow.cs b/Source/Editor/Windows/Assets/MaterialWindow.cs index aea385967..2cad5dfca 100644 --- a/Source/Editor/Windows/Assets/MaterialWindow.cs +++ b/Source/Editor/Windows/Assets/MaterialWindow.cs @@ -78,7 +78,10 @@ namespace FlaxEditor.Windows.Assets // Transparency - [EditorOrder(200), DefaultValue(true), EditorDisplay("Transparency"), Tooltip("Enables reflections when rendering material.")] + [EditorOrder(200), DefaultValue(MaterialTransparentLightingMode.Surface), EditorDisplay("Transparency"), Tooltip("Transparent material lighting mode.")] + public MaterialTransparentLightingMode TransparentLightingMode; + + [EditorOrder(205), DefaultValue(true), EditorDisplay("Transparency"), Tooltip("Enables reflections when rendering material.")] public bool EnableReflections; [VisibleIf(nameof(EnableReflections))] @@ -161,6 +164,7 @@ namespace FlaxEditor.Windows.Assets MaxTessellationFactor = info.MaxTessellationFactor; MaskThreshold = info.MaskThreshold; DecalBlendingMode = info.DecalBlendingMode; + TransparentLightingMode = info.TransparentLightingMode; PostFxLocation = info.PostFxLocation; BlendMode = info.BlendMode; ShadingModel = info.ShadingModel; @@ -203,6 +207,7 @@ namespace FlaxEditor.Windows.Assets info.MaxTessellationFactor = MaxTessellationFactor; info.MaskThreshold = MaskThreshold; info.DecalBlendingMode = DecalBlendingMode; + info.TransparentLightingMode = TransparentLightingMode; info.PostFxLocation = PostFxLocation; info.BlendMode = BlendMode; info.ShadingModel = ShadingModel; diff --git a/Source/Engine/Content/Assets/Material.cpp b/Source/Engine/Content/Assets/Material.cpp index fba44b6f2..51eb8ba57 100644 --- a/Source/Engine/Content/Assets/Material.cpp +++ b/Source/Engine/Content/Assets/Material.cpp @@ -439,7 +439,17 @@ void Material::InitCompilationOptions(ShaderCompilationOptions& options) options.Macros.Add({ "MATERIAL_REFLECTIONS", Numbers[1] }); options.Macros.Add({ "USE_FOG", Numbers[info.FeaturesFlags & MaterialFeaturesFlags::DisableFog ? 0 : 1] }); if (useForward) + { options.Macros.Add({ "USE_PIXEL_NORMAL_OFFSET_REFRACTION", Numbers[info.FeaturesFlags & MaterialFeaturesFlags::PixelNormalOffsetRefraction ? 1 : 0] }); + switch (info.TransparentLightingMode) + { + case MaterialTransparentLightingMode::Surface: + break; + case MaterialTransparentLightingMode::SurfaceNonDirectional: + options.Macros.Add({ "LIGHTING_NO_DIRECTIONAL", "1" }); + break; + } + } // TODO: don't compile VS_Depth for deferred/forward materials if material doesn't use position offset or masking diff --git a/Source/Engine/Content/Upgraders/ShaderAssetUpgrader.h b/Source/Engine/Content/Upgraders/ShaderAssetUpgrader.h index 87cbc758d..8d26c9ccd 100644 --- a/Source/Engine/Content/Upgraders/ShaderAssetUpgrader.h +++ b/Source/Engine/Content/Upgraders/ShaderAssetUpgrader.h @@ -23,13 +23,14 @@ public: static const Upgrader upgraders[] = { { 18, 19, &Upgrade_18_To_19 }, + { 19, 20, &Upgrade_19_To_20 }, }; setup(upgraders, ARRAY_COUNT(upgraders)); } private: // ============================================ - // Version 18: + // Versions 18,19,20: // Designed: 7/24/2019 // Custom Data: Header // Chunk 0: Material Params @@ -38,20 +39,46 @@ private: // Chunk 14: Visject Surface data // Chunk 15: Source code: ANSI text (encrypted) // ============================================ - // Version 18: - // Designed: 9/13/2018 - // Custom Data: Header - // Chunk 0: Material Params - // Chunk 1: Internal SM5 cache - // Chunk 2: Internal SM4 cache - // Chunk 14: Visject Surface data - // Chunk 15: Source code: ANSI text (encrypted) - // ============================================ typedef ShaderStorage::Header Header; + typedef ShaderStorage::Header20 Header20; typedef ShaderStorage::Header19 Header19; typedef ShaderStorage::Header18 Header18; + static bool Upgrade_19_To_20(AssetMigrationContext& context) + { + ASSERT(context.Input.SerializedVersion == 19 && context.Output.SerializedVersion == 20); + + // Convert header + if (context.Input.CustomData.IsInvalid()) + return true; + auto& oldHeader = *(Header19*)context.Input.CustomData.Get(); + Header20 newHeader; + Platform::MemoryClear(&newHeader, sizeof(newHeader)); + if (context.Input.Header.TypeName == TEXT("FlaxEngine.ParticleEmitter")) + { + newHeader.ParticleEmitter.GraphVersion = oldHeader.ParticleEmitter.GraphVersion; + newHeader.ParticleEmitter.CustomDataSize = oldHeader.ParticleEmitter.CustomDataSize; + } + else if (context.Input.Header.TypeName == TEXT("FlaxEngine.Material")) + { + newHeader.Material.GraphVersion = oldHeader.Material.GraphVersion; + newHeader.Material.Info = oldHeader.Material.Info; + } + else if (context.Input.Header.TypeName == TEXT("FlaxEngine.Shader")) + { + } + else + { + LOG(Warning, "Unknown input asset type."); + return true; + } + context.Output.CustomData.Copy(&newHeader); + + // Copy all chunks + return CopyChunks(context); + } + static bool Upgrade_18_To_19(AssetMigrationContext& context) { ASSERT(context.Input.SerializedVersion == 18 && context.Output.SerializedVersion == 19); diff --git a/Source/Engine/ContentImporters/CreateMaterial.cpp b/Source/Engine/ContentImporters/CreateMaterial.cpp index 8689658c8..2a3441f7b 100644 --- a/Source/Engine/ContentImporters/CreateMaterial.cpp +++ b/Source/Engine/ContentImporters/CreateMaterial.cpp @@ -107,10 +107,10 @@ CreateMaterial::Options::Options() CreateAssetResult CreateMaterial::Create(CreateAssetContext& context) { // Base - IMPORT_SETUP(Material, 19); + IMPORT_SETUP(Material, 20); context.SkipMetadata = true; - ShaderStorage::Header19 shaderHeader; + ShaderStorage::Header20 shaderHeader; Platform::MemoryClear(&shaderHeader, sizeof(shaderHeader)); if (context.CustomArg) { diff --git a/Source/Engine/Graphics/MaterialInfo.cs b/Source/Engine/Graphics/MaterialInfo.cs index 1ebe7d9c8..b01ea5b43 100644 --- a/Source/Engine/Graphics/MaterialInfo.cs +++ b/Source/Engine/Graphics/MaterialInfo.cs @@ -18,6 +18,7 @@ namespace FlaxEngine UsageFlags = MaterialUsageFlags.None, FeaturesFlags = MaterialFeaturesFlags.None, DecalBlendingMode = MaterialDecalBlendingMode.Translucent, + TransparentLightingMode = MaterialTransparentLightingMode.SurfaceNonDirectional, PostFxLocation = MaterialPostFxLocation.AfterPostProcessingPass, MaskThreshold = 0.3f, OpacityThreshold = 0.12f, @@ -61,6 +62,7 @@ namespace FlaxEngine && UsageFlags == other.UsageFlags && FeaturesFlags == other.FeaturesFlags && DecalBlendingMode == other.DecalBlendingMode + && TransparentLightingMode == other.TransparentLightingMode && PostFxLocation == other.PostFxLocation && Mathf.NearEqual(MaskThreshold, other.MaskThreshold) && Mathf.NearEqual(OpacityThreshold, other.OpacityThreshold) @@ -86,6 +88,7 @@ namespace FlaxEngine hashCode = (hashCode * 397) ^ (int)FeaturesFlags; hashCode = (hashCode * 397) ^ (int)PostFxLocation; hashCode = (hashCode * 397) ^ (int)DecalBlendingMode; + hashCode = (hashCode * 397) ^ (int)TransparentLightingMode; hashCode = (hashCode * 397) ^ (int)(MaskThreshold * 1000.0f); hashCode = (hashCode * 397) ^ (int)(OpacityThreshold * 1000.0f); hashCode = (hashCode * 397) ^ (int)TessellationMode; diff --git a/Source/Engine/Graphics/Materials/MaterialInfo.h b/Source/Engine/Graphics/Materials/MaterialInfo.h index a3de6be0b..3bf12ca7c 100644 --- a/Source/Engine/Graphics/Materials/MaterialInfo.h +++ b/Source/Engine/Graphics/Materials/MaterialInfo.h @@ -355,6 +355,22 @@ API_ENUM() enum class MaterialDecalBlendingMode : byte Emissive = 3, }; +/// +/// Transparent material lighting modes. +/// +API_ENUM() enum class MaterialTransparentLightingMode : byte +{ + /// + /// Default directional lighting evaluated per-pixel at the material surface. Use it for semi-transparent surfaces - with both diffuse and specular lighting component active. + /// + Surface = 0, + + /// + /// Non-directional lighting evaluated per-pixel at material surface. Use it for volumetric objects such as smoke, rain or dust - only diffuse lighting term is active (no specular highlights). + /// + SurfaceNonDirectional = 1, +}; + /// /// Material input scene textures. Special inputs from the graphics pipeline. /// @@ -441,6 +457,33 @@ struct MaterialInfo8 bool operator==(const MaterialInfo8& other) const; }; +/// +/// Material info structure - version 9 +/// [Deprecated on 13.07.2022, expires on 13.07.2024] +/// +struct MaterialInfo9 +{ + MaterialDomain Domain; + MaterialBlendMode BlendMode; + MaterialShadingModel ShadingModel; + MaterialUsageFlags UsageFlags; + MaterialFeaturesFlags FeaturesFlags; + MaterialDecalBlendingMode DecalBlendingMode; + MaterialPostFxLocation PostFxLocation; + CullMode CullMode; + float MaskThreshold; + float OpacityThreshold; + TessellationMethod TessellationMode; + int32 MaxTessellationFactor; + + MaterialInfo9() + { + } + + MaterialInfo9(const MaterialInfo8& other); + bool operator==(const MaterialInfo9& other) const; +}; + /// /// Structure with basic information about the material surface. It describes how material is reacting on light and which graphical features of it requires to render. /// @@ -478,6 +521,11 @@ API_STRUCT() struct FLAXENGINE_API MaterialInfo /// API_FIELD() MaterialDecalBlendingMode DecalBlendingMode; + /// + /// The transparent material lighting mode. + /// + API_FIELD() MaterialTransparentLightingMode TransparentLightingMode; + /// /// The post fx material rendering location. /// @@ -512,10 +560,10 @@ API_STRUCT() struct FLAXENGINE_API MaterialInfo { } - MaterialInfo(const MaterialInfo8& other); + MaterialInfo(const MaterialInfo9& other); bool operator==(const MaterialInfo& other) const; }; // The current material info descriptor version used by the material pipeline -typedef MaterialInfo MaterialInfo9; -#define MaterialInfo_Version 9 +typedef MaterialInfo MaterialInfo10; +#define MaterialInfo_Version 10 diff --git a/Source/Engine/Graphics/Materials/MaterialParams.cpp b/Source/Engine/Graphics/Materials/MaterialParams.cpp index 790aa6588..7c3e9d2d0 100644 --- a/Source/Engine/Graphics/Materials/MaterialParams.cpp +++ b/Source/Engine/Graphics/Materials/MaterialParams.cpp @@ -30,7 +30,7 @@ bool MaterialInfo8::operator==(const MaterialInfo8& other) const && MaxTessellationFactor == other.MaxTessellationFactor; } -MaterialInfo::MaterialInfo(const MaterialInfo8& other) +MaterialInfo9::MaterialInfo9(const MaterialInfo8& other) { Domain = other.Domain; BlendMode = other.BlendMode; @@ -78,6 +78,39 @@ MaterialInfo::MaterialInfo(const MaterialInfo8& other) MaxTessellationFactor = other.MaxTessellationFactor; } +bool MaterialInfo9::operator==(const MaterialInfo9& other) const +{ + return Domain == other.Domain + && BlendMode == other.BlendMode + && ShadingModel == other.ShadingModel + && UsageFlags == other.UsageFlags + && FeaturesFlags == other.FeaturesFlags + && DecalBlendingMode == other.DecalBlendingMode + && PostFxLocation == other.PostFxLocation + && CullMode == other.CullMode + && Math::NearEqual(MaskThreshold, other.MaskThreshold) + && Math::NearEqual(OpacityThreshold, other.OpacityThreshold) + && TessellationMode == other.TessellationMode + && MaxTessellationFactor == other.MaxTessellationFactor; +} + +MaterialInfo::MaterialInfo(const MaterialInfo9& other) +{ + Domain = other.Domain; + BlendMode = other.BlendMode; + ShadingModel = other.ShadingModel; + UsageFlags = other.UsageFlags; + FeaturesFlags = other.FeaturesFlags; + DecalBlendingMode = other.DecalBlendingMode; + TransparentLightingMode = MaterialTransparentLightingMode::Surface; + PostFxLocation = other.PostFxLocation; + CullMode = other.CullMode; + MaskThreshold = other.MaskThreshold; + OpacityThreshold = other.OpacityThreshold; + TessellationMode = other.TessellationMode; + MaxTessellationFactor = other.MaxTessellationFactor; +} + bool MaterialInfo::operator==(const MaterialInfo& other) const { return Domain == other.Domain @@ -86,6 +119,7 @@ bool MaterialInfo::operator==(const MaterialInfo& other) const && UsageFlags == other.UsageFlags && FeaturesFlags == other.FeaturesFlags && DecalBlendingMode == other.DecalBlendingMode + && TransparentLightingMode == other.TransparentLightingMode && PostFxLocation == other.PostFxLocation && CullMode == other.CullMode && Math::NearEqual(MaskThreshold, other.MaskThreshold) diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index dbd934a8e..8debde3eb 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -76,7 +76,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, SpanEnvironmentProbes.Count(); i++) { const auto p = cache->EnvironmentProbes[i]; @@ -103,7 +103,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, SpanPointLights.Count() && data.LocalLightsCount < MaxLocalLights; i++) { const auto& light = cache->PointLights[i]; - if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint) + if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.ObjectPosition) != ContainmentType::Disjoint) { light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false); data.LocalLightsCount++; @@ -112,7 +112,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, SpanSpotLights.Count() && data.LocalLightsCount < MaxLocalLights; i++) { const auto& light = cache->SpotLights[i]; - if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint) + if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.ObjectPosition) != ContainmentType::Disjoint) { light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false); data.LocalLightsCount++; diff --git a/Source/Engine/Graphics/Shaders/Cache/ShaderStorage.h b/Source/Engine/Graphics/Shaders/Cache/ShaderStorage.h index 8d504d3c3..3fabbb5b7 100644 --- a/Source/Engine/Graphics/Shaders/Cache/ShaderStorage.h +++ b/Source/Engine/Graphics/Shaders/Cache/ShaderStorage.h @@ -69,9 +69,9 @@ public: /// MaterialInfo8 MaterialInfo; }; - /// /// File header, version 19 +/// [Deprecated on 13.07.2022, expires on 13.07.2024] /// struct Header19 { @@ -115,8 +115,53 @@ public: } }; + /// + /// File header, version 20 + /// + struct Header20 + { + static const int32 Version = 20; + + union + { + struct + { + } Shader; + + struct + { + /// + /// The material graph version. + /// + int32 GraphVersion; + + /// + /// The material additional information. + /// + MaterialInfo10 Info; + } Material; + + struct + { + /// + /// The particle emitter graph version. + /// + int32 GraphVersion; + + /// + /// The custom particles data size (in bytes). + /// + int32 CustomDataSize; + } ParticleEmitter; + }; + + Header20() + { + } + }; + /// /// Current header type /// - typedef Header19 Header; + typedef Header20 Header; }; diff --git a/Source/Shaders/GI/GlobalSurfaceAtlas.shader b/Source/Shaders/GI/GlobalSurfaceAtlas.shader index 730ecc9ef..70b5ee9dc 100644 --- a/Source/Shaders/GI/GlobalSurfaceAtlas.shader +++ b/Source/Shaders/GI/GlobalSurfaceAtlas.shader @@ -1,7 +1,7 @@ // Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. // Diffuse-only lighting -#define NO_SPECULAR 1 +#define LIGHTING_NO_SPECULAR 1 #include "./Flax/Common.hlsl" #include "./Flax/Math.hlsl" diff --git a/Source/Shaders/Lighting.hlsl b/Source/Shaders/Lighting.hlsl index af1b193a0..e7d168d8a 100644 --- a/Source/Shaders/Lighting.hlsl +++ b/Source/Shaders/Lighting.hlsl @@ -5,10 +5,6 @@ #include "./Flax/LightingCommon.hlsl" -#ifndef NO_SPECULAR -#define NO_SPECULAR 0 -#endif - ShadowData GetShadow(LightData lightData, GBufferSample gBuffer, float4 shadowMask) { ShadowData shadow; @@ -28,7 +24,7 @@ LightingData StandardShading(GBufferSample gBuffer, float energy, float3 L, floa LightingData lighting; lighting.Diffuse = Diffuse_Lambert(diffuseColor); -#if NO_SPECULAR +#if LIGHTING_NO_SPECULAR lighting.Specular = 0; #else float3 specularColor = GetSpecularColor(gBuffer); @@ -95,7 +91,12 @@ float4 GetSkyLightLighting(LightData lightData, GBufferSample gBuffer, TextureCu // Compute the preconvolved incoming lighting with the normal direction (apply ambient color) // Some data is packed, see C++ RendererSkyLightData::SetupLightData float mip = lightData.SourceLength; - float3 diffuseLookup = ibl.SampleLevel(SamplerLinearClamp, gBuffer.Normal, mip).rgb * lightData.Color.rgb; +#if LIGHTING_NO_DIRECTIONAL + float3 uvw = float3(0, 0, 0); +#else + float3 uvw = gBuffer.Normal; +#endif + float3 diffuseLookup = ibl.SampleLevel(SamplerLinearClamp, uvw, mip).rgb * lightData.Color.rgb; diffuseLookup += float3(lightData.SpotAngles.rg, lightData.SourceRadius); // Fade out based on distance to capture @@ -117,26 +118,28 @@ float4 GetLighting(float3 viewPos, LightData lightData, GBufferSample gBuffer, f float3 N = gBuffer.Normal; float3 L = lightData.Direction; // no need to normalize float NoL = saturate(dot(N, L)); - float distanceAttenuation = 1; - float lightRadiusMask = 1; - float spotAttenuation = 1; float3 toLight = lightData.Direction; + // Calculate shadow + ShadowData shadow = GetShadow(lightData, gBuffer, shadowMask); + // Calculate attenuation if (isRadial) { toLight = lightData.Position - gBuffer.WorldPos; float distanceSqr = dot(toLight, toLight); L = toLight * rsqrt(distanceSqr); + float distanceAttenuation = 1, lightRadiusMask = 1, spotAttenuation = 1; GetRadialLightAttenuation(lightData, isSpotLight, N, distanceSqr, 1, toLight, L, NoL, distanceAttenuation, lightRadiusMask, spotAttenuation); + float attenuation = distanceAttenuation * lightRadiusMask * spotAttenuation; + shadow.SurfaceShadow *= attenuation; + shadow.TransmissionShadow *= attenuation; } - float attenuation = distanceAttenuation * lightRadiusMask * spotAttenuation; - - // Calculate shadow - ShadowData shadow = GetShadow(lightData, gBuffer, shadowMask); +#if !LIGHTING_NO_DIRECTIONAL // Reduce shadow mapping artifacts - shadow.SurfaceShadow *= saturate(NoL * 6.0f - 0.2f); + shadow.SurfaceShadow *= saturate(NoL * 6.0f - 0.2f) * NoL; +#endif BRANCH if (shadow.SurfaceShadow + shadow.TransmissionShadow > 0) @@ -148,8 +151,8 @@ float4 GetLighting(float3 viewPos, LightData lightData, GBufferSample gBuffer, f LightingData lighting = SurfaceShading(gBuffer, energy, L, V, N); // Calculate final light color - float3 surfaceLight = (lighting.Diffuse + lighting.Specular) * (NoL * attenuation * shadow.SurfaceShadow); - float3 subsurfaceLight = lighting.Transmission * (attenuation * shadow.TransmissionShadow); + float3 surfaceLight = (lighting.Diffuse + lighting.Specular) * shadow.SurfaceShadow; + float3 subsurfaceLight = lighting.Transmission * shadow.TransmissionShadow; result.rgb = lightData.Color * (surfaceLight + subsurfaceLight); result.a = 1; } diff --git a/Source/Shaders/LightingCommon.hlsl b/Source/Shaders/LightingCommon.hlsl index 1015cf536..f58871512 100644 --- a/Source/Shaders/LightingCommon.hlsl +++ b/Source/Shaders/LightingCommon.hlsl @@ -6,6 +6,16 @@ #include "./Flax/BRDF.hlsl" #include "./Flax/GBufferCommon.hlsl" +// Disables directional lighting (no shadowing with dot(N, L), eg. for smoke particles) +#ifndef LIGHTING_NO_DIRECTIONAL +#define LIGHTING_NO_DIRECTIONAL 0 +#endif + +// Disables specular lighting (diffuse-only) +#ifndef LIGHTING_NO_SPECULAR +#define LIGHTING_NO_SPECULAR 0 +#endif + // Structure that contains information about light struct LightData { diff --git a/Source/Shaders/Lights.shader b/Source/Shaders/Lights.shader index 0e09ecb2d..afc593d63 100644 --- a/Source/Shaders/Lights.shader +++ b/Source/Shaders/Lights.shader @@ -40,8 +40,8 @@ Model_VS2PS VS_Model(ModelInput_PosOnly input) // Pixel shader for directional light rendering META_PS(true, FEATURE_LEVEL_ES2) -META_PERMUTATION_1(NO_SPECULAR=0) -META_PERMUTATION_1(NO_SPECULAR=1) +META_PERMUTATION_1(LIGHTING_NO_SPECULAR=0) +META_PERMUTATION_1(LIGHTING_NO_SPECULAR=1) void PS_Directional(Quad_VS2PS input, out float4 output : SV_Target0) { output = 0; @@ -72,10 +72,10 @@ void PS_Directional(Quad_VS2PS input, out float4 output : SV_Target0) // Pixel shader for point light rendering META_PS(true, FEATURE_LEVEL_ES2) -META_PERMUTATION_2(NO_SPECULAR=0, USE_IES_PROFILE=0) -META_PERMUTATION_2(NO_SPECULAR=1, USE_IES_PROFILE=0) -META_PERMUTATION_2(NO_SPECULAR=0, USE_IES_PROFILE=1) -META_PERMUTATION_2(NO_SPECULAR=1, USE_IES_PROFILE=1) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=0, USE_IES_PROFILE=0) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=1, USE_IES_PROFILE=0) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=0, USE_IES_PROFILE=1) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=1, USE_IES_PROFILE=1) void PS_Point(Model_VS2PS input, out float4 output : SV_Target0) { output = 0; @@ -114,10 +114,10 @@ void PS_Point(Model_VS2PS input, out float4 output : SV_Target0) // Pixel shader for spot light rendering META_PS(true, FEATURE_LEVEL_ES2) -META_PERMUTATION_2(NO_SPECULAR=0, USE_IES_PROFILE=0) -META_PERMUTATION_2(NO_SPECULAR=1, USE_IES_PROFILE=0) -META_PERMUTATION_2(NO_SPECULAR=0, USE_IES_PROFILE=1) -META_PERMUTATION_2(NO_SPECULAR=1, USE_IES_PROFILE=1) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=0, USE_IES_PROFILE=0) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=1, USE_IES_PROFILE=0) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=0, USE_IES_PROFILE=1) +META_PERMUTATION_2(LIGHTING_NO_SPECULAR=1, USE_IES_PROFILE=1) void PS_Spot(Model_VS2PS input, out float4 output : SV_Target0) { output = 0; diff --git a/Source/Shaders/ShadowsSampling.hlsl b/Source/Shaders/ShadowsSampling.hlsl index bf608a0c5..9a5dfd28f 100644 --- a/Source/Shaders/ShadowsSampling.hlsl +++ b/Source/Shaders/ShadowsSampling.hlsl @@ -458,6 +458,9 @@ float SampleShadow(LightData light, LightShadowData shadow, Texture2DArray shado } #endif + float3 samplePosWS = gBuffer.WorldPos; + +#if !LIGHTING_NO_DIRECTIONAL // Skip if surface is in a full shadow float NoL = dot(gBuffer.Normal, light.Direction); BRANCH @@ -467,8 +470,8 @@ float SampleShadow(LightData light, LightShadowData shadow, Texture2DArray shado } // Apply normal offset bias - float3 samplePosWS = gBuffer.WorldPos; samplePosWS += GetShadowPositionOffset(shadow.NormalOffsetScale, NoL, gBuffer.Normal); +#endif // Sample shadow return SampleShadow(light, shadow, shadowMap, samplePosWS, viewDepth); @@ -480,7 +483,11 @@ float SampleShadow(LightData light, LightShadowData shadow, Texture2D shadowMap, float3 toLight = light.Position - worldPosition; float toLightLength = length(toLight); float3 L = toLight / toLightLength; +#if LIGHTING_NO_DIRECTIONAL + float dirCheck = 1.0f; +#else float dirCheck = dot(-light.Direction, L); +#endif // Skip pixels outside of the light influence BRANCH @@ -539,7 +546,11 @@ float SampleShadow(LightData light, LightShadowData shadow, Texture2D shadowMap, float3 toLight = light.Position - gBuffer.WorldPos; float toLightLength = length(toLight); float3 L = toLight / toLightLength; +#if LIGHTING_NO_DIRECTIONAL + float dirCheck = 1.0f; +#else float dirCheck = dot(-light.Direction, L); +#endif // Skip pixels outside of the light influence BRANCH @@ -569,7 +580,10 @@ float SampleShadow(LightData light, LightShadowData shadow, Texture2D shadowMap, subsurfaceShadow = lerp(1.0f, subsurfaceShadow, shadow.Fade); } #endif + + float3 samplePosWS = gBuffer.WorldPos; +#if !LIGHTING_NO_DIRECTIONAL // Skip if surface is in a full shadow float NoL = dot(gBuffer.Normal, L); BRANCH @@ -579,8 +593,8 @@ float SampleShadow(LightData light, LightShadowData shadow, Texture2D shadowMap, } // Apply normal offset bias - float3 samplePosWS = gBuffer.WorldPos; samplePosWS += GetShadowPositionOffset(shadow.NormalOffsetScale, NoL, gBuffer.Normal); +#endif // Sample shadow return SampleShadow(light, shadow, shadowMap, samplePosWS); @@ -686,7 +700,10 @@ float SampleShadow(LightData light, LightShadowData shadow, TextureCube s subsurfaceShadow = lerp(1.0f, subsurfaceShadow, shadow.Fade); } #endif + + float3 samplePosWS = gBuffer.WorldPos; +#if !LIGHTING_NO_DIRECTIONAL // Skip if surface is in a full shadow float NoL = dot(gBuffer.Normal, L); BRANCH @@ -696,8 +713,8 @@ float SampleShadow(LightData light, LightShadowData shadow, TextureCube s } // Apply normal offset bias - float3 samplePosWS = gBuffer.WorldPos; samplePosWS += GetShadowPositionOffset(shadow.NormalOffsetScale, NoL, gBuffer.Normal); +#endif // Sample shadow return SampleShadow(light, shadow, shadowMap, samplePosWS);