Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudUtils.hlsl
2024-08-26 23:07:20 +03:00

52 lines
2.3 KiB
HLSL

#ifndef __CLOUDUTILS_H__
#define __CLOUDUTILS_H__
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyCommon.hlsl"
// Returns true if the ray intersects the cloud volume
// Outputs the entry and exit distance from the volume
bool IntersectCloudVolume(float3 originPS, float3 dir, float lowerBoundPS, float higherBoundPS, out float tEntry, out float tExit)
{
bool intersect;
float radialDistance = length(originPS);
float rcpRadialDistance = rcp(radialDistance);
float cosChi = dot(originPS, dir) * rcpRadialDistance;
float2 tInner = IntersectSphere(lowerBoundPS, cosChi, radialDistance, rcpRadialDistance);
float2 tOuter = IntersectSphere(higherBoundPS, cosChi, radialDistance, rcpRadialDistance);
if (tInner.x < 0.0 && tInner.y >= 0.0) // Below the lower bound
{
// The ray starts at the intersection with the lower bound and ends at the intersection with the outer bound
tEntry = tInner.y;
tExit = tOuter.y;
// We don't see the clouds if they are behind Earth
intersect = cosChi >= ComputeCosineOfHorizonAngle(radialDistance);
}
else // Inside or above the cloud volume
{
// The ray starts at the intersection with the outer bound, or at 0 if we are inside
// The ray ends at the lower bound if we hit it, at the outer bound otherwise
tEntry = max(tOuter.x, 0.0f);
tExit = tInner.x >= 0.0 ? tInner.x : tOuter.y;
// We don't see the clouds if we don't hit the outer bound
intersect = tOuter.y >= 0.0f;
}
return intersect;
}
// Returns true if the ray exits the cloud volume (doesn't intersect earth)
// The ray is supposed to start inside the volume
bool ExitCloudVolume(float3 originPS, float3 dir, float higherBoundPS, out float tExit)
{
// Given that we are inside the volume, we are guaranteed to exit at the outer bound
float radialDistance = length(originPS);
float cosChi = dot(originPS, dir) * rcp(radialDistance);
tExit = IntersectSphere(higherBoundPS, cosChi, radialDistance, rcp(radialDistance)).y;
// If the ray intersects the earth, then the sun is occluded by the earth
return cosChi >= ComputeCosineOfHorizonAngle(radialDistance);
}
#endif // __CLOUDUTILS_H__