1 | struct INPUTDATA
|
---|
2 | {
|
---|
3 | float2 diffuseTexCoords : TEXCOORD0;
|
---|
4 |
|
---|
5 | };
|
---|
6 |
|
---|
7 | struct OUTPUTDATA
|
---|
8 | {
|
---|
9 | float4 color : COLOR0;
|
---|
10 |
|
---|
11 | };
|
---|
12 |
|
---|
13 | #define SAMPLES 24
|
---|
14 |
|
---|
15 | //kustls magic sample positions
|
---|
16 | static const float2 samples[SAMPLES] =
|
---|
17 | {
|
---|
18 | {-0.326212f, -0.405805f},
|
---|
19 | {-0.840144f, -0.07358f},
|
---|
20 | {-0.695914f, 0.457137f},
|
---|
21 | {-0.203345f, 0.620716},
|
---|
22 | {0.96234f, -0.194983f},
|
---|
23 | {0.473434f, -0.480026f},
|
---|
24 | {0.519456, 0.767022f},
|
---|
25 | {0.185461f, -0.893124f},
|
---|
26 | {0.507431f, 0.064425f},
|
---|
27 | {0.89642f, 0.412458f},
|
---|
28 | {-0.32194f, -0.932615f},
|
---|
29 | {-0.791559f, -0.597705f},
|
---|
30 | {0.326212f, 0.405805f},
|
---|
31 | {0.840144f, 0.07358f},
|
---|
32 | {0.695914f, -0.457137f},
|
---|
33 | {0.203345f, -0.620716},
|
---|
34 | {-0.96234f, 0.194983f},
|
---|
35 | {-0.473434f, 0.480026f},
|
---|
36 | {-0.519456, -0.767022f},
|
---|
37 | {-0.185461f, 0.893124f},
|
---|
38 | {-0.507431f, -0.064425f},
|
---|
39 | {-0.89642f, -0.412458f},
|
---|
40 | {0.32194f, 0.932615f},
|
---|
41 | {0.791559f, 0.597705f}
|
---|
42 | };
|
---|
43 |
|
---|
44 | //based on kustls shader
|
---|
45 | OUTPUTDATA main(INPUTDATA input,
|
---|
46 | uniform sampler2D positions,
|
---|
47 | uniform sampler2D colors,
|
---|
48 | uniform sampler2D normals,
|
---|
49 | const uniform float4x4 projectionTransformation,
|
---|
50 | uniform sampler2D noiseTexture
|
---|
51 | )
|
---|
52 | {
|
---|
53 |
|
---|
54 | OUTPUTDATA o;
|
---|
55 |
|
---|
56 | float4 centerPositionW = tex2D(positions, input.diffuseTexCoords);
|
---|
57 | float3 centerPosition = centerPositionW.xyz;
|
---|
58 | float3 centerNormal = tex2D(normals, input.diffuseTexCoords).xyz;
|
---|
59 | float3 centerColor = tex2D(colors, input.diffuseTexCoords).xyz;
|
---|
60 |
|
---|
61 | // Check in a circular area around the current position.
|
---|
62 | // Shoot vectors to the positions there, and check the angle to these positions.
|
---|
63 | // Summing up these angles gives an estimation of the occlusion at the current position.
|
---|
64 |
|
---|
65 | float total_ao = 0.0;
|
---|
66 | const float areaSize = 4.0f;
|
---|
67 | const float sampleIntensity = 0.1;
|
---|
68 |
|
---|
69 | for (int sample = 0; sample < SAMPLES; sample++)
|
---|
70 | {
|
---|
71 | float2 offset = samples[sample];
|
---|
72 |
|
---|
73 | //sample noisetex; r stores costheta, g stores sintheta
|
---|
74 | float3 randomRotation = tex2D(noiseTexture, input.diffuseTexCoords*10.0f).xyz;
|
---|
75 |
|
---|
76 | float2 offsetTransformed;
|
---|
77 | offsetTransformed.x = randomRotation.r*offset.x - randomRotation.g*offset.y;
|
---|
78 | offsetTransformed.y = randomRotation.g*offset.x + randomRotation.r*offset.y;
|
---|
79 |
|
---|
80 |
|
---|
81 | float2 texcoord = input.diffuseTexCoords + offsetTransformed * areaSize*(1.0f-centerPositionW.w);
|
---|
82 |
|
---|
83 | float3 sample_position = tex2D(positions, texcoord).xyz;
|
---|
84 |
|
---|
85 | float3 vector_to_sample = sample_position - centerPosition;
|
---|
86 | float length_to_sample = length(vector_to_sample);
|
---|
87 | float3 direction_to_sample = vector_to_sample / length_to_sample;
|
---|
88 |
|
---|
89 | // Angle between current normal and direction to sample controls AO intensity.
|
---|
90 | float angle = dot(direction_to_sample, centerNormal);
|
---|
91 | angle = max(angle, 0.0);
|
---|
92 |
|
---|
93 | // Distance between current position and sample position controls AO intensity.
|
---|
94 | float distance_intensity = 2.0 - 2.0f*length_to_sample;
|
---|
95 | distance_intensity = max(distance_intensity, 0.0);
|
---|
96 |
|
---|
97 | total_ao += angle * sampleIntensity * distance_intensity;
|
---|
98 | }
|
---|
99 |
|
---|
100 |
|
---|
101 | o.color.rgb = (1.0f-total_ao)*saturate(centerColor);
|
---|
102 |
|
---|
103 |
|
---|
104 | return o;
|
---|
105 | } |
---|