#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; }