forked from JuliaPlots/GLMakie.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request JuliaPlots#97 from ffreyer/SSAO
SSAO
- Loading branch information
Showing
17 changed files
with
367 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
{{GLSL_VERSION}} | ||
|
||
// SSAO | ||
uniform sampler2D position_buffer; | ||
uniform sampler2D normal_buffer; | ||
uniform sampler2D noise; | ||
uniform vec3 kernel[{{N_samples}}]; | ||
uniform vec2 noise_scale; | ||
uniform mat4 projection; | ||
|
||
// bias/epsilon for depth check | ||
uniform float bias; | ||
// max range for depth check | ||
uniform float radius; | ||
|
||
|
||
in vec2 frag_uv; | ||
out float o_occlusion; | ||
|
||
|
||
void main(void) | ||
{ | ||
vec3 view_pos = texture(position_buffer, frag_uv).xyz; | ||
vec3 normal = texture(normal_buffer, frag_uv).xyz; | ||
|
||
// The normal buffer gets cleared every frame. (also position, color etc) | ||
// If normal == vec3(1) then there is no geometry at this fragment. | ||
// Therefore skip SSAO calculation | ||
if (normal != vec3(1)) { | ||
vec3 rand_vec = vec3(texture(noise, frag_uv * noise_scale).xy, 0.0); | ||
vec3 tangent = normalize(rand_vec - normal * dot(rand_vec, normal)); | ||
vec3 bitangent = cross(normal, tangent); | ||
mat3 TBN = mat3(tangent, bitangent, normal); | ||
|
||
float occlusion = 0.0; | ||
for (int i = 0; i < {{N_samples}}; ++i) { | ||
// random offset in view space | ||
vec3 sample_view_offset = TBN * kernel[i] * radius; | ||
|
||
/* | ||
We want to get the uv (screen) coordinate of position + offset in | ||
view space. Usually this would be: | ||
clip_coordinate = projection * view_coordinate | ||
clip_coordinate /= clip_coordinate.w | ||
screen_coordinate = 0.5 * clip_coordinate + 0.5 | ||
But Makie allows multiple scenes, which each have their own | ||
coordinate system. This means it is possible that multiple | ||
regions of the screen (different scenes) refer to the same view | ||
position. To differentiate between them we must calculate the | ||
screen space coordinate using frag_uv and an offset derived from | ||
the view space offset. | ||
Instead of | ||
clip_coord = projection * (view_pos + view_offset) | ||
clip_coord /= clip_coord.w | ||
screen_coordinate = 0.5 * clip_coord + 0.5 | ||
we essentially calculate | ||
clip_offset = projection * view_offset | ||
clip_offset /= (projection * (view_pos + view_offset)).w | ||
clip_position = frag_uv - 0.5 | ||
clip_position *= (projection * view_pos).w | ||
clip_position /= (projection * (view_pos + view_offset)).w | ||
screen_coordinate = clip_position + 0.5 * clip_offset+ 0.5 | ||
*/ | ||
|
||
vec4 sample_frag_pos = vec4( | ||
(projection * vec4(sample_view_offset, 1.0)).xyz, | ||
(projection * vec4(view_pos + sample_view_offset, 1.0)).w | ||
); | ||
float sample_clip_pos_w = sample_frag_pos.w; | ||
float clip_pos_w = (projection * vec4(view_pos, 1.0)).w; | ||
sample_frag_pos.xyz /= sample_frag_pos.w; | ||
sample_frag_pos.xyz = sample_frag_pos.xyz * 0.5 + 0.5; | ||
sample_frag_pos.xy += (frag_uv - 0.5) * clip_pos_w / sample_clip_pos_w; | ||
|
||
|
||
float sample_depth = texture(position_buffer, sample_frag_pos.xy).z; | ||
float range_check = smoothstep(0.0, 1.0, radius / abs(view_pos.z - sample_depth)); | ||
occlusion += (sample_depth >= sample_view_offset.z + view_pos.z + bias ? 1.0 : 0.0) * range_check; | ||
} | ||
occlusion = 1.0 - (occlusion / {{N_samples}}); | ||
o_occlusion = occlusion; | ||
} else { | ||
o_occlusion = 1.0; | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
src/GLVisualize/assets/shader/postprocessing/SSAO_blur.frag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{{GLSL_VERSION}} | ||
|
||
uniform sampler2D occlusion; | ||
uniform sampler2D color_texture; | ||
uniform usampler2D ids; | ||
uniform vec2 inv_texel_size; | ||
// Settings/Attributes | ||
uniform int blur_range; | ||
|
||
in vec2 frag_uv; | ||
out vec4 fragment_color; | ||
|
||
void main(void) | ||
{ | ||
// occlusion blur | ||
float blurred_occlusion = 0.0; | ||
uvec2 id0 = texture(ids, frag_uv).xy; | ||
float weight = 0; | ||
|
||
for (int x = -blur_range; x <= blur_range; ++x){ | ||
for (int y = -blur_range; y <= blur_range; ++y){ | ||
vec2 offset = vec2(float(x), float(y)) * inv_texel_size; | ||
// The id check makes it so that the blur acts per object. | ||
// Without this, a high (low) occlusion from one object can bleed | ||
// into the low (high) occlusion of another, giving an unwanted | ||
// shine effect. | ||
uvec2 id = texture(ids, frag_uv + offset).xy; | ||
if (id0 == id) { | ||
blurred_occlusion += texture(occlusion, frag_uv + offset).r; | ||
weight += 1; | ||
} | ||
} | ||
} | ||
blurred_occlusion = blurred_occlusion / weight; | ||
fragment_color = texture(color_texture, frag_uv) * blurred_occlusion; | ||
// Display occlusion instead: | ||
// fragment_color = vec4(vec3(blurred_occlusion), 1.0); | ||
} |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.