Added new Shadow SSS Lut;

Fixed the issue that SSGI and SSAO weight not works properly;
This commit is contained in:
2025-03-17 00:02:46 +09:00
parent b2136e1ff4
commit ee0b720b6d
7 changed files with 126 additions and 58 deletions

View File

@@ -1,9 +1,14 @@
#pragma kernel CSMain
#pragma kernel SkinLut
#pragma kernel ShadowLut
#pragma multi_compile_local _ _PRODUCTION
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#define _PROFILE_WIDTH 8.166
float _ScatterRadius;
float _PositionShift;
float _Intensity;
int _SampleCount;
int _ApplyTonemap;
@@ -51,12 +56,11 @@ float3 RadianceScatter(float r)
float3 IntegrateDiffuseScattering_Ring(float theta, float r)
{
float x = -HALF_PI;
float increment = PI / _SampleCount;
float3 totalScatter = 0;
float3 totalWeight = 0;
float increment = PI / _SampleCount;
float x = -HALF_PI;
while (x < HALF_PI)
{
float diffuse = saturate(cos(theta + x));
@@ -72,13 +76,42 @@ float3 IntegrateDiffuseScattering_Ring(float theta, float r)
return totalScatter / totalWeight;
}
float newPenumbra(float pos, float penumbraWidth)
{
return saturate((pos * penumbraWidth - _PROFILE_WIDTH) / (penumbraWidth - _PROFILE_WIDTH));
}
float3 IntegrateShadowScattering(float penumbraLocation, float penumbraWidth)
{
float3 totalScatter = 0;
float3 totalWeights = 0;
float increment = (_PROFILE_WIDTH * 2) / _SampleCount;
penumbraWidth = max(penumbraWidth, _PROFILE_WIDTH + 1e-5);
float x = -_PROFILE_WIDTH;
while (x <= _PROFILE_WIDTH)
{
float light = newPenumbra(penumbraLocation + x / penumbraWidth, penumbraWidth);
float distance = abs(x);
float3 weights = RadianceScatter(distance);
totalWeights += weights;
totalScatter += light * weights;
x += increment;
}
return totalScatter / totalWeights;
}
float3 FilmicTonemap(float3 color)
{
return (color * (6.2 * color + 0.5)) / (color * (6.2 * color + 1.7) + 0.06);
}
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
void SkinLut (uint3 id : SV_DispatchThreadID)
{
if (id.x > _TextureSize || id.y > _TextureSize)
{
@@ -90,7 +123,7 @@ void CSMain (uint3 id : SV_DispatchThreadID)
uv.y = 1.0 - uv.y;
#endif
float theta = acos(uv.x * 2.0 - 1.0);
float theta = acos((uv.x * 2.0 - 1.0)) + _PositionShift;
float r = rcp(max(uv.y, 0.001) * _ScatterRadius);
float3 scatter = IntegrateDiffuseScattering_Ring(theta, r) * _Intensity;
@@ -99,5 +132,31 @@ void CSMain (uint3 id : SV_DispatchThreadID)
scatter = FilmicTonemap(scatter);
}
_SSSLut[id.xy] = float4(scatter, 1.0);
//_SSSLut[id.xy] = theta;
}
[numthreads(8, 8, 1)]
void ShadowLut(uint3 id : SV_DispatchThreadID)
{
if (id.x > _TextureSize || id.y > _TextureSize)
{
return;
}
float2 uv = id.xy / float2(_TextureSize, _TextureSize);
#if UNITY_UV_STARTS_AT_TOP && _PRODUCTION
uv.y = 1.0 - uv.y;
#endif
float penumbraLocation = uv.x + _PositionShift;
float penumbraWidth = rcp(max(uv.y, 0.001) * _ScatterRadius);
float3 scatter = IntegrateShadowScattering(penumbraLocation, penumbraWidth) * _Intensity;
if (_ApplyTonemap == 1)
{
scatter = FilmicTonemap(scatter);
}
_SSSLut[id.xy] = float4(scatter, 1.0);
}