You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
3.7 KiB
84 lines
3.7 KiB
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2
|
|
|
|
// Shadows
|
|
#pragma kernel TraceVolumetricCloudsShadows
|
|
|
|
#pragma multi_compile _ CLOUDS_SIMPLE_PRESET
|
|
|
|
// #pragma enable_d3d11_debug_symbols
|
|
|
|
#define TRACE_CLOUDS_SHADOWS 1
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricCloudsUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl"
|
|
|
|
RW_TEXTURE2D(float4, _VolumetricCloudsShadowRW);
|
|
|
|
[numthreads(8, 8, 1)]
|
|
void TraceVolumetricCloudsShadows(uint3 currentCoords : SV_DispatchThreadID, int groupIndex : SV_GroupIndex)
|
|
{
|
|
// If we can, load the cloud lut into the LDS
|
|
#if defined(CLOUDS_SIMPLE_PRESET)
|
|
LoadCloudLutToLDS(groupIndex);
|
|
#endif
|
|
|
|
// Compute the normalized coordinate on the shadow plane
|
|
float2 normalizedCoord = currentCoords.xy / (float)(_ShadowCookieResolution - 1);
|
|
|
|
// Compute the origin of the ray properties in the planet space
|
|
float3 rayOriginPS = _CloudShadowSunOrigin.xyz + (normalizedCoord.x * _CloudShadowSunRight.xyz + normalizedCoord.y * _CloudShadowSunUp.xyz);
|
|
float3 rayDirection = -_CloudShadowSunForward.xyz;
|
|
|
|
// Compute the attenuation
|
|
float transmittance = 1.0f;
|
|
float closestDistance = FLT_MAX;
|
|
float farthestDistance = FLT_MIN;
|
|
bool validShadow = false;
|
|
|
|
// Intersect the outer sphere
|
|
float2 lowestAltitudeIntersections, highestAltitudeIntersections;
|
|
bool lowBoundOk = IntersectRaySphere(rayOriginPS, rayDirection, _LowestCloudAltitude, lowestAltitudeIntersections);
|
|
bool highBoundOk = IntersectRaySphere(rayOriginPS, rayDirection, _HighestCloudAltitude, highestAltitudeIntersections);
|
|
|
|
if (lowBoundOk && highBoundOk)
|
|
{
|
|
// Compute the integration range
|
|
float startDistance = highestAltitudeIntersections.x;
|
|
float totalDistance = max(lowestAltitudeIntersections.x - highestAltitudeIntersections.x, highestAltitudeIntersections.x - lowestAltitudeIntersections.x);
|
|
rayOriginPS += startDistance * rayDirection;
|
|
|
|
float stepSize = totalDistance / 16;
|
|
|
|
for (int i = 1; i < 16; ++i)
|
|
{
|
|
// Compute the sphere intersection position
|
|
float dist = (stepSize * i);
|
|
float3 positionPS = rayOriginPS + rayDirection * dist;
|
|
|
|
// Get the coverage at intersection point
|
|
CloudCoverageData cloudCoverageData;
|
|
GetCloudCoverageData(positionPS, cloudCoverageData);
|
|
|
|
// Compute the cloud density
|
|
CloudProperties cloudProperties;
|
|
EvaluateCloudProperties(positionPS, 0.0, 0.0, true, true, cloudProperties);
|
|
|
|
// Apply the camera fade it to match the clouds perceived by the camera
|
|
cloudProperties.density *= DensityFadeValue(length(positionPS - _CameraPositionPS.xyz));
|
|
|
|
if (cloudProperties.density > CLOUD_DENSITY_TRESHOLD)
|
|
{
|
|
// Apply the extinction
|
|
closestDistance = min(closestDistance, totalDistance - stepSize * (i + 1));
|
|
farthestDistance = max(farthestDistance, totalDistance - stepSize * i);
|
|
const float3 currentStepExtinction = exp(-_ScatteringTint.xyz * cloudProperties.density * cloudProperties.sigmaT * stepSize);
|
|
transmittance *= Luminance(currentStepExtinction);
|
|
validShadow = true;
|
|
}
|
|
}
|
|
}
|
|
// If we didn't manage to hit a non null density, we need to fix the distances
|
|
float4 result = validShadow ? float4(closestDistance, lerp(1.0 - _ShadowIntensity, 1.0, transmittance), farthestDistance, 1.0) : float4(0.0, 1.0, 0.0, 0.0);
|
|
|
|
_VolumetricCloudsShadowRW[currentCoords.xy] = result;
|
|
}
|