Pixel-Composer/shaders/sh_d3d_ssao/sh_d3d_ssao.fsh

71 lines
2.3 KiB
Plaintext
Raw Normal View History

2023-08-28 12:56:00 +02:00
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
#define MAX_SAMPLE 256
uniform sampler2D vPosition;
uniform sampler2D vNormal;
uniform float radius;
uniform float bias;
uniform float strength;
uniform vec3 cameraPosition;
uniform mat4 projMatrix;
float seed = 234234.453;
float rand(vec2 pos) {
float value = dot(pos, vec2(12.9898, 78.233));
value = fract(sin(value + seed) * 43758.5453);
seed++;
return value;
}
float rand(vec3 pos) {
float value = dot(pos, vec3(12.9898, 78.233, 45.164));
value = fract(sin(value + seed) * 43758.5453);
seed++;
return value;
}
void main() {
vec3 cPosition = texture2D( vPosition, v_vTexcoord ).rgb;
vec3 cNormal = texture2D( vNormal, v_vTexcoord ).rgb;
cNormal = normalize(cNormal);
gl_FragColor = vec4(0.);
float occluded = 0.;
float raysTotal = float(MAX_SAMPLE);
vec3 rvec = vec3(rand(v_vTexcoord), rand(v_vTexcoord), rand(v_vTexcoord)) * 2. - 1.;
vec3 tangent = normalize(rvec - cNormal * dot(rvec, cNormal));
vec3 bitangent = cross(cNormal, tangent);
mat3 tbn = mat3(tangent, bitangent, cNormal); //matrix to align the deviated vector to the normal hemisphere.
for(int i = 0; i < MAX_SAMPLE; i++ ) {
vec3 sNormal = tbn * vec3( rand(v_vTexcoord) * 2. - 1., rand(v_vTexcoord) * 2. - 1., rand(v_vTexcoord) ); // genetate random point inside the hemisphere.
float scale = length(sNormal);
scale = mix(0.1, 1.0, scale * scale);
sNormal = normalize(sNormal) * scale;
vec3 wPosition = cPosition + sNormal * radius; //add random vector to current world position.
float vecToCamDist = distance(wPosition, cameraPosition);
vec4 projPos = projMatrix * vec4(wPosition, 1.);
projPos.xyz /= projPos.w;
projPos = (projPos + 1.) / 2.; //project new world position to view space.
vec3 sPosition = texture2D( vPosition, projPos.xy ).xyz; //sample depth at the new point in the view space.
if(sPosition == vec3(0.)) continue;
float geoToCamDist = distance(sPosition, cameraPosition);
if(distance(sPosition, cPosition) < radius)
if(vecToCamDist - bias > geoToCamDist)
occluded++;
}
gl_FragColor = vec4(vec3(1. - occluded / raysTotal * strength), 1.);
//gl_FragColor = vec4(vec3(distance(cPosition, cameraPosition) / 10.), 1.);
}