#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" #pragma kernel KMain #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch #pragma multi_compile _ INPUT_FROM_FRAME_TEXTURE #pragma multi_compile _ WRITE_TO_OUTPUT_TEXTURE // Inputs #ifdef INPUT_FROM_FRAME_TEXTURE TEXTURE2D_X(_FrameTexture); #endif float4 _AccumulationWeights; int _AccumulationNeedsExposure; uint _AccumulationFrameIndex; uint _AccumulationNumSamples; // Input - Output(s) RW_TEXTURE2D_X(float4, _CameraColorTextureRW); RW_TEXTURE2D_X(float4, _AccumulatedFrameTexture); void AddConvergenceCue(uint2 pixelCoord, uint sampleCount, inout float3 color) { // If we reached 100%, do not display the bar anymore if (sampleCount >= _AccumulationNumSamples) return; uint width = _ScreenSize.x; uint height = _ScreenSize.y; // Define progress bar height as 0.5% of the resolution (and at least 4 pixels high) uint barHeight = max(4, ceil(height * 0.005)); // Change color only in a region corresponding to a progress bar, at the bottom of the screen if (pixelCoord.y < barHeight && (float)pixelCoord.x / width <= (float)sampleCount / _AccumulationNumSamples) { float lum = Luminance(color); if (lum > 1.0) { color /= lum; lum = 1.0; } // Make dark color brighter, and vice versa color += lum > 0.5 ? -0.5 * lum : 0.05 + 0.5 * lum; } } [numthreads(8, 8, 1)] void KMain(uint3 dispatchThreadId : SV_DispatchThreadID) { UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); uint2 currentPixelCoord = dispatchThreadId.xy; float4 exposureMultiplier; exposureMultiplier.xyz = (_AccumulationNeedsExposure != 0) ? GetCurrentExposureMultiplier() : 1.0; exposureMultiplier.w = 1.0; // Have we reached max sampling? uint sampleCount = _AccumulationFrameIndex; if (sampleCount >= _AccumulationNumSamples) { #ifdef WRITE_TO_OUTPUT_TEXTURE _CameraColorTextureRW[COORD_TEXTURE2D_X(currentPixelCoord)] = _AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)] * exposureMultiplier; #endif } else { #ifdef INPUT_FROM_FRAME_TEXTURE float4 color = _FrameTexture[COORD_TEXTURE2D_X(dispatchThreadId.xy)]; #else float4 color = _CameraColorTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)] * _AccumulationWeights.x; #endif if (sampleCount > 0) color = (_AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)] * _AccumulationWeights.y + color); color *= _AccumulationWeights.z; _AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)] = color; #ifdef WRITE_TO_OUTPUT_TEXTURE // Apply exposure modifier color *= exposureMultiplier; // Add a little convergence cue to our result AddConvergenceCue(currentPixelCoord, sampleCount + 1, color.xyz); _CameraColorTextureRW[COORD_TEXTURE2D_X(currentPixelCoord)] = color; #endif } }