Add Transparent Lighting Modes for material with option to use non-directional shading

This commit is contained in:
Wojciech Figat
2022-07-14 09:21:09 +02:00
parent 047821f7d2
commit 85f351663b
14 changed files with 254 additions and 52 deletions

View File

@@ -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"

View File

@@ -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;
}

View File

@@ -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
{

View File

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

View File

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