Blur and SSAO passes

This commit is contained in:
Lubos Lenco 2016-03-22 12:04:08 +01:00
parent 3578f775f5
commit 01c8806abd
8 changed files with 266 additions and 238 deletions

View file

@ -4,108 +4,20 @@
precision mediump float;
#endif
uniform sampler2D aomap;
uniform sampler2D gmap;
uniform sampler2D tex;
uniform vec2 dir;
in vec2 texCoord;
vec3 normalFromDepth(float depth, vec2 texcoords) {
const vec2 offset1 = vec2(0.0, 0.001);
const vec2 offset2 = vec2(0.001, 0.0);
float depth1 = (texture(gmap, texcoords + offset1).r - 0.5) * 2.0;
float depth2 = (texture(gmap, texcoords + offset2).r - 0.5) * 2.0;
vec3 p1 = vec3(offset1, depth1 - depth);
vec3 p2 = vec3(offset2, depth2 - depth);
vec3 normal = cross(p1, p2);
normal.z = -normal.z;
return normalize(normal);
}
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;
vec2 step = dir / vec2(640, 480.0);
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(1136.0, 640.0); //g_resolution.xy;
vec3 normal[9];
float depth = (texture(gmap, texCoord + indices[0]*step).r - 0.5) * 2.0;
normal[0] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[1]*step).r - 0.5) * 2.0;
normal[1] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[2]*step).r - 0.5) * 2.0;
normal[2] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[3]*step).r - 0.5) * 2.0;
normal[3] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[4]*step).r - 0.5) * 2.0;
normal[4] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[5]*step).r - 0.5) * 2.0;
normal[5] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[6]*step).r - 0.5) * 2.0;
normal[6] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[7]*step).r - 0.5) * 2.0;
normal[7] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[8]*step).r - 0.5) * 2.0;
normal[8] = normalFromDepth(depth, texCoord);
// normal[0] = texture(gmap, texCoord + indices[0]*step).r;
// normal[1] = texture(gmap, texCoord + indices[1]*step).r;
// normal[2] = texture(gmap, texCoord + indices[2]*step).r;
// normal[3] = texture(gmap, texCoord + indices[3]*step).r;
// normal[4] = texture(gmap, texCoord + indices[4]*step).r;
// normal[5] = texture(gmap, texCoord + indices[5]*step).r;
// normal[6] = texture(gmap, texCoord + indices[6]*step).r;
// normal[7] = texture(gmap, texCoord + indices[7]*step).r;
// normal[8] = texture(gmap, texCoord + indices[8]*step).r;
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;
}
}
float res = 0.0;
for (i = 0; i < 9; ++i) {
res += texture(aomap, texCoord + indices[i]*step).r * weights[i];
}
res /= total_weight;
float 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;
gl_FragColor = vec4(vec3(res), 1.0);
}

View file

@ -0,0 +1,113 @@
#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

@ -27,13 +27,13 @@ os.chdir('../fxaa_pass')
make_resources.make('fxaa_pass.shader.json')
make_variants.make('fxaa_pass.shader.json')
# os.chdir('../ssao_pass')
# make_resources.make('ssao_pass.shader.json')
# make_variants.make('ssao_pass.shader.json')
os.chdir('../ssao_pass')
make_resources.make('ssao_pass.shader.json')
make_variants.make('ssao_pass.shader.json')
# os.chdir('../blur_pass')
# make_resources.make('blur_pass.shader.json')
# make_variants.make('blur_pass.shader.json')
os.chdir('../blur_pass')
make_resources.make('blur_pass.shader.json')
make_variants.make('blur_pass.shader.json')
# os.chdir('../combine_pass')
# make_resources.make('combine_pass.shader.json')

View file

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

View file

@ -11,6 +11,8 @@ uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
uniform sampler2D ssaotex;
uniform sampler2D shadowMap;
uniform sampler2D senvmapRadiance;
uniform sampler2D senvmapIrradiance;
@ -71,15 +73,16 @@ vec3 diffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh, flo
void main() {
vec4 g0 = texture(gbuffer0, texCoord); // Positions, depth
vec4 g0 = texture(gbuffer0, texCoord); // Normals, depth
float depth = g0.a;
if (depth >= 1.0) discard;
vec4 g1 = texture(gbuffer1, texCoord); // Normals, roughness
vec4 g1 = texture(gbuffer1, texCoord); // Positions, roughness
vec4 g2 = texture(gbuffer2, texCoord); // Base color, metalness
float ao = texture(ssaotex, texCoord).r; // Normals, depth
vec3 p = g0.rgb;
vec3 n = g1.rgb;// * 2.0 - 1.0;
vec3 n = g0.rgb * 2.0 - 1.0;
vec3 p = g1.rgb;
//n = normalize(n);
vec3 baseColor = g2.rgb;
@ -124,6 +127,7 @@ void main() {
vec4 outColor = vec4(vec3(direct * visibility + indirect), 1.0);
// outColor.rgb *= occlusion;
outColor.rgb *= ao;
gl_FragColor = vec4(pow(outColor.rgb, vec3(1.0 / 2.2)), outColor.a);
}

View file

@ -1,127 +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
uniform sampler2D gmap;
#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
uniform float u1;
uniform float u2;
uniform float u3;
uniform float u4;
uniform float u5;
uniform float u6;
#define MOD3 vec3(.1031,.11369,.13787)
uniform mat4 invP;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
in vec2 texCoord;
vec3 rand(vec2 coord) {
float noiseX = fract(sin(dot(coord, vec2(12.9898,78.233))) * 43758.5453) * 2.0 - 1.0;
float noiseY = fract(sin(dot(coord, vec2(12.9898,78.233)*2.0)) * 43758.5453) * 2.0 - 1.0;
float noiseZ = fract(sin(dot(coord, vec2(12.9898,78.233)*3.0)) * 43758.5453) * 2.0 - 1.0;
return vec3(noiseX, noiseY, noiseZ) * 0.001;
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 normalFromDepth(float depth, vec2 texcoords) {
const vec2 offset1 = vec2(0.0, 0.001);
const vec2 offset2 = vec2(0.001, 0.0);
float depth1 = texture(gmap, texcoords + offset1).r * 2.0 - 1.0;
float depth2 = texture(gmap, texcoords + offset2).r * 2.0 - 1.0;
vec3 p1 = vec3(offset1, depth1 - depth);
vec3 p2 = vec3(offset2, depth2 - depth);
vec3 normal = cross(p1, p2);
normal.z = -normal.z;
return normalize(normal);
// 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;
}
// vec3 ndc_to_view(vec2 ndc, float depth, vec2 clipPlanes, vec2 tanFov) {
// float z = depth * clipPlanes.x + clipPlanes.y; // go from [0,1] to [zNear, zFar]
// return vec3(ndc * tanFov, -1.0) * z; // view space position
// }
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;
}
// vec2 view_to_ndc(vec3 view, vec2 clipPlanes, vec2 tanFov) {
// return -view.xy / (tanFov*view.z);
// }
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() {
const float zn = 1.0;
const float zf = 100.0;
// float zscale = 0.8;
// float total_strength = 1.0;
// float base = 0.15;
// float area = 0.05 * zscale;
// float falloff = 0.002 * zscale;
// float radius = 0.01 * zscale;
float zscale = u1;
float total_strength = u2;
float base = u3;
float area = u4;
float falloff = u5 * zscale;
float radius = u6 * zscale;
const int samples = 16;
vec3 sample_sphere[samples];
sample_sphere[0] = vec3( 0.5381, 0.1856,-0.4319);
sample_sphere[1] = vec3( 0.1379, 0.2486, 0.4430);
sample_sphere[2] = vec3( 0.3371, 0.5679,-0.0057);
sample_sphere[3] = vec3(-0.6999,-0.0451,-0.0019);
sample_sphere[4] = vec3( 0.0689,-0.1598,-0.8547);
sample_sphere[5] = vec3( 0.0560, 0.0069,-0.1843);
sample_sphere[6] = vec3(-0.0146, 0.1402, 0.0762);
sample_sphere[7] = vec3( 0.0100,-0.1924,-0.0344);
sample_sphere[8] = vec3(-0.3577,-0.5301,-0.4358);
sample_sphere[9] = vec3(-0.3169, 0.1063, 0.0158);
sample_sphere[10] = vec3( 0.0103,-0.5869, 0.0046);
sample_sphere[11] = vec3(-0.0897,-0.4940, 0.3287);
sample_sphere[12] = vec3( 0.7119,-0.0154,-0.0918);
sample_sphere[13] = vec3(-0.0533, 0.0596,-0.5411);
sample_sphere[14] = vec3( 0.0352,-0.0631, 0.5460);
sample_sphere[15] = vec3(-0.4776, 0.2847,-0.0271);
vec3 rvec = normalize(rand(texCoord)) * 0.4;
float depth = texture(gmap, texCoord).r * 2.0 - 1.0;
vec3 normal = normalFromDepth(depth, texCoord);
vec3 position = vec3(texCoord, depth);
float radius_depth = radius / (depth);
float occlusion = 0.0;
for (int i = 0; i < samples; ++i) {
vec3 ray = radius_depth * reflect(sample_sphere[i], rvec);
vec3 hemi_ray = position + sign(dot(ray,normal)) * ray;
float occ_depth = texture(gmap, clamp(hemi_ray.xy, 0.0, 1.0)).r * 2.0 - 1.0;
float difference = depth - occ_depth;
occlusion += step(falloff, difference) * (1.0 - smoothstep(falloff, area, difference));
}
vec4 g0 = texture(gbuffer0, texCoord);
float depth = g0.a;
vec3 n = g0.rgb * 2.0 - 1.0;
vec3 p = getViewPos(texCoord, depth);
float ao = 1.0 - total_strength * occlusion * (1.0 / samples);
float aocol = clamp(ao + base, 0.0, 1.0);
gl_FragColor = vec4(aocol, 0.0, 0.0, 1.0);
// vec2 uTanFovs = vec2(0.83632286848, 0.41398034288);
// float uRadius = 100;
// float uGiBoost = 1.0;
// int uSampleCnt = 16;
// vec2 uClipZ = vec2(0.1, 100.0);
// const float ATTF = 1e-5;
// vec3 p = ndc_to_view(texCoord*2.0-1.0, depth, uClipZ, uTanFovs); // get view pos
// float occ = 0.0;
// float occCnt = 0.0;
// for(int i=0; i<uSampleCnt && depth < 1.0; ++i) {
// vec3 dir = reflect(sample_sphere[i].xyz, rvec); // a la Crysis
// dir -= 2.0*dir*step(dot(normal,dir),0.0); // a la Starcraft
// vec3 sp = p + (dir * uRadius) * (depth * 1e2); // scale radius with depth
// vec2 spNdc = view_to_ndc(sp, uClipZ, uTanFovs); // get sample ndc coords
// float spNd = (texture(gmap, (spNdc*0.5 + 0.5)).r - 0.5) * 2.0;
// vec3 occEye = -sp/sp.z*(spNd*uClipZ.x+uClipZ.y); // compute correct pos
// vec3 occVec = occEye - p; // vector
// float att2 = 1.0+ATTF*length(occVec); // quadratic attenuation
// occ += max(0.0,dot(normalize(occVec),normal)-0.25) / (att2*att2);
// ++occCnt;
// }
// vec3 vocc = occCnt > 0.0 ? vec3(1.0-occ*uGiBoost/occCnt) : vec3(1.0);
// gl_FragColor = vec4(vocc, 1.0);
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.);
}

View file

@ -26,28 +26,8 @@
],
"links": [
{
"id": "u1",
"link": "_u1"
},
{
"id": "u2",
"link": "_u2"
},
{
"id": "u3",
"link": "_u3"
},
{
"id": "u4",
"link": "_u4"
},
{
"id": "u5",
"link": "_u5"
},
{
"id": "u6",
"link": "_u6"
"id": "invP",
"link": "_inverseProjectionMatrix"
}
],
"texture_params": [],