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