[2810] | 1 | #define SAMPLES 24 |
---|
| 2 | |
---|
| 3 | // kustls magic sample positions |
---|
| 4 | static const float2 samples[SAMPLES] = |
---|
| 5 | { |
---|
| 6 | {-0.326212f, -0.405805f}, |
---|
| 7 | {-0.840144f, -0.07358f}, |
---|
| 8 | {-0.695914f, 0.457137f}, |
---|
| 9 | {-0.203345f, 0.620716}, |
---|
| 10 | {0.96234f, -0.194983f}, |
---|
| 11 | {0.473434f, -0.480026f}, |
---|
| 12 | {0.519456, 0.767022f}, |
---|
| 13 | {0.185461f, -0.893124f}, |
---|
| 14 | {0.507431f, 0.064425f}, |
---|
| 15 | {0.89642f, 0.412458f}, |
---|
| 16 | {-0.32194f, -0.932615f}, |
---|
| 17 | {-0.791559f, -0.597705f}, |
---|
| 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 | }; |
---|
| 31 | |
---|
| 32 | |
---|
| 33 | struct fragment |
---|
| 34 | { |
---|
| 35 | float4 pos: WPOS; // normalized screen position |
---|
| 36 | float4 texCoord: TEXCOORD0; |
---|
| 37 | }; |
---|
| 38 | |
---|
| 39 | |
---|
| 40 | struct pixel |
---|
| 41 | { |
---|
| 42 | float4 color: COLOR0; |
---|
| 43 | }; |
---|
| 44 | |
---|
| 45 | |
---|
| 46 | //based on kustls shader |
---|
| 47 | float ssao(fragment IN, |
---|
| 48 | uniform sampler2D positions, |
---|
| 49 | uniform sampler2D normals, |
---|
| 50 | const uniform float4x4 ProjTrafo, |
---|
| 51 | uniform sampler2D noiseTexture |
---|
| 52 | ) |
---|
| 53 | { |
---|
| 54 | // the current world position |
---|
| 55 | float4 centerPositionW = tex2D(positions, IN.texCoord.xy); |
---|
| 56 | float3 centerPosition = centerPositionW.xyz; |
---|
| 57 | |
---|
| 58 | // the normal on the current position |
---|
[2811] | 59 | float3 centerNormal = tex2D(normals, IN.texCoord.xy).xyz; |
---|
| 60 | normalize(centerNormal); |
---|
| 61 | |
---|
[2810] | 62 | // Check in a circular area around the current position. |
---|
| 63 | // Shoot vectors to the positions there, and check the angle to these positions. |
---|
| 64 | // Summing up these angles gives an estimation of the occlusion at the current position. |
---|
| 65 | |
---|
| 66 | float total_ao = 0.0; |
---|
| 67 | |
---|
| 68 | //const float areaSize = 4.0f; |
---|
[2811] | 69 | const float areaSize = 4e-3f; |
---|
| 70 | const float sampleIntensity = 0.1f; |
---|
[2810] | 71 | |
---|
| 72 | for (int i = 0; i < SAMPLES; i ++) { |
---|
| 73 | float2 offset = samples[i]; |
---|
| 74 | |
---|
| 75 | //sample noisetex; r stores costheta, g stores sintheta |
---|
| 76 | float3 noise = tex2D(noiseTexture, IN.texCoord.xy).xyz * 2.0f - 1.0f; |
---|
| 77 | |
---|
[2811] | 78 | // float2 offsetTransformed = offset; |
---|
[2810] | 79 | float2 offsetTransformed; |
---|
| 80 | offsetTransformed.x = noise.r*offset.x - noise.g*offset.y; |
---|
| 81 | offsetTransformed.y = noise.g*offset.x + noise.r*offset.y; |
---|
| 82 | |
---|
| 83 | float2 texcoord = IN.texCoord.xy + offsetTransformed * areaSize;// * (1.0f - centerPositionW.w); |
---|
| 84 | |
---|
| 85 | float3 sample_position = tex2D(positions, texcoord).xyz; |
---|
| 86 | |
---|
| 87 | float3 vector_to_sample = sample_position - centerPosition; |
---|
[2811] | 88 | // vector_to_sample.z = -vector_to_sample.z; |
---|
[2810] | 89 | float length_to_sample = length(vector_to_sample); |
---|
[2811] | 90 | float3 direction_to_sample = vector_to_sample / (length_to_sample + 1e-9f); |
---|
[2810] | 91 | |
---|
| 92 | // Angle between current normal and direction to sample controls AO intensity. |
---|
| 93 | float cos_angle = dot(direction_to_sample, centerNormal); |
---|
| 94 | cos_angle = max(cos_angle, 0.0f); |
---|
| 95 | |
---|
| 96 | // distance between current position and sample position controls AO intensity. |
---|
[2811] | 97 | const float maxdist = 5e-1f; |
---|
| 98 | //const float scale = 50.0f; |
---|
[2810] | 99 | |
---|
[2811] | 100 | float distance_intensity = maxdist - length_to_sample; |
---|
[2810] | 101 | distance_intensity = max(distance_intensity, 0.0f); |
---|
| 102 | |
---|
| 103 | total_ao += cos_angle * sampleIntensity * distance_intensity; |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | return (1.0f - total_ao); |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | |
---|
| 110 | pixel main(fragment IN, |
---|
| 111 | uniform sampler2D colors, |
---|
| 112 | uniform sampler2D positions, |
---|
| 113 | uniform sampler2D normals, |
---|
| 114 | const uniform float4x4 ProjTrafo, |
---|
| 115 | uniform sampler2D noiseTexture) |
---|
| 116 | { |
---|
| 117 | pixel OUT; |
---|
[2811] | 118 | //float4 lightDir = float4(1.0f, 1.0f, 1.0f, 0.0f); |
---|
| 119 | float4 lightDir = float4(0.0f, 1.0f, 0.0f, 0.0f); |
---|
[2810] | 120 | |
---|
| 121 | float4 color = tex2D(colors, IN.texCoord.xy); |
---|
| 122 | float3 normal = tex2D(normals, IN.texCoord.xy).xyz; |
---|
| 123 | // expand normal |
---|
| 124 | normal = normal * 2.0f - 1.0f; |
---|
| 125 | |
---|
| 126 | float4 position = tex2D(positions, IN.texCoord.xy); |
---|
| 127 | |
---|
[2811] | 128 | float4 ambient = float4(0.1f); |
---|
[2810] | 129 | |
---|
| 130 | // float3 L = normalize(lightPosition - position); |
---|
| 131 | float3 light = normalize(lightDir.xyz); |
---|
| 132 | |
---|
| 133 | float diffuseLight = max(dot(normal, light), 0.0f); |
---|
| 134 | float diffuse = diffuseLight; |
---|
| 135 | |
---|
| 136 | float ao = ssao(IN, positions, normals, ProjTrafo, noiseTexture); |
---|
| 137 | OUT.color = ao; //(ambient + diffuse) * color; |
---|
| 138 | //OUT.color = (ambient + diffuse) * color; |
---|
[2811] | 139 | |
---|
[2810] | 140 | //float4 currentPos = tex2D(positions, IN.texCoord.xy); |
---|
| 141 | //OUT.color = currentPos; |
---|
[2811] | 142 | //float4 currentPos = tex2D(normals, IN.texCoord.xy) * 0.5f + 0.5f; |
---|
| 143 | //OUT.color = currentPos; |
---|
[2810] | 144 | |
---|
| 145 | return OUT; |
---|
| 146 | } |
---|