1
2struct VIn
3{
4    float4 p   : POSITION;
5    float3 n   : NORMAL;
6    float2 uv  : TEXCOORD0;
7};
8
9struct VOut
10{
11    float4 p   : POSITION;
12    float2 uv  : TEXCOORD0;
13};
14
15struct PIn
16{
17	float4 p   : POSITION;
18    float2 uv  : TEXCOORD0;
19};
20
21VOut dof_vs(VIn IN, uniform float4x4 wvp, uniform float3 farCorner)
22{
23    VOut OUT;
24    OUT.p = mul(wvp, IN.p);
25    // clean up inaccuracies for the UV coords
26    float2 uv = sign(IN.p);
27    // convert to image space
28    uv = (float2(uv.x, -uv.y) + 1.0) * 0.5;
29    OUT.uv = uv;
30     return OUT;
31}
32
33float4 Gaussian3x3_ps(
34PIn IN
35,uniform sampler2D sourceTex: TEXUNIT0
36,uniform float4 pixelSize
37) : COLOR0
38{
39
40  float weights[9];
41  float2 offsets[9];
42  weights[0] = 1.0/16.0; weights[1] = 2.0/16.0; weights[2] = 1.0/16.0;
43  weights[3] = 2.0/16.0; weights[4] = 4.0/16.0; weights[5] = 2.0/16.0;
44  weights[6] = 1.0/16.0; weights[7] = 2.0/16.0; weights[8] = 1.0/16.0;
45
46  offsets[0] = float2(-pixelSize.x, -pixelSize.y);
47  offsets[1] = float2(0, -pixelSize.y);
48  offsets[2] = float2(pixelSize.x, -pixelSize.y);
49  offsets[3] = float2(-pixelSize.x, 0);
50  offsets[4] = float2(0, 0);
51  offsets[5] = float2(pixelSize.x, 0);
52  offsets[6] = float2(-pixelSize.x, pixelSize.y);
53  offsets[7] = float2(0,  pixelSize.y);
54  offsets[8] = float2(pixelSize.x, pixelSize.y);
55
56  float4 sum = {0.0,0.0,0.0,0.0};
57
58  for (int i = 0; i < 9; ++i)
59    sum += weights[i] * tex2D(sourceTex, IN.uv + offsets[i]);
60
61  return sum;
62}
63
64float ConvertDepth(float d, float far,float4 dofParams)
65{
66//	float4 dofParams = float4(.001,100,1000,1.0);
67	//float3 viewPos = d ;
68	float depth = d*far;//viewPos.z;
69	float depthResult;
70	if (depth < dofParams.y)
71    {
72       // scale depth value between near blur distance and focal distance to
73       // [-1, 0] range
74     //  depthResult = (depth - dofParams.y) / (dofParams.y - dofParams.x);
75	 depthResult=0;
76     }
77    else
78    {
79       // scale depth value between focal distance and far blur distance to
80       // [0, 1] range
81       depthResult = (depth - dofParams.y) / (dofParams.z - dofParams.y);
82       // clamp the far blur to a maximum blurriness
83       depthResult = clamp(depthResult, 0.0, dofParams.w);
84
85
86    }
87    // scale and bias into [0, 1] range
88	depthResult = 0.5f*depthResult + 0.5f;
89	return depthResult;
90}
91float4 DepthOfField_ps(
92PIn IN
93,uniform sampler2D sceneTex: TEXUNIT0                // full resolution image
94,uniform sampler2D depthTex: TEXUNIT1                // full resolution image with depth values
95,uniform sampler2D blurTex: TEXUNIT2                 // downsampled and blurred image
96,uniform float4 pixelSize
97,uniform float far
98,uniform float4 dofparams
99) : COLOR0
100{
101	float2 poisson[12];               // containts poisson-distributed positions on the unit circle
102float2 pixelSizeScene = pixelSize.xy;// pixel size of full resolution image
103float2 pixelSizeBlur = pixelSize.zw;// pixel size of downsampled and blurred image
104  poisson[ 0] = float2( 0.00,  0.00);
105  poisson[ 1] = float2( 0.07, -0.45);
106  poisson[ 2] = float2(-0.15, -0.33);
107  poisson[ 3] = float2( 0.35, -0.32);
108  poisson[ 4] = float2(-0.39, -0.26);
109  poisson[ 5] = float2( 0.10, -0.23);
110  poisson[ 6] = float2( 0.36, -0.12);
111  poisson[ 7] = float2(-0.31, -0.01);
112  poisson[ 8] = float2(-0.38,  0.22);
113  poisson[ 9] = float2( 0.36,  0.23);
114  poisson[10] = float2(-0.13,  0.29);
115  poisson[11] = float2( 0.14,  0.41);
116
117  float2 maxCoC;                          // maximum circle of confusion (CoC) radius
118                                        // and diameter in pixels
119  maxCoC = float2(5.0, 10.0);
120
121  float radiusScale;                      // scale factor for minimum CoC size on low res. image
122  radiusScale = 0.4;
123
124  // Get depth of center tap and convert it into blur radius in pixels
125  float centerDepth = ConvertDepth(tex2D(depthTex, IN.uv).r, far,dofparams);
126 // return float4(centerDepth,centerDepth,centerDepth,1);
127  float discRadiusScene = abs(centerDepth * maxCoC.y - maxCoC.x);
128  float discRadiusBlur = discRadiusScene * radiusScale; // radius on low res. image
129
130  float4 sum = float4(0.0,0.0,0.0,0.0);
131
132  for (int i = 0; i < 12; ++i)
133  {
134    // compute texture coordinates
135    float2 coordScene = IN.uv + (pixelSizeScene * poisson[i] * discRadiusScene);
136    float2 coordBlur = IN.uv + (pixelSizeBlur * poisson[i] * discRadiusBlur);
137
138    // fetch taps and depth
139    float4 tapScene = tex2D(sceneTex, coordScene);
140    float tapDepth = ConvertDepth(tex2D(depthTex, coordScene).r ,far,dofparams);
141    float4 tapBlur = tex2D(blurTex, coordBlur);
142
143    // mix low and high res. taps based on tap blurriness
144    float blurAmount = abs(tapDepth * 2.0 - 1.0); // put blurriness into [0, 1]
145    float4 tap = lerp(tapScene, tapBlur, blurAmount);
146
147    // "smart" blur ignores taps that are closer than the center tap and in focus
148    float factor = (tapDepth >= centerDepth) ? 1.0 : abs(tapDepth * 2.0 - 1.0);
149
150    // accumulate
151    sum.rgb += tap.rgb * factor;
152    sum.a += factor;
153  }
154
155  return (sum / sum.a);
156}
157