1 | struct fragment |
---|
2 | { |
---|
3 | float4 pos: WPOS; // normalized screen position |
---|
4 | float4 view: COLOR; |
---|
5 | float4 texcoord: TEXCOORD0; |
---|
6 | float4 lindepth: TEXCOORD1; |
---|
7 | }; |
---|
8 | |
---|
9 | |
---|
10 | struct pixel |
---|
11 | { |
---|
12 | float4 col: COLOR0; |
---|
13 | }; |
---|
14 | |
---|
15 | |
---|
16 | float3 reflect(float3 pt, float3 n) |
---|
17 | { |
---|
18 | // distance to plane |
---|
19 | float d = dot(n, pt); |
---|
20 | // reflect around plane |
---|
21 | float3 rpt = pt - d * 2.0f * n; |
---|
22 | |
---|
23 | //return pt; |
---|
24 | return rpt; |
---|
25 | } |
---|
26 | |
---|
27 | |
---|
28 | pixel main(fragment IN, |
---|
29 | uniform sampler2D lindepth, |
---|
30 | uniform sampler2D scene, |
---|
31 | uniform sampler2D normal, |
---|
32 | uniform float invTexSize, |
---|
33 | uniform float radius, |
---|
34 | uniform float3 eyevec, |
---|
35 | uniform float3 samples[32]) |
---|
36 | { |
---|
37 | pixel OUT; |
---|
38 | |
---|
39 | // eye space z |
---|
40 | float eyez = tex2D(lindepth, IN.texcoord.xy).x; |
---|
41 | |
---|
42 | float3 viewvec = IN.view.xyz * 2.0f - float3(1.0f); |
---|
43 | viewvec /= viewvec.z; |
---|
44 | |
---|
45 | //return float4(viewvec.xyz, 1.0f); |
---|
46 | // eye point |
---|
47 | //float3 eyept = eyez * viewvec; |
---|
48 | float3 eyept = float3(IN.texcoord.xy, eyez); |
---|
49 | |
---|
50 | float4 pl = tex2D(normal, IN.pos.xy * invTexSize); |
---|
51 | pl = pl * 2.0 - float4(1.0); |
---|
52 | |
---|
53 | float occlusion = 0.0; |
---|
54 | |
---|
55 | // gather occlusion from surrounding samples |
---|
56 | for (int i = 0; i < 32; i ++) |
---|
57 | { |
---|
58 | // generate new sample point |
---|
59 | //float3 samplepos = eyept + radius * samples[i]; |
---|
60 | // create some dithering by reflecting the sample point alond some random plane |
---|
61 | float3 samplepos = eyept + radius * reflect(samples[i], pl.xyz); |
---|
62 | |
---|
63 | // project to texture space q: why the scaling? |
---|
64 | float2 sampletex = (samplepos.xy / samplepos.z);// * float2(0.75, 1.0); |
---|
65 | |
---|
66 | //float2 sampletexn = sampletex; |
---|
67 | // normalize to [0 .. 1], move eye point to center |
---|
68 | //float2 sampletexn = sampletex * 0.5f + float2(0.5f); |
---|
69 | float2 sampletexn = sampletex + float2(0.5f); |
---|
70 | |
---|
71 | // look up depth at sample point |
---|
72 | float depth = tex2D(lindepth, sampletexn).x; |
---|
73 | // compare: is point occluded? |
---|
74 | //float zdist = 50.0f * max(-samplepos.z + depth, 0.0f); |
---|
75 | float zdist = 50.0f * max(samplepos.z - depth, 0.0f); |
---|
76 | // occlusion factor shrinks quadratic with distance to occluder |
---|
77 | occlusion += 1.0 / (1.0 + zdist * zdist); |
---|
78 | //occlusion += 1.0 / (1.0 + zdist); |
---|
79 | } |
---|
80 | |
---|
81 | // normalize |
---|
82 | occlusion /= 32.0f; |
---|
83 | |
---|
84 | OUT.col = 1.0f - occlusion; |
---|
85 | // OUT.col = tex2D(scene, IN.texcoord.xy) * 0.5 + (1.0f - occlusion); |
---|
86 | |
---|
87 | return OUT; |
---|
88 | } |
---|