Alchemy AO

This commit is contained in:
Lubos Lenco 2016-03-26 12:53:25 +01:00
parent 9145384a9c
commit d6e7a7d1ca
11 changed files with 561 additions and 267 deletions

View file

@ -10,14 +10,19 @@ uniform vec2 dir;
in vec2 texCoord;
void main() {
vec2 step = dir / vec2(640, 480.0);
vec2 step = dir / vec2(400, 300);
float res = texture( tex, texCoord + (step * 2.0) ).r;
float res = texture( tex, texCoord + (step * 4.0) ).r;
res += texture( tex, texCoord + (step * 3.0) ).r;
res += texture( tex, texCoord + (step * 2.0) ).r;
res += texture( tex, texCoord + step ).r;
res += texture( tex, texCoord ).r;
res += texture( tex, texCoord -step ).r;
res += texture( tex, texCoord -(step * 2.0) ).r;
res /= 5.0;
res += texture( tex, texCoord -(step * 3.0) ).r;
res += texture( tex, texCoord -(step * 4.0) ).r;
res /= 9.0;
gl_FragColor = vec4(vec3(res), 1.0);
// gl_FragColor = texture(tex, texCoord);
}

View file

@ -0,0 +1,65 @@
#version 450
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D tex;
uniform sampler2D gbuffer0;
uniform vec2 dir;
in vec2 texCoord;
void main() {
vec2 pixelStep = dir / vec2(800, 600);
vec3 blurredResult = vec3( 0.0, 0.0, 0.0 );
float depth = texture(gbuffer0, texCoord).a;
float weight = 0.0;
// for (float i = -3.0; i <= 3.0; i += 1.0) {
// float pixelDepth = texture(gbuffer0, texCoord + i * pixelStep).a;
// float pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
// weight += pixelWeight;
// blurredResult += texture(tex, texCoord + i * pixelStep).rgb * pixelWeight;
float pixelDepth = texture(gbuffer0, texCoord + pixelStep * -3).a;
float pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
weight += pixelWeight;
blurredResult += texture(tex, texCoord + pixelStep * -3).rgb * pixelWeight;
pixelDepth = texture(gbuffer0, texCoord + pixelStep * -2).a;
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
weight += pixelWeight;
blurredResult += texture(tex, texCoord + pixelStep * -2).rgb * pixelWeight;
pixelDepth = texture(gbuffer0, texCoord + pixelStep * -1).a;
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
weight += pixelWeight;
blurredResult += texture(tex, texCoord + pixelStep * -1).rgb * pixelWeight;
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 0).a;
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
weight += pixelWeight;
blurredResult += texture(tex, texCoord + pixelStep * 0).rgb * pixelWeight;
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 1).a;
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
weight += pixelWeight;
blurredResult += texture(tex, texCoord + pixelStep * 1).rgb * pixelWeight;
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 2).a;
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
weight += pixelWeight;
blurredResult += texture(tex, texCoord + pixelStep * 2).rgb * pixelWeight;
pixelDepth = texture(gbuffer0, texCoord + pixelStep * 3).a;
pixelWeight = max(0.0, 1.0 - step(0.2, abs(depth - pixelDepth)));
weight += pixelWeight;
blurredResult += texture(tex, texCoord + pixelStep * 3).rgb * pixelWeight;
// }
blurredResult /= weight;
gl_FragColor = vec4(vec3(blurredResult), 1.0);
}

View file

@ -1,113 +0,0 @@
#version 450
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D tex;
uniform sampler2D gbuffer0;
uniform vec2 dir;
in vec2 texCoord;
void main() {
float weights[9];
weights[0] = 0.013519569015984728;
weights[1] = 0.047662179108871855;
weights[2] = 0.11723004402070096;
weights[3] = 0.20116755999375591;
weights[4] = 0.240841295721373;
weights[5] = 0.20116755999375591;
weights[6] = 0.11723004402070096;
weights[7] = 0.047662179108871855;
weights[8] = 0.013519569015984728;
float indices[9];
indices[0] = -4;
indices[1] = -3;
indices[2] = -2;
indices[3] = -1;
indices[4] = 0;
indices[5] = 1;
indices[6] = 2;
indices[7] = 3;
indices[8] = 4;
vec2 step = dir / vec2(640, 480); //g_resolution.xy;
vec3 normal[9];
normal[0] = texture(gbuffer0, texCoord + indices[0]*step).rgb * 2.0 - 1.0;
normal[1] = texture(gbuffer0, texCoord + indices[1]*step).rgb * 2.0 - 1.0;
normal[2] = texture(gbuffer0, texCoord + indices[2]*step).rgb * 2.0 - 1.0;
normal[3] = texture(gbuffer0, texCoord + indices[3]*step).rgb * 2.0 - 1.0;
normal[4] = texture(gbuffer0, texCoord + indices[4]*step).rgb * 2.0 - 1.0;
normal[5] = texture(gbuffer0, texCoord + indices[5]*step).rgb * 2.0 - 1.0;
normal[6] = texture(gbuffer0, texCoord + indices[6]*step).rgb * 2.0 - 1.0;
normal[7] = texture(gbuffer0, texCoord + indices[7]*step).rgb * 2.0 - 1.0;
normal[8] = texture(gbuffer0, texCoord + indices[8]*step).rgb * 2.0 - 1.0;
float total_weight = 1.0;
float discard_threshold = 0.85;
//int i;
// for(i = 0; i < 9; ++i) {
// if (dot(normal[i], normal[4]) < discard_threshold) {
// total_weight -= weights[i];
// weights[i] = 0;
// }
if (dot(normal[0], normal[4]) < discard_threshold) {
total_weight -= weights[0];
weights[0] = 0;
}
if (dot(normal[1], normal[4]) < discard_threshold) {
total_weight -= weights[1];
weights[1] = 0;
}
if (dot(normal[2], normal[4]) < discard_threshold) {
total_weight -= weights[2];
weights[2] = 0;
}
if (dot(normal[3], normal[4]) < discard_threshold) {
total_weight -= weights[3];
weights[3] = 0;
}
if (dot(normal[4], normal[4]) < discard_threshold) {
total_weight -= weights[4];
weights[4] = 0;
}
if (dot(normal[5], normal[4]) < discard_threshold) {
total_weight -= weights[5];
weights[5] = 0;
}
if (dot(normal[6], normal[4]) < discard_threshold) {
total_weight -= weights[6];
weights[6] = 0;
}
if (dot(normal[7], normal[4]) < discard_threshold) {
total_weight -= weights[7];
weights[7] = 0;
}
if (dot(normal[8], normal[4]) < discard_threshold) {
total_weight -= weights[8];
weights[8] = 0;
}
// }
float res = 0.0;
//for (i = 0; i < 9; ++i) {
//res += texture(tex, texCoord + indices[i]*step).r * weights[i];
res += texture(tex, texCoord + indices[0]*step).r * weights[0];
res += texture(tex, texCoord + indices[1]*step).r * weights[1];
res += texture(tex, texCoord + indices[2]*step).r * weights[2];
res += texture(tex, texCoord + indices[3]*step).r * weights[3];
res += texture(tex, texCoord + indices[4]*step).r * weights[4];
res += texture(tex, texCoord + indices[5]*step).r * weights[5];
res += texture(tex, texCoord + indices[6]*step).r * weights[6];
res += texture(tex, texCoord + indices[7]*step).r * weights[7];
res += texture(tex, texCoord + indices[8]*step).r * weights[8];
//}
res /= total_weight;
gl_FragColor = vec4(res, 0.0, 0.0, 1.0);
}

View file

@ -81,7 +81,7 @@ void main() {
// occlusion
gl_FragData[0] = vec4(normal.xyz * 0.5 + 0.5, depth);
gl_FragData[1] = vec4(position.xyz * 0.5 + 0.5, roughness);
gl_FragData[0] = vec4(n.xyz, depth);
gl_FragData[1] = vec4(position.xyz, roughness);
gl_FragData[2] = vec4(baseColor.rgb, metalness);
}

View file

@ -141,6 +141,8 @@ void main() {
vec3 bitangent = normalize(cross(_normal, tangent));
TBN = mat3(tangent, bitangent, _normal);
#else
// vec4 n = V * vec4(_normal, 1.0);
// normal = n.xyz;
normal = _normal;
#endif
}

View file

@ -140,8 +140,8 @@ void main() {
vec4 g2 = texture(gbuffer2, texCoord); // Base color, metalness
float ao = texture(ssaotex, texCoord).r; // Normals, depth
vec3 n = g0.rgb * 2.0 - 1.0;
vec3 p = g1.rgb * 2.0 - 1.0;
vec3 n = g0.rgb;
vec3 p = g1.rgb;
//n = normalize(n);
vec3 baseColor = g2.rgb;
@ -188,10 +188,12 @@ void main() {
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
vec3 indirect = indirectDiffuse + indirectSpecular;
vec4 outColor = vec4(vec3(direct * visibility + indirect), 1.0);
vec4 outColor = vec4(vec3(direct * visibility + indirect * ao), 1.0);
// outColor.rgb *= occlusion;
outColor.rgb *= ao;
// outColor.rgb *= ao;
gl_FragColor = vec4(pow(outColor.rgb, vec3(1.0 / 2.2)), outColor.a);
// vec4 aocol = texture(ssaotex, texCoord);
// gl_FragColor = aocol;
}

View file

@ -8,33 +8,33 @@ uniform sampler2D tex;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
const float focus_depth = 0.3;
const float focus_depth = 0.5;
in vec2 texCoord;
vec4 sampleBox(float u, float v, float size) {
vec4 color = vec4(0.0,0.0,0.0,0.0);
color += texture(tex, vec2(texCoord.x - size, texCoord.y - size)) * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y - size)) * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y - size)) * 0.075;
color += texture(tex, vec2(texCoord.x - size, texCoord.y)) * 0.1;
color += texture(tex, vec2(texCoord.x, texCoord.y)) * 0.30;
color += texture(tex, vec2(texCoord.x + size, texCoord.y)) * 0.1;
color += texture(tex, vec2(texCoord.x - size, texCoord.y + size)) * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y + size)) * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y + size)) * 0.075;
vec4 sampleBox(float size) {
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
color += texture(tex, vec2(texCoord.x - size, texCoord.y - size)) * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y - size)) * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y - size)) * 0.075;
color += texture(tex, vec2(texCoord.x - size, texCoord.y)) * 0.1;
color += texture(tex, vec2(texCoord.x, texCoord.y)) * 0.30;
color += texture(tex, vec2(texCoord.x + size, texCoord.y)) * 0.1;
color += texture(tex, vec2(texCoord.x - size, texCoord.y + size)) * 0.075;
color += texture(tex, vec2(texCoord.x, texCoord.y + size)) * 0.1;
color += texture(tex, vec2(texCoord.x + size, texCoord.y + size)) * 0.075;
return color;
}
void main() {
float depth = texture(gbuffer0, texCoord).a;
float blur_amount = abs(depth-_u1);
if(depth < depth-_u1) {
float blur_amount = abs(depth - focus_depth);
if(depth < depth - focus_depth) {
blur_amount *= 10.0;
}
blur_amount = clamp(blur_amount, 0.0, 1.0);
vec4 baseColor = texture(tex, texCoord);
vec4 blurredColor = vec4(0.0,0.0,0.0,0.0);
float blurSize = 0.005*blur_amount;
blurredColor = 0.75*sampleBox(texCoord.x, texCoord.y, blurSize*0.5) + 0.25*sampleBox(texCoord.x, texCoord.y, blurSize*1.0);
vec4 blurredColor = vec4(0.0, 0.0, 0.0, 0.0);
float blurSize = 0.005 * blur_amount;
blurredColor = 0.75 * sampleBox(blurSize * 0.5) + 0.25 * sampleBox(blurSize * 1.0);
gl_FragColor = baseColor * (1.0 - blur_amount) + blurredColor * blur_amount;
}

View file

@ -18,7 +18,7 @@ in vec2 texCoord;
vec2 getVelocity(vec2 texCoord, float depth) {
// Get the depth buffer value at this pixel
float zOverW = depth;
float zOverW = depth; // * 2.0 - 1.0
// H is the viewport position at this pixel in the range -1 to 1
vec4 H = vec4(texCoord.x * 2.0 - 1.0, (texCoord.y) * 2.0 - 1.0, zOverW, 1.0);
// Transform by the view-projection inverse

View file

@ -1,5 +1,16 @@
// Based on SSAO by Reinder Nijhoff 2016 @reindernijhoff
// https://www.shadertoy.com/view/ls3GWS
// Alchemy AO
// Compute kernel
// var kernel:Array<Float> = [];
// var kernelSize = 8;
// for (i in 0...kernelSize) {
// var angle = i / kernelSize;
// angle *= 3.1415926535 * 2.0;
// var x1 = Math.cos(angle);
// var y1 = Math.sin(angle);
// x1 = Std.int(x1 * 10000000) / 10000000;
// y1 = Std.int(y1 * 10000000) / 10000000;
// trace(x1, y1);
// }
#version 450
@ -7,140 +18,284 @@
precision mediump float;
#endif
#define SAMPLES 8
#define INTENSITY 3.5
#define SCALE 3.5
#define BIAS 0.75
#define SAMPLE_RAD 0.1
#define MAX_DISTANCE 0.34
#define MOD3 vec3(.1031,.11369,.13787)
uniform mat4 invP;
uniform mat4 invVP;
uniform mat4 invV;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
uniform sampler2D snoise;
const float PI = 3.1415926535;
const vec2 screenSize = vec2(800.0, 600.0);
const float aoSize = 0.43;
const int kernelSize = 8;
const float strength = 0.55;
in vec2 texCoord;
float hash12(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * MOD3);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.x + p3.y) * p3.z);
float linearize(float depth, float znear, float zfar) {
return -zfar * znear / (depth * (zfar - znear) - zfar);
}
// vec3 getPosition(vec2 uv) {
// float fl = texture(iChannel0, vec2(0.)).x;
// float d = texture(iChannel0, uv).w;
// vec2 p = uv*2.-1.;
// mat3 ca = mat3(1.,0.,0.,0.,1.,0.,0.,0.,-1./1.5);
// vec3 rd = normalize( ca * vec3(p,fl) );
// vec3 pos = rd * d;
// return pos;
// float rand(vec2 co) { // Unreliable
// return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
// }
vec3 getViewPos(vec2 texCoord, float depth) {
float x = texCoord.s * 2.0 - 1.0;
float y = texCoord.t * 2.0 - 1.0;
float z = depth * 2.0 - 1.0;
vec4 posProj = vec4(x, y, z, 1.0);
vec4 posView = invP * posProj;
posView /= posView.w;
return posView.xyz;
}
float doAmbientOcclusion(vec2 tcoord,vec2 uv, vec3 p, vec3 cnorm)
{
// vec3 diff = getPosition(tcoord + uv) - p;
float depth = texture(gbuffer0, tcoord + uv).a;
vec3 diff = getViewPos(tcoord + uv, depth) - p;
float l = length(diff);
vec3 v = diff/l;
float d = l*SCALE;
float ao = max(0.0,dot(cnorm,v)-BIAS)*(1.0/(1.0+d));
ao *= smoothstep(MAX_DISTANCE,MAX_DISTANCE * 0.5, l);
return ao;
}
float spiralAO(vec2 uv, vec3 p, vec3 n, float rad)
{
float goldenAngle = 2.4;
float ao = 0.;
float inv = 1. / float(SAMPLES);
float radius = 0.;
float rotatePhase = hash12( uv*100. ) * 6.28;
float rStep = inv * rad;
vec2 spiralUV;
// for (int i = 0; i < SAMPLES; i++) {
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
//}
ao *= inv;
return ao;
}
void main() {
vec4 g0 = texture(gbuffer0, texCoord);
float depth = g0.a;
vec3 n = g0.rgb * 2.0 - 1.0;
vec3 p = getViewPos(texCoord, depth);
float ao = 0.;
float rad = SAMPLE_RAD/p.z;
ao = spiralAO(texCoord, p, n, rad);
ao = 1. - ao * INTENSITY;
gl_FragColor = vec4(ao,ao,ao,1.);
void main() {
vec2 kernel[kernelSize];
kernel[0] = vec2(1.0, 0.0);
kernel[1] = vec2(0.7071067, 0.7071067);
kernel[2] = vec2(0.0, 1.0);
kernel[3] = vec2(-0.7071067, 0.7071067);
kernel[4] = vec2(-1.0, 0.0);
kernel[5] = vec2(-0.7071067, -0.7071067);
kernel[6] = vec2(0.0, -1.0);
kernel[7] = vec2(0.7071067, -0.7071067);
// kernel[0] = vec2(1.0, 0.0);
// kernel[1] = vec2(0.8660254, 0.4999999);
// kernel[2] = vec2(0.5, 0.8660254);
// kernel[3] = vec2(0.0, 1.0);
// kernel[4] = vec2(-0.4999999, 0.8660254);
// kernel[5] = vec2(-0.8660254, 0.5);
// kernel[6] = vec2(-1.0, 0.0);
// kernel[7] = vec2(-0.8660254, -0.4999999);
// kernel[8] = vec2(-0.5, -0.8660254);
// kernel[9] = vec2(0.0, -1.0);
// kernel[10] = vec2(0.4999999, -0.8660254);
// kernel[11] = vec2(0.8660254, -0.5);
vec4 g0 = texture(gbuffer0, texCoord);
vec4 g1 = texture(gbuffer1, texCoord);
vec3 N = g0.rgb;
vec3 P = g1.rgb;
// Get the current pixel's positiom
vec3 currentPos = P;
// float currentDistance = length(currentPos);
float currentDistance = linearize(g0.a, 0.1, 1000.0);
vec3 currentNormal = N;
vec2 aspectRatio = vec2(min(1.0, screenSize.y / screenSize.x), min(1.0, screenSize.x / screenSize.y));
// Grab a random vector from a 8x8 tiled random texture
// vec2 randomVec = vec2(rand(texCoord), rand(texCoord * 2.0));
vec2 randomVec = texture(snoise, (0.5 * texCoord * screenSize) / 8.0).xy;
randomVec *= 2.0;
randomVec -= 1.0;
mat2 rotMat = mat2( vec2( cos( randomVec.x * PI ), -sin( randomVec.x * PI ) ),
vec2( sin( randomVec.x * PI ), cos( randomVec.x * PI ) ) );
float amount = 0.0;
// for (int i = 0; i < kernelSize; i++) {
vec2 kernelVec = kernel[0];
kernelVec.xy *= aspectRatio;
float radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
vec3 pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
float angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[1];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[2];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[3];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[4];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[5];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[6];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[7];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
/*
kernelVec = kernel[8];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[9];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[10];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[11];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;*/
// }
amount *= strength / kernelSize;
amount = 1.0 - amount;
amount = max(0.0, amount);
gl_FragColor = vec4(vec3(amount), 1.0);
}

View file

@ -28,6 +28,38 @@
{
"id": "invP",
"link": "_inverseProjectionMatrix"
},
{
"id": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{
"id": "invV",
"link": "_inverseViewMatrix"
},
{
"id": "_u1",
"link": "_u1"
},
{
"id": "_u2",
"link": "_u2"
},
{
"id": "_u3",
"link": "_u3"
},
{
"id": "_u4",
"link": "_u4"
},
{
"id": "_u5",
"link": "_u5"
},
{
"id": "_u6",
"link": "_u6"
}
],
"texture_params": [],

View file

@ -0,0 +1,146 @@
// Based on SSAO by Reinder Nijhoff 2016 @reindernijhoff
// https://www.shadertoy.com/view/ls3GWS
#version 450
#ifdef GL_ES
precision mediump float;
#endif
#define SAMPLES 8
#define INTENSITY 3.5
#define SCALE 3.5
#define BIAS 0.75
#define SAMPLE_RAD 0.1
#define MAX_DISTANCE 0.34
#define MOD3 vec3(.1031,.11369,.13787)
uniform mat4 invP;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
in vec2 texCoord;
float hash12(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * MOD3);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.x + p3.y) * p3.z);
}
// vec3 getPosition(vec2 uv) {
// float fl = texture(iChannel0, vec2(0.)).x;
// float d = texture(iChannel0, uv).w;
// vec2 p = uv*2.-1.;
// mat3 ca = mat3(1.,0.,0.,0.,1.,0.,0.,0.,-1./1.5);
// vec3 rd = normalize( ca * vec3(p,fl) );
// vec3 pos = rd * d;
// return pos;
// }
vec3 getViewPos(vec2 texCoord, float depth) {
float x = texCoord.s * 2.0 - 1.0;
float y = texCoord.t * 2.0 - 1.0;
float z = depth * 2.0 - 1.0;
vec4 posProj = vec4(x, y, z, 1.0);
vec4 posView = invP * posProj;
posView /= posView.w;
return posView.xyz;
}
float doAmbientOcclusion(vec2 tcoord,vec2 uv, vec3 p, vec3 cnorm)
{
// vec3 diff = getPosition(tcoord + uv) - p;
float depth = texture(gbuffer0, tcoord + uv).a;
vec3 diff = getViewPos(tcoord + uv, depth) - p;
float l = length(diff);
vec3 v = diff/l;
float d = l*SCALE;
float ao = max(0.0,dot(cnorm,v)-BIAS)*(1.0/(1.0+d));
ao *= smoothstep(MAX_DISTANCE,MAX_DISTANCE * 0.5, l);
return ao;
}
float spiralAO(vec2 uv, vec3 p, vec3 n, float rad)
{
float goldenAngle = 2.4;
float ao = 0.;
float inv = 1. / float(SAMPLES);
float radius = 0.;
float rotatePhase = hash12( uv*100. ) * 6.28;
float rStep = inv * rad;
vec2 spiralUV;
// for (int i = 0; i < SAMPLES; i++) {
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
spiralUV.x = sin(rotatePhase);
spiralUV.y = cos(rotatePhase);
radius += rStep;
ao += doAmbientOcclusion(uv, spiralUV * radius, p, n);
rotatePhase += goldenAngle;
//}
ao *= inv;
return ao;
}
void main() {
vec4 g0 = texture(gbuffer0, texCoord);
float depth = g0.a;
vec3 n = g0.rgb * 2.0 - 1.0;
vec3 p = getViewPos(texCoord, depth);
float ao = 0.;
float rad = SAMPLE_RAD/p.z;
ao = spiralAO(texCoord, p, n, rad);
ao = 1. - ao * INTENSITY;
gl_FragColor = vec4(ao,ao,ao,1.);
}