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.
 
 
 
 
 

113 lines
4.4 KiB

#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
// Render clouds
#pragma kernel RenderClouds
#pragma multi_compile _ PHYSICALLY_BASED_SUN
#pragma multi_compile _ CLOUDS_MICRO_EROSION
#pragma multi_compile _ CLOUDS_SIMPLE_PRESET
#pragma multi_compile _ TRACE_FOR_SKY
// #pragma enable_d3d11_debug_symbols
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricCloudsUtilities.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl"
// Input textures
TEXTURE2D_X(_VolumetricCloudsSourceDepth);
// Output texture
RW_TEXTURE2D_X(float4, _CloudsLightingTextureRW);
RW_TEXTURE2D_X(float, _CloudsDepthTextureRW);
CloudRay BuildRay(uint2 intermediateCoord)
{
CloudRay ray;
ZERO_INITIALIZE(CloudRay, ray);
float2 positionCS = _LowResolutionEvaluation ? intermediateCoord * _IntermediateResolutionScale : intermediateCoord;
// Compute the position of the point from which the ray will start
ray.originWS = GetCameraPositionWS();
// Compute the view direction
ray.direction = GetCloudViewDirWS(positionCS);
// Compute the max ray length
ray.maxRayLength = FLT_MAX;
#ifndef TRACE_FOR_SKY
if (_ValidSceneDepth)
{
float depthValue = LOAD_TEXTURE2D_X(_VolumetricCloudsSourceDepth, intermediateCoord.xy).x;
if (depthValue != UNITY_RAW_FAR_CLIP_VALUE)
ray.maxRayLength = LinearEyeDepth(positionCS * _ScreenSize.zw, depthValue, _InvProjParams) * rcp(dot(ray.direction, -UNITY_MATRIX_V[2].xyz));
}
#endif
// Keep track of the integration noise
ray.integrationNoise = _EnableIntegration ? GetBNDSequenceSample(intermediateCoord, _AccumulationFrameIndex, 0) : 0.0;
return ray;
}
[numthreads(8, 8, 1)]
void RenderClouds(uint3 traceCoord : SV_DispatchThreadID, int groupIndex : SV_GroupIndex)
{
UNITY_XR_ASSIGN_VIEW_INDEX(traceCoord.z);
// If we can, load the cloud lut into the LDS
#ifdef CLOUDS_SIMPLE_PRESET
LoadCloudLutToLDS(groupIndex);
#endif
// If this is bigger than the trace size, we are done
if (any(traceCoord.xy >= uint2(_TraceScreenSize.xy)))
return;
// Depending on if we are in full res or not, use a different intermediate coord
uint2 intermediateCoord = traceCoord.xy; // Full resolution case
if (_LowResolutionEvaluation)
{
intermediateCoord = traceCoord.xy * 2;
if (_EnableIntegration)
{
// Compute the half res coordinate that matches this thread (as we virtually do the computation in half res space)
int checkerBoardIndex = ComputeCheckerBoardIndex(traceCoord.xy, _SubPixelIndex);
intermediateCoord += HalfResolutionIndexToOffset(checkerBoardIndex);
}
}
// Given that the rendering resolution is not guaranteed to be an even number, we need to clamp to the intermediate resolution in this case
intermediateCoord = min(intermediateCoord, _IntermediateScreenSize.xy - 1);
// Build the ray we will use of the ray marching.
CloudRay ray = BuildRay(intermediateCoord);
// Evaluate the cloud transmittance
VolumetricRayResult result = TraceVolumetricRay(ray);
result.inScattering *= GetCurrentExposureMultiplier();
result.meanDistance = min(result.meanDistance, ray.maxRayLength);
#if defined(PHYSICALLY_BASED_SUN) && !defined(TRACE_FOR_SKY)
if (!result.invalidRay && _PBRFogEnabled)
{
// Apply atmospheric fog
float3 V = ray.direction;
float2 positionNDC = intermediateCoord * _IntermediateScreenSize.zw;
float3 skyColor, skyOpacity;
EvaluateAtmosphericScattering(V, positionNDC, result.meanDistance, skyColor, skyOpacity);
result.inScattering.xyz = result.inScattering.xyz * (1 - skyOpacity) + skyColor * (1 - result.transmittance);
}
#endif
// Output the result
_CloudsLightingTextureRW[COORD_TEXTURE2D_X(traceCoord.xy)] = float4(result.inScattering, result.transmittance);
// Compute the cloud depth
float depth = result.invalidRay ? UNITY_RAW_FAR_CLIP_VALUE : EncodeInfiniteDepth(result.meanDistance, _CloudNearPlane);
_CloudsDepthTextureRW[COORD_TEXTURE2D_X(traceCoord.xy)] = depth;
}