185 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
		
		
			
		
	
	
			185 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
|   | #ifndef VOLUMETRIC_FOG_2_BLUR | ||
|  | #define VOLUMETRIC_FOG_2_BLUR | ||
|  | 
 | ||
|  | #include "CommonsURP.hlsl" | ||
|  | 
 | ||
|  | TEXTURE2D_X(_MainTex); | ||
|  | TEXTURE2D_X(_LightBuffer); | ||
|  | TEXTURE2D_X(_DownsampledDepth); | ||
|  | float4    _MainTex_TexelSize; | ||
|  | float4    _MainTex_ST; | ||
|  | float     _BlurScale; | ||
|  | float4    _DownsampledDepth_TexelSize; | ||
|  | float     _EdgeThreshold; | ||
|  | 
 | ||
|  | // Optimization for SSPR | ||
|  | #define uvN uv1 | ||
|  | #define uvE uv2 | ||
|  | #define uvW uv3 | ||
|  | #define uvS uv4 | ||
|  | 
 | ||
|  | 
 | ||
|  | #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) || defined(SINGLE_PASS_STEREO) | ||
|  |     #define VERTEX_CROSS_UV_DATA | ||
|  |     #define VERTEX_OUTPUT_GAUSSIAN_UV(o) | ||
|  | 
 | ||
|  |     #if defined(BLUR_HORIZ) | ||
|  |         #define FRAG_SETUP_GAUSSIAN_UV(i) float2 inc = float2(_MainTex_TexelSize.x * 1.3846153846 * _BlurScale, 0); float2 uv1 = i.uv - inc; float2 uv2 = i.uv + inc; float2 inc2 = float2(_MainTex_TexelSize.x * 3.2307692308 * _BlurScale, 0); float2 uv3 = i.uv - inc2; float2 uv4 = i.uv + inc2; | ||
|  |     #else | ||
|  |         #define FRAG_SETUP_GAUSSIAN_UV(i) float2 inc = float2(0, _MainTex_TexelSize.y * 1.3846153846 * _BlurScale); float2 uv1 = i.uv - inc; float2 uv2 = i.uv + inc; float2 inc2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * _BlurScale); float2 uv3 = i.uv - inc2; float2 uv4 = i.uv + inc2; | ||
|  |     #endif | ||
|  | 
 | ||
|  | #else | ||
|  |     #define VERTEX_CROSS_UV_DATA float2 uvN : TEXCOORD1; float2 uvW: TEXCOORD2; float2 uvE: TEXCOORD3; float2 uvS: TEXCOORD4; | ||
|  | 
 | ||
|  |     #if defined(BLUR_HORIZ) | ||
|  |         #define VERTEX_OUTPUT_GAUSSIAN_UV(o) float2 inc = float2(_MainTex_TexelSize.x * 1.3846153846 * _BlurScale, 0); o.uv1 = o.uv - inc; o.uv2 = o.uv + inc; float2 inc2 = float2(_MainTex_TexelSize.x * 3.2307692308 * _BlurScale, 0); o.uv3 = o.uv - inc2; o.uv4 = o.uv + inc2; | ||
|  |     #else | ||
|  |         #define VERTEX_OUTPUT_GAUSSIAN_UV(o) float2 inc = float2(0, _MainTex_TexelSize.y * 1.3846153846 * _BlurScale); o.uv1 = o.uv - inc; o.uv2 = o.uv + inc; float2 inc2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * _BlurScale); o.uv3 = o.uv - inc2; o.uv4 = o.uv + inc2; | ||
|  |     #endif | ||
|  |     #define FRAG_SETUP_GAUSSIAN_UV(i) float2 uv1 = i.uv1; float2 uv2 = i.uv2; float2 uv3 = i.uv3; float2 uv4 = i.uv4; | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  | 	struct VaryingsCross { | ||
|  | 	    float4 positionCS : SV_POSITION; | ||
|  | 	    float2 uv: TEXCOORD0; | ||
|  |         UNITY_VERTEX_INPUT_INSTANCE_ID | ||
|  |         VERTEX_CROSS_UV_DATA | ||
|  |         UNITY_VERTEX_OUTPUT_STEREO | ||
|  | 	}; | ||
|  | 
 | ||
|  | 
 | ||
|  | 	VaryingsCross VertBlur(Attributes v) { | ||
|  |     	VaryingsCross o; | ||
|  |         UNITY_SETUP_INSTANCE_ID(v); | ||
|  |         UNITY_TRANSFER_INSTANCE_ID(v, o); | ||
|  |         UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); | ||
|  | 
 | ||
|  | 	    o.positionCS = v.positionOS; | ||
|  | 		o.positionCS.y *= _ProjectionParams.x; | ||
|  |     	o.uv = v.uv; | ||
|  |         VERTEX_OUTPUT_GAUSSIAN_UV(o) | ||
|  | 
 | ||
|  |     	return o; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	inline float getLuma(float4 rgb) { | ||
|  | 		const float3 lum = float3(0.299, 0.587, 0.114); | ||
|  | 		return dot(rgb.xyz, lum); | ||
|  | 	} | ||
|  | 	 | ||
|  | 	float4 FragBlur (VaryingsCross i): SV_Target { | ||
|  |     	UNITY_SETUP_INSTANCE_ID(i); | ||
|  |         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); | ||
|  |         i.uv = UnityStereoTransformScreenSpaceTex(i.uv); | ||
|  |         FRAG_SETUP_GAUSSIAN_UV(i) | ||
|  | 
 | ||
|  |         #if defined(FINAL_BLEND) && EDGE_PRESERVE | ||
|  |             // edge aware blur | ||
|  |             float4 mask  = SAMPLE_TEXTURE2D_X(_LightBuffer, sampler_PointClamp, i.uv); | ||
|  |             float4 mask1 = SAMPLE_TEXTURE2D_X(_LightBuffer, sampler_PointClamp, uv1); | ||
|  |             float4 mask2 = SAMPLE_TEXTURE2D_X(_LightBuffer, sampler_PointClamp, uv2); | ||
|  |             float4 mask3 = SAMPLE_TEXTURE2D_X(_LightBuffer, sampler_PointClamp, uv3); | ||
|  |             float4 mask4 = SAMPLE_TEXTURE2D_X(_LightBuffer, sampler_PointClamp, uv4); | ||
|  |             float luma  = getLuma(mask); | ||
|  |             float luma1 = getLuma(mask1); | ||
|  |             float luma2 = getLuma(mask2); | ||
|  |             float luma3 = getLuma(mask3); | ||
|  |             float luma4 = getLuma(mask4); | ||
|  |             float4 diffs = saturate(float4(luma, luma1, luma3, luma4) / _EdgeThreshold); | ||
|  |             float atten = max(max(diffs.x, diffs.y), max(diffs.z, diffs.w)); | ||
|  |             if (atten <= 0) return 0; | ||
|  |         #endif | ||
|  | 
 | ||
|  |         float4 pixel0 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv) * 0.2270270270; | ||
|  |         float4 pixel1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv1) * 0.3162162162; | ||
|  |         float4 pixel2 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv2) * 0.3162162162; | ||
|  | 		float4 pixel3 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv3) * 0.0702702703; | ||
|  |         float4 pixel4 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv4) * 0.0702702703; | ||
|  | 
 | ||
|  |         // remove black halo around edges | ||
|  |         if (getLuma(pixel1) <= 0) pixel1 = pixel2; | ||
|  |         if (getLuma(pixel2) <= 0) pixel2 = pixel1; | ||
|  |         if (getLuma(pixel3) <= 0) pixel3 = pixel4; | ||
|  |         if (getLuma(pixel4) <= 0) pixel4 = pixel3; | ||
|  | 
 | ||
|  |         float4 pixel = pixel0 + pixel1 + pixel2 + pixel3 + pixel4; | ||
|  | 
 | ||
|  |         #if defined(DITHER) | ||
|  |             const float3 magic = float3( 0.06711056, 0.00583715, 52.9829189 ); | ||
|  |             float jitter = frac( magic.z * frac( dot( i.uv.xy * _MainTex_TexelSize.zw, magic.xy ) ) ); | ||
|  | 	        pixel = max(0, pixel - jitter * 0.01); | ||
|  |         #endif | ||
|  | 
 | ||
|  |         #if defined(FINAL_BLEND) && EDGE_PRESERVE | ||
|  |             pixel *= atten; | ||
|  |         #endif | ||
|  | 
 | ||
|  |    		return pixel; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	struct VaryingsSimple { | ||
|  | 	    float4 positionCS : SV_POSITION; | ||
|  | 	    float2 uv: TEXCOORD0; | ||
|  |         UNITY_VERTEX_INPUT_INSTANCE_ID | ||
|  |         UNITY_VERTEX_OUTPUT_STEREO | ||
|  | 	}; | ||
|  | 
 | ||
|  | 
 | ||
|  | 	VaryingsSimple VertSimple(Attributes v) { | ||
|  |     	VaryingsSimple o; | ||
|  |         UNITY_SETUP_INSTANCE_ID(v); | ||
|  |         UNITY_TRANSFER_INSTANCE_ID(v, o); | ||
|  |         UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); | ||
|  | 
 | ||
|  | 	    o.positionCS = v.positionOS; | ||
|  | 		o.positionCS.y *= _ProjectionParams.x; | ||
|  |     	o.uv = v.uv; | ||
|  | 
 | ||
|  |     	return o; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	float4 FragSeparatedBlend (VaryingsSimple i): SV_Target { | ||
|  |     	UNITY_SETUP_INSTANCE_ID(i); | ||
|  |         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); | ||
|  | 
 | ||
|  |         float depthFull = GetRawDepth(i.uv); | ||
|  |          | ||
|  |         const float threshold = 0.0005; | ||
|  |         const float t = 0.5; | ||
|  |         float2 uv00 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, -t)); | ||
|  |         float2 uv10 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, -t)); | ||
|  |         float2 uv01 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, t)); | ||
|  |         float2 uv11 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, t)); | ||
|  |         float4 depths; | ||
|  |         depths.x = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv00).r; | ||
|  |         depths.y = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv10).r; | ||
|  |         depths.z = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv01).r; | ||
|  |         depths.w = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv11).r; | ||
|  |         float4 diffs = abs(depthFull.xxxx - depths); | ||
|  | 
 | ||
|  |         float2 minUV = UnityStereoTransformScreenSpaceTex(i.uv); | ||
|  |         if (any(diffs > threshold)) { | ||
|  |             // Check 10 vs 00 | ||
|  |             float minDiff  = lerp(diffs.x, diffs.y, diffs.y < diffs.x); | ||
|  |             minUV    = lerp(uv00, uv10, diffs.y < diffs.x); | ||
|  |             // Check against 01 | ||
|  |             minUV    = lerp(minUV, uv01, diffs.z < minDiff); | ||
|  |             minDiff  = lerp(minDiff, diffs.z, diffs.z < minDiff); | ||
|  |             // Check against 11 | ||
|  |             minUV    = lerp(minUV, uv11, diffs.w < minDiff); | ||
|  |         }  | ||
|  |          | ||
|  |         float4 pixel = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, minUV); | ||
|  |    		return pixel; | ||
|  | 	}	 | ||
|  | 
 | ||
|  | 	 | ||
|  | 	float4 FragOnlyDepth (VaryingsSimple i): SV_Target { | ||
|  |     	UNITY_SETUP_INSTANCE_ID(i); | ||
|  |         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); | ||
|  |         return GetRawDepth(i.uv); | ||
|  | 	} | ||
|  | 
 | ||
|  | #endif // VOLUMETRIC_FOG_2_BLUR |