This commit is contained in:
StarBeats 2026-01-30 17:49:21 +08:00
parent 2c49be5735
commit 12b305e9a7

View File

@ -197,6 +197,38 @@ float CalcSphereOcclusion2(in float3 pos, in float3 nor, in float4 sph)
// float sqL = dot(di, di);
// return clamp(1.0 - dot(nor, di) * rsqrt(sqL * sqL * sqL), 0.1, 1);
}
float sphOcclusion( in float3 pos, in float3 nor, in float4 sph )
{
float3 di = sph.xyz - pos;
float l = length(di);
float nl = dot(nor,di/l) * _CapsuleShadowData[0].ConeAngle;
float h = l/sph.w;
float h2 = h*h;
float k2 = 1.0 - h2*nl*nl;
// above/below horizon
// EXACT: Quilez - https://iquilezles.org/articles/sphereao
float res = max(0.0,nl)/h2;
// intersecting horizon
if( k2 > 0.001 )
{
#if 0
// EXACT : Lagarde/de Rousiers - https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
res = nl*acos(-nl*sqrt( (h2-1.0)/(1.0-nl*nl) )) - sqrt(k2*(h2-1.0));
res = res/h2 + atan( sqrt(k2/(h2-1.0)));
res /= 3.141593;
#else
// APPROXIMATED : Quilez - https://iquilezles.org/articles/sphereao
res = (nl*h+1.0)/h2;
res = 0.33*res*res;
#endif
}
return 1 -res;
}
float CalcCapsuleOcclusionByIndexV2(float3 p, float3 n, uint s, uint e, float intensity, float intensity1)
{
float ao = 1.0;
@ -209,7 +241,7 @@ float CalcCapsuleOcclusionByIndexV2(float3 p, float3 n, uint s, uint e, float in
// p 在 ba 上投影长度与 ba 长度比值
float t = /* abs(l) < 1e-8f ? 0.0 : */ saturate(dot(pa, ba) / l);
float3 positionToRay = capsule.a + t * ba;
ao *= CalcSphereOcclusion2(p, n, float4(positionToRay, capsule.radius));
ao *= sphOcclusion(p, n, float4(positionToRay, capsule.radius));
}
ao = saturate(lerp(1, ao, intensity));
return saturate(lerp(1, ao, intensity1));
@ -264,8 +296,8 @@ void CalcCapsuleShadow(float3 worldPos, float3 worldNormal, out float shadow, o
shadow = min(shadow, tempShadow);
}
}
occlusion *= CalcCapsuleOcclusionByIndex(worldPos, worldNormal, c.capsuleStartID, c.capsuleEndID, intensity, _CapsuleShadowData[0].AmbientIntensity);
//occlusion *= CalcCapsuleOcclusionByIndexV2(worldPos, worldNormal, c.capsuleStartID, c.capsuleEndID, intensity, _CapsuleShadowData[0].AmbientIntensity);
// occlusion *= CalcCapsuleOcclusionByIndex(worldPos, worldNormal, c.capsuleStartID, c.capsuleEndID, intensity, _CapsuleShadowData[0].AmbientIntensity);
occlusion *= CalcCapsuleOcclusionByIndexV2(worldPos, worldNormal, c.capsuleStartID, c.capsuleEndID, intensity, _CapsuleShadowData[0].AmbientIntensity);
#elif defined(_MultiCapsule_AO_ON)
occlusion *= CalcCapsuleOcclusionByIndex(worldPos, worldNormal, c.capsuleStartID, c.capsuleEndID, intensity, _CapsuleShadowData[0].AmbientIntensity);
#endif