#ifndef BLUR_INCLUDED #define BLUR_INCLUDED // Declare the texture only when the required macros exist. #if defined(TEXTURE2D_X) && defined(SAMPLE_TEXTURE2D_X) #define BLUR_TEXTURE_AVAILABLE 1 TEXTURE2D_X(_CameraOpaqueTexture); SAMPLER(sampler_CameraOpaqueTexture); #else #define BLUR_TEXTURE_AVAILABLE 0 #endif void Gaussian_float(float2 UV, float Blur, float Quality, out float3 Color) { #if defined(SHADERGRAPH_PREVIEW) || !BLUR_TEXTURE_AVAILABLE Color = float3(0.5, 0.5, 0.5); #else float2 screenUV = saturate(UV); float radius = saturate(Blur) * 0.04; float2 stepUV = radius * float2( _ScreenParams.y / _ScreenParams.x, 1.0 ); // LOW: 9 samples // MEDIUM: 25 samples // HIGH: 49 samples int extent = (int)clamp(floor(Quality + 0.5), 0.0, 2.0) + 1; float sigma = max(0.8, extent * 0.65); float invTwoSigmaSq = 0.5 / (sigma * sigma); float3 sum = 0.0; float totalWeight = 0.0; [loop] for (int y = -extent; y <= extent; ++y) { [loop] for (int x = -extent; x <= extent; ++x) { float2 offset = float2(x, y); float weight = exp2( -dot(offset, offset) * invTwoSigmaSq * 1.44269504089 ); float2 sampleUV = saturate( screenUV + offset * stepUV / extent ); float3 sampleColor = SAMPLE_TEXTURE2D_X( _CameraOpaqueTexture, sampler_CameraOpaqueTexture, sampleUV ).rgb; sum += sampleColor * weight; totalWeight += weight; } } Color = sum / max(totalWeight, 1e-5); #endif } void Gaussian_half(half2 UV, half Blur, half Quality, out half3 Color) { float3 result; Gaussian_float( (float2) UV, (float) Blur, (float) Quality, result ); Color = (half3) result; } #endif