struct INPUTDATA { float2 diffuseTexCoords : TEXCOORD0; }; struct OUTPUTDATA { float4 color : COLOR0; }; #define SAMPLES 24 //kustls magic sample positions static const float2 samples[SAMPLES] = { {-0.326212f, -0.405805f}, {-0.840144f, -0.07358f}, {-0.695914f, 0.457137f}, {-0.203345f, 0.620716}, {0.96234f, -0.194983f}, {0.473434f, -0.480026f}, {0.519456, 0.767022f}, {0.185461f, -0.893124f}, {0.507431f, 0.064425f}, {0.89642f, 0.412458f}, {-0.32194f, -0.932615f}, {-0.791559f, -0.597705f}, {0.326212f, 0.405805f}, {0.840144f, 0.07358f}, {0.695914f, -0.457137f}, {0.203345f, -0.620716}, {-0.96234f, 0.194983f}, {-0.473434f, 0.480026f}, {-0.519456, -0.767022f}, {-0.185461f, 0.893124f}, {-0.507431f, -0.064425f}, {-0.89642f, -0.412458f}, {0.32194f, 0.932615f}, {0.791559f, 0.597705f} }; //based on kustls shader OUTPUTDATA main(INPUTDATA input, uniform sampler2D positions, uniform sampler2D colors, uniform sampler2D normals, const uniform float4x4 projectionTransformation, uniform sampler2D noiseTexture ) { OUTPUTDATA o; float4 centerPositionW = tex2D(positions, input.diffuseTexCoords); float3 centerPosition = centerPositionW.xyz; float3 centerNormal = tex2D(normals, input.diffuseTexCoords).xyz; float3 centerColor = tex2D(colors, input.diffuseTexCoords).xyz; // Check in a circular area around the current position. // Shoot vectors to the positions there, and check the angle to these positions. // Summing up these angles gives an estimation of the occlusion at the current position. float total_ao = 0.0; const float areaSize = 4.0f; const float sampleIntensity = 0.1; for (int sample = 0; sample < SAMPLES; sample++) { float2 offset = samples[sample]; //sample noisetex; r stores costheta, g stores sintheta float3 randomRotation = tex2D(noiseTexture, input.diffuseTexCoords*10.0f).xyz; float2 offsetTransformed; offsetTransformed.x = randomRotation.r*offset.x - randomRotation.g*offset.y; offsetTransformed.y = randomRotation.g*offset.x + randomRotation.r*offset.y; float2 texcoord = input.diffuseTexCoords + offsetTransformed * areaSize*(1.0f-centerPositionW.w); float3 sample_position = tex2D(positions, texcoord).xyz; float3 vector_to_sample = sample_position - centerPosition; float length_to_sample = length(vector_to_sample); float3 direction_to_sample = vector_to_sample / length_to_sample; // Angle between current normal and direction to sample controls AO intensity. float angle = dot(direction_to_sample, centerNormal); angle = max(angle, 0.0); // Distance between current position and sample position controls AO intensity. float distance_intensity = 2.0 - 2.0f*length_to_sample; distance_intensity = max(distance_intensity, 0.0); total_ao += angle * sampleIntensity * distance_intensity; } o.color.rgb = (1.0f-total_ao)*saturate(centerColor); return o; }