Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cloud shadows #172

Merged
merged 13 commits into from
Feb 6, 2024
51 changes: 51 additions & 0 deletions features/Cloud Shadows/Shaders/CloudShadows/CloudShadows.hlsli
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
struct PerPassCloudShadow
{
uint EnableCloudShadows;

float CloudHeight;
float PlanetRadius;

float ShadowBlend;
float DiffuseLightBrightness;
float DiffuseLightSaturation;

float RcpHPlusR;
};

StructuredBuffer<PerPassCloudShadow> perPassCloudShadow : register(t23);
TextureCube<float4> cloudShadows : register(t40);

float3 getCloudShadowSampleDir(float3 rel_pos, float3 eye_to_sun)
{
float r = perPassCloudShadow[0].PlanetRadius;
float3 p = (rel_pos + float3(0, 0, r)) * perPassCloudShadow[0].RcpHPlusR;
float dotprod = dot(p, eye_to_sun);
float lengthsqr = dot(p, p);
float t = -dotprod + sqrt(dotprod * dotprod - dot(p, p) + 1);
float3 v = (p + eye_to_sun * t) * (r + perPassCloudShadow[0].CloudHeight) - float3(0, 0, r);
v = normalize(v);
return v;
}

float3 getCloudShadowSampleDirFlatEarth(float3 rel_pos, float3 eye_to_sun)
{
float3 p = rel_pos / perPassCloudShadow[0].CloudHeight;
float dotprod = dot(p, eye_to_sun);
float t = -dotprod + sqrt(dotprod * dotprod - dot(p, p) + 1);
float3 v = p + eye_to_sun * t;
v = normalize(v); // optional
return v;
}

float3 getCloudShadowMult(float3 rel_pos, float3 eye_to_sun, SamplerState samp)
{
// float3 cloudSampleDir = getCloudShadowSampleDirFlatEarth(rel_pos, eye_to_sun).xyz;
float3 cloudSampleDir = getCloudShadowSampleDir(rel_pos, eye_to_sun).xyz;

float4 cloudCubeSample = cloudShadows.Sample(samp, cloudSampleDir);
float3 cloudDiffuseLight = cloudCubeSample.xyz * perPassCloudShadow[0].DiffuseLightBrightness;
cloudDiffuseLight = saturate(lerp(dot(cloudDiffuseLight, float3(0.2125, 0.7154, 0.0721)), cloudDiffuseLight, perPassCloudShadow[0].DiffuseLightSaturation));
float cloudShadowBlend = lerp(0, saturate(cloudCubeSample.w), perPassCloudShadow[0].ShadowBlend);

return lerp(1.0, cloudDiffuseLight, cloudShadowBlend);
}
2 changes: 2 additions & 0 deletions features/Cloud Shadows/Shaders/Features/CloudShadows.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Info]
Version = 1-0-0
20 changes: 20 additions & 0 deletions features/Grass Lighting/Shaders/RunGrass.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
#include "Common/FrameBuffer.hlsl"
#include "Common/MotionBlur.hlsl"

struct LightingData
alandtse marked this conversation as resolved.
Show resolved Hide resolved
{
float WaterHeight[25];
bool Reflections;
};

StructuredBuffer<LightingData> lightingData : register(t126);

#define GRASS

struct VS_INPUT
Expand Down Expand Up @@ -355,6 +363,10 @@ float3x3 CalculateTBN(float3 N, float3 p, float2 uv)
# include "DynamicCubemaps/DynamicCubemaps.hlsli"
# endif

# if defined(CLOUD_SHADOWS)
# include "CloudShadows/CloudShadows.hlsli"
# endif

PS_OUTPUT main(PS_INPUT input, bool frontFace
: SV_IsFrontFace)
{
Expand Down Expand Up @@ -435,6 +447,14 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
dirLightColor *= SunlightScale;
}

# if defined(CLOUD_SHADOWS)
float3 cloudShadowMult = 1.0;
if (perPassCloudShadow[0].EnableCloudShadows && !lightingData[0].Reflections) {
cloudShadowMult = getCloudShadowMult(input.WorldPosition.xyz, DirLightDirection.xyz, SampColorSampler);
dirLightColor *= cloudShadowMult;
}
# endif

dirLightColor *= shadowColor.x;

# if defined(SCREEN_SPACE_SHADOWS)
Expand Down
26 changes: 26 additions & 0 deletions features/Tree LOD Lighting/Shaders/DistantTree.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
#include "Common/FrameBuffer.hlsl"
#include "Common/MotionBlur.hlsl"

struct LightingData
{
float WaterHeight[25];
bool Reflections;
};

StructuredBuffer<LightingData> lightingData : register(t126);

cbuffer PerFrame : register(b3)
{
row_major float3x4 DirectionalAmbient;
Expand Down Expand Up @@ -36,6 +44,8 @@ struct VS_OUTPUT
float4 PreviousWorldPosition : POSITION2;
#endif
float3 SphereNormal : TEXCOORD4;

row_major float3x4 World : POSITION3;
};

#ifdef VSHADER
Expand Down Expand Up @@ -82,6 +92,8 @@ VS_OUTPUT main(VS_INPUT input)

vsout.SphereNormal.xyz = mul(World, normalize(adjustedModelPosition));

vsout.World = World;

return vsout;
}
#endif
Expand Down Expand Up @@ -174,6 +186,10 @@ Texture2D<float4> TexShadowMaskSampler : register(t17);
# include "ScreenSpaceShadows/ShadowsPS.hlsli"
# endif

# if defined(CLOUD_SHADOWS)
# include "CloudShadows/CloudShadows.hlsli"
# endif

PS_OUTPUT main(PS_INPUT input, bool frontFace
: SV_IsFrontFace)
{
Expand Down Expand Up @@ -243,6 +259,16 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
dirLightColor *= DirLightScale;
}

# if defined(CLOUD_SHADOWS)
float3 normalizedDirLightDirectionWS = -normalize(mul(input.World, float4(DirLightDirection.xyz, 0))).xyz;

float3 cloudShadowMult = 1.0;
if (perPassCloudShadow[0].EnableCloudShadows && !lightingData[0].Reflections) {
cloudShadowMult = getCloudShadowMult(input.WorldPosition.xyz, normalizedDirLightDirectionWS.xyz, SampDiffuse);
dirLightColor *= cloudShadowMult;
}
# endif

float3 nsDirLightColor = dirLightColor;

# if defined(SCREEN_SPACE_SHADOWS)
Expand Down
28 changes: 23 additions & 5 deletions package/Shaders/Lighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,10 @@ float2 ComputeTriplanarUV(float3 InputPosition)
# include "WetnessEffects/WetnessEffects.hlsli"
# endif

# if defined(CLOUD_SHADOWS)
# include "CloudShadows/CloudShadows.hlsli"
# endif

PS_OUTPUT main(PS_INPUT input, bool frontFace
: SV_IsFrontFace)
{
Expand Down Expand Up @@ -1441,6 +1445,21 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
float3 dirLightColor = DirLightColor.xyz;
float selfShadowFactor = 1.0f;

float3 normalizedDirLightDirectionWS = DirLightDirection;
# if ((defined(SKINNED) || !defined(MODELSPACENORMALS)) && !defined(DRAW_IN_WORLDSPACE))
normalizedDirLightDirectionWS = lerp(normalize(mul(input.World[eyeIndex], float4(DirLightDirection, 0))), normalizedDirLightDirectionWS, input.WorldSpace);
// temp fix for tree barks
normalizedDirLightDirectionWS = any(isnan(normalizedDirLightDirectionWS)) ? DirLightDirection : normalizedDirLightDirectionWS;
# endif

# if defined(CLOUD_SHADOWS)
float3 cloudShadowMult = 1.0;
if (perPassCloudShadow[0].EnableCloudShadows && !lightingData[0].Reflections) {
cloudShadowMult = getCloudShadowMult(input.WorldPosition.xyz, normalizedDirLightDirectionWS, SampColorSampler);
dirLightColor *= cloudShadowMult;
}
# endif

float3 nsDirLightColor = dirLightColor;

if ((shaderDescriptors[0].PixelShaderDescriptor & _DefShadow) && (shaderDescriptors[0].PixelShaderDescriptor & _ShadowDir))
Expand Down Expand Up @@ -1519,7 +1538,6 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
screenSpaceNormal = normalize(screenSpaceNormal);

float3 worldSpaceNormal = normalize(mul(CameraViewInverse[eyeIndex], float4(screenSpaceNormal, 0)));
float3 normalizedDirLightDirectionWS = DirLightDirection;

# if (defined(SKINNED) || !defined(MODELSPACENORMALS))
float3 vertexNormal = tbnTr[2];
Expand All @@ -1533,10 +1551,6 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace

float3 worldSpaceVertexNormal = normalize(mul(CameraViewInverse[eyeIndex], float4(screenSpaceVertexNormal, 0)));
# endif

# if (!defined(DRAW_IN_WORLDSPACE))
normalizedDirLightDirectionWS = lerp(normalize(mul(input.World[eyeIndex], float4(DirLightDirection, 0))), normalizedDirLightDirectionWS, input.WorldSpace);
# endif
# endif

float porosity = 1.0;
Expand Down Expand Up @@ -1935,7 +1949,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
# endif

# if defined(CPM_AVAILABLE) && defined(ENVMAP)
# if defined(DYNAMIC_CUBEMAPS)
vertexColor += envColor * lerp(complexSpecular, 1.0, dynamicCubemap) * diffuseColor;
# else
vertexColor += envColor * complexSpecular * diffuseColor;
# endif
# else
vertexColor += envColor * diffuseColor;
# endif
Expand Down
7 changes: 7 additions & 0 deletions package/Shaders/Sky.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ struct PS_OUTPUT
float4 Color : SV_Target0;
float2 MotionVectors : SV_Target1;
float4 Normal : SV_Target2;
float4 CloudShadows : SV_Target3;
};

#ifdef PSHADER
Expand Down Expand Up @@ -205,6 +206,12 @@ PS_OUTPUT main(PS_INPUT input)
psout.MotionVectors = screenMotionVector;
psout.Normal = float4(0.5, 0.5, 0, 0);

# if defined(CLOUDS)
alandtse marked this conversation as resolved.
Show resolved Hide resolved
psout.CloudShadows = psout.Color;
# else
psout.CloudShadows = 0.0;
# endif

return psout;
}
#endif
18 changes: 18 additions & 0 deletions package/Shaders/Water.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
#include "Common/MotionBlur.hlsl"
#include "Common/Permutation.hlsl"

struct LightingData
{
float WaterHeight[25];
bool Reflections;
};

StructuredBuffer<LightingData> lightingData : register(t126);

#define WATER

struct VS_INPUT
Expand Down Expand Up @@ -507,6 +515,10 @@ float3 GetSunColor(float3 normal, float3 viewDirection)
# include "LightLimitFix/LightLimitFix.hlsli"
# endif

# if defined(CLOUD_SHADOWS)
# include "CloudShadows/CloudShadows.hlsli"
# endif

PS_OUTPUT main(PS_INPUT input)
{
PS_OUTPUT psout;
Expand Down Expand Up @@ -623,6 +635,12 @@ PS_OUTPUT main(PS_INPUT input)
finalSpecularColor;
# else
float3 sunColor = GetSunColor(normal, viewDirection);

// # if defined(CLOUD_SHADOWS)
alandtse marked this conversation as resolved.
Show resolved Hide resolved
// if (perPassCloudShadow[0].EnableCloudShadows && !lightingData[0].Reflections)
// sunColor *= getCloudShadowMult(input.WPosition.xyz, SunDir.xyz, CubeMapSampler);
// # endif

float specularFraction = lerp(1, fresnel * depthControl.x, distanceFactor);
float3 finalColorPreFog = lerp(diffuseColor, specularColor, specularFraction) + sunColor * depthControl.w;
float3 finalColor = lerp(finalColorPreFog, input.FogParam.xyz, input.FogParam.w);
Expand Down
4 changes: 3 additions & 1 deletion src/Feature.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Feature.h"

#include "Features/CloudShadows.h"
#include "Features/DistantTreeLighting.h"
#include "Features/DynamicCubemaps.h"
#include "Features/ExtendedMaterials.h"
Expand Down Expand Up @@ -81,7 +82,8 @@ const std::vector<Feature*>& Feature::GetFeatureList()
WaterBlending::GetSingleton(),
WetnessEffects::GetSingleton(),
LightLimitFix::GetSingleton(),
DynamicCubemaps::GetSingleton()
DynamicCubemaps::GetSingleton(),
CloudShadows::GetSingleton()
};

static std::vector<Feature*> featuresVR = {
Expand Down
Loading
Loading