so tried implement ssao, not working intended. seems split @ position z=0 (worldspace), there white line @ position z=0. occlusion there doesn't right.
plus @ greater distance, when moving camera, occlusion becomes weirder
my shader render geometry (instanciated):
vertex:
#version 330 core layout(location = 0) in vec3 vertexposition; layout(location = 1) in vec2 vertexuv; layout(location = 2) in vec3 vertexcolor; layout(location = 3) in vec3 vertexnormal; layout(location = 4) in mat4 offset; layout(location = 8) in vec4 instancecolor; uniform mat4 projection; uniform mat4 view; out vec2 uv; out vec4 color; out vec3 normal; void main() { mat4 model = offset; mat4 mvp = projection * view * model; vec4 pos = mvp * vec4(endpos,1); gl_position = pos; uv = vertexuv; color = instancecolor; normal = normalize((model * vec4(vertexnormal,0)).xyz); }
fragment:
#version 330 core in vec2 uv; in vec4 color; in vec3 normal; uniform sampler2d diffuse; void main() { gl_fragdata[0] = vec4(color); gl_fragdata[1] = (vec4(normal,1)+1)/2; }
after geometry pass, apply ssao pass normal , depth information.
this noisetexture:
i use hardware depth buffer. calculate in world space.
here fragment shader:
#version 330 core #define kernel_size 16 uniform sampler2d normalmap; uniform sampler2d depthmap; uniform sampler2d noisetexture; uniform vec2 noisescale; uniform vec2 resolution; uniform mat4 invertviewprojection; uniform float g_sample_rad = 0.1; uniform float g_intensity = 2.0; uniform float g_scale = 0.1; uniform float g_bias = 0.0; vec2 calctexcoord() { return gl_fragcoord.xy / resolution; } vec3 getposition(vec2 uv) { vec4 worldpos; float depth = texture2d(depthmap, uv).r; worldpos.x = uv.x * 2.0f - 1.0f; worldpos.y = uv.y * 2.0f - 1.0f; worldpos.z = depth * 2.0f - 1.0f; worldpos.w = 1.0; worldpos = invertviewprojection * worldpos; worldpos /= worldpos.w; return worldpos.rgb; } vec3 getnormal(vec2 uv) { return normalize(texture2d(normalmap, uv).xyz * 2.0f - 1.0f); } vec2 getrandom(vec2 uv) { return normalize(texture2d(noisetexture, resolution*uv / noisescale).xy * 2.0f - 1.0f); } float doambientocclusion(in vec2 tcoord, in vec2 uv, in vec3 p, in vec3 cnorm) { vec3 diff = getposition(tcoord + uv) - p; vec3 v = normalize(diff); float d = length(diff)*g_scale; return max(0.0, dot(cnorm, v) - g_bias)*(1.0 / (1.0 + d))*g_intensity; } void main() { vec4 kernels[kernel_size] = vec4[]( vec4(0.355512, -0.709318, -0.102371, 0.0 ), vec4(0.534186, 0.71511, -0.115167, 0.0 ), vec4(-0.87866, 0.157139, -0.115167, 0.0 ), vec4(0.140679, -0.475516, -0.0639818, 0.0 ), vec4(-0.0796121, 0.158842, -0.677075, 0.0 ), vec4(-0.0759516, -0.101676, -0.483625, 0.0 ), vec4(0.12493, -0.0223423, -0.483625, 0.0 ), vec4(-0.0720074, 0.243395, -0.967251, 0.0 ), vec4(-0.207641, 0.414286, 0.187755, 0.0 ), vec4(-0.277332, -0.371262, 0.187755, 0.0 ), vec4(0.63864, -0.114214, 0.262857, 0.0 ), vec4(-0.184051, 0.622119, 0.262857, 0.0 ), vec4(0.110007, -0.219486, 0.435574, 0.0 ), vec4(0.235085, 0.314707, 0.696918, 0.0 ), vec4(-0.290012, 0.0518654, 0.522688, 0.0 ), vec4(0.0975089, -0.329594, 0.609803, 0.0 ) ); vec2 uv = calctexcoord(); //same uv coordinate vertex vec3 p = getposition(uv); vec3 n = getnormal(uv); vec2 rand = getrandom(uv); float ao = 0.0f; float rad = g_sample_rad / p.z; (int j = 0; j < kernel_size; ++j) { vec2 coord = reflect(kernels[j].xy, rand)*rad; ao += doambientocclusion(uv, coord, p, n); } ao /= kernel_size; ao = 1 - (ao); gl_fragcolor = vec4(ao,ao,ao, 1); }
i figured out debugging code step step.
i calculate in world space. it's easier handle there. looked @ tutorial uses view space , changed needed world space.
the error here:
float rad = g_sample_rad / p.z;
this calculates sampling radius based on distance. in view space, calculates sampling radius distance camera. in world space, calculates distance world coordinate, resulted in looking weird @ z=0 , weirder @ farther away.
so did fix simple this:
vec4 viewpos = camview * vec4(p,1); float ao = 0.0f; float rad = g_sample_rad/viewpos.z;
i changed point view space , calculated sampling radius in view space, taking in account distance camera.
this fixes it.
i played little bit g_values fit them needs. see how looks everywhere same. that's should like.
Comments
Post a Comment