| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
- /*
- DX11 Depth Of Field
- pretty much just does bokeh texture splatting
- basic algorithm:
- * find bright spots
- * verify high frequency (otherwise dont care)
- * if possitive, replace with black pixel and add to append buffer
- * box blur buffer (thus smearing black pixels)
- * blend bokeh texture sprites via append buffer on top of box blurred buffer
- * composite with frame buffer
- */
- Shader "Hidden/Dof/DX11Dof"
- {
- Properties
- {
- _MainTex ("", 2D) = "white" {}
- _BlurredColor ("", 2D) = "white" {}
- _FgCocMask ("", 2D) = "white" {}
- }
- CGINCLUDE
- #define BOKEH_ZERO_VEC (float4(0,0,0,0))
- #define BOKEH_ONE_VEC (float4(1,1,1,1))
- float4 _BokehParams; // legend: dx11BokehScale, dx11BokehIntensity,dx11BokehThreshhold, internalBlurWidth
- float4 _MainTex_TexelSize;
- float3 _Screen;
- float _SpawnHeuristic;
- sampler2D_float _CameraDepthTexture;
- sampler2D _BlurredColor;
- sampler2D _MainTex;
- sampler2D _FgCocMask;
- struct appendStruct {
- float3 pos;
- float4 color;
- };
- struct gs_out {
- float4 pos : SV_POSITION;
- float3 uv : TEXCOORD0;
- float4 color : TEXCOORD1;
- float4 misc : TEXCOORD2;
- };
- // TODO: activate border clamp tex sampler state instead?
- inline float4 clampBorderColor(float2 uv)
- {
- #if 1
- if(uv.x<=0) return BOKEH_ZERO_VEC; if(uv.x>=1) return BOKEH_ZERO_VEC;
- if(uv.y<=0) return BOKEH_ZERO_VEC; if(uv.y>=1) return BOKEH_ZERO_VEC;
- #endif
- return BOKEH_ONE_VEC;
- }
- struct vs_out {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- float4 color : TEXCOORD1;
- float cocOverlap : TEXCOORD2;
- };
- StructuredBuffer<appendStruct> pointBuffer;
- vs_out vertApply (uint id : SV_VertexID)
- {
- vs_out o;
- float2 pos = pointBuffer[id].pos.xy ;
- o.pos = float4(pos * 2.0 - 1.0, 0, 1);
- o.color = pointBuffer[id].color;
- #if UNITY_UV_STARTS_AT_TOP
- o.pos.y *= -1;
- #endif
- o.cocOverlap = pointBuffer[id].pos.z;
- return o;
- }
- [maxvertexcount(4)]
- void geom (point vs_out input[1], inout TriangleStream<gs_out> outStream)
- {
- // NEW ENERGY CONSERVATION:
- float2 scale2 = _BokehParams.ww * input[0].color.aa * _BokehParams.xx;
- float4 offs = 0;
- offs.xy = float2(3.0, 3.0) + 2.0f * floor(scale2 + float2(0.5,0.5));
- float2 rs = ((float2(1.0, 1.0) + 2.0f * (scale2 + float2(0.5,0.5))));;
- float2 f2 = offs.xy / rs;
- float energyAdjustment = (_BokehParams.y) / (rs.x*rs.y);
- offs.xy *= _Screen.xy;
- gs_out output;
- output.pos = input[0].pos + offs*float4(-1,1,0,0);
- output.misc = float4(f2,0,0);
- output.uv = float3(0, 1, input[0].cocOverlap);
- output.color = input[0].color * energyAdjustment;
- outStream.Append (output);
- output.pos = input[0].pos + offs*float4(1,1,0,0);
- output.misc = float4(f2,0,0);
- output.uv = float3(1, 1, input[0].cocOverlap);
- output.color = input[0].color * energyAdjustment;
- outStream.Append (output);
- output.pos = input[0].pos + offs*float4(-1,-1,0,0);
- output.misc = float4(f2,0,0);
- output.uv = float3(0, 0, input[0].cocOverlap);
- output.color = input[0].color * energyAdjustment;
- outStream.Append (output);
- output.pos = input[0].pos + offs*float4(1,-1,0,0);
- output.misc = float4(f2,0,0);
- output.uv = float3(1, 0, input[0].cocOverlap);
- output.color = input[0].color * energyAdjustment;
- outStream.Append (output);
- outStream.RestartStrip();
- }
- ENDCG
- SubShader
- {
- // pass 0: append buffer "collect"
- Pass
- {
- ZWrite Off ZTest Always Cull Off
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #pragma target 5.0
- #include "UnityCG.cginc"
- struct appdata {
- float4 vertex : POSITION;
- float2 texcoord : TEXCOORD0;
- };
- struct v2f {
- float4 pos : SV_POSITION;
- float2 uv_flip : TEXCOORD0;
- float2 uv : TEXCOORD1;
- };
- v2f vert (appdata v)
- {
- v2f o;
- o.pos = UnityObjectToClipPos (v.vertex);
- o.uv = v.texcoord;
- o.uv_flip = v.texcoord;
- #if UNITY_UV_STARTS_AT_TOP
- if(_MainTex_TexelSize.y<0)
- o.uv_flip.y = 1.0-o.uv_flip.y;
- if(_MainTex_TexelSize.y<0)
- o.pos.y *= -1.0;
- #endif
- return o;
- }
- AppendStructuredBuffer<appendStruct> pointBufferOutput : register(u1);
- float4 frag (v2f i) : SV_Target
- {
- float4 c = tex2D (_MainTex, i.uv_flip);
- float lumc = Luminance (c.rgb);
- float4 cblurred = tex2D (_BlurredColor, i.uv);
- float lumblurred = Luminance (cblurred.rgb);
- float fgCoc = tex2D(_FgCocMask, i.uv).a;
- [branch]
- if (c.a * _BokehParams.w > 1 && cblurred.a > 0.1 && lumc > _BokehParams.z && abs(lumc-lumblurred) > _SpawnHeuristic)
- {
- appendStruct append;
- append.pos = float3(i.uv, fgCoc);
- append.color.rgba = float4(c.rgb * saturate(c.a*4), c.a);
- pointBufferOutput.Append (append);
- return float4(c.rgb * saturate(1-c.a*4), c.a);
- }
- return c;
- }
- ENDCG
- }
- // pass 1: bokeh splatting (low resolution)
- Pass {
- ZWrite Off ZTest Always Cull Off
- Blend One One, One One
- ColorMask RGBA
- CGPROGRAM
- #pragma target 5.0
- #pragma vertex vertApply
- #pragma geometry geom
- #pragma fragment frag
- #include "UnityCG.cginc"
- fixed4 frag (gs_out i) : SV_Target
- {
- float2 uv = (i.uv.xy) * i.misc.xy + (float2(1,1)-i.misc.xy) * 0.5; // smooth uv scale
- return float4(i.color.rgb, 1) * float4(tex2D(_MainTex, uv.xy).rgb, i.uv.z) * clampBorderColor (uv);
- }
- ENDCG
- }
- // pass 2: bokeh splatting (high resolution)
- Pass {
- ZWrite Off ZTest Always Cull Off
- BlendOp Add, Add
- Blend DstAlpha One, Zero One
- ColorMask RGBA
- CGPROGRAM
- #pragma target 5.0
- #pragma vertex vertApply
- #pragma geometry geom
- #pragma fragment frag
- #include "UnityCG.cginc"
- fixed4 frag (gs_out i) : SV_Target
- {
- float2 uv = (i.uv.xy) * i.misc.xy + (float2(1,1)-i.misc.xy) * 0.5; // smooth uv scale
- return float4(i.color.rgb, 1) * float4(tex2D(_MainTex, uv.xy).rgb, i.uv.z) * clampBorderColor (uv);
- }
- ENDCG
- }
- }
- Fallback Off
- }
|