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);