Add Transparent Lighting Modes for material with option to use non-directional shading
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<float> 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<float> 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);
|
||||
|
||||
Reference in New Issue
Block a user