Alchemy AO
This commit is contained in:
parent
9145384a9c
commit
d6e7a7d1ca
|
@ -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);
|
||||
}
|
||||
|
|
65
raw/blur_pass/blur_pass_edges.frag.glsl
Normal file
65
raw/blur_pass/blur_pass_edges.frag.glsl
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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": [],
|
||||
|
|
146
raw/ssao_pass/ssao_pass_st.frag.glsl
Normal file
146
raw/ssao_pass/ssao_pass_st.frag.glsl
Normal 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.);
|
||||
}
|
Loading…
Reference in a new issue