diff options
author | Julian Eisel <julian@blender.org> | 2020-03-12 17:58:03 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-03-12 17:58:03 +0300 |
commit | b86be9b2145458037fd0b17433b7af0efa7b6472 (patch) | |
tree | f333625555402992ebb35d258f93eda1130389e6 /source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl | |
parent | 00f83ec125207e90bf180b3eb7752d8cb6482a86 (diff) | |
parent | cb6cec904fa14ce0ab10a2a53af5c936d56376cf (diff) |
Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl')
-rw-r--r-- | source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl index 376b19cdd1b..87d04144cde 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl @@ -1,77 +1,87 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_data_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_common_lib.glsl) -/* from The Alchemy screen-space ambient obscurance algorithm +layout(std140) uniform samples_block +{ + vec4 samples_coords[512]; +}; + +uniform sampler2D cavityJitter; + +/* From The Alchemy screen-space ambient obscurance algorithm * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */ -void ssao_factors(in float depth, - in vec3 normal, - in vec3 position, - in vec2 screenco, - out float cavities, - out float edges) +void cavity_compute(vec2 screenco, + sampler2D depthBuffer, + sampler2D normalBuffer, + out float cavities, + out float edges) { cavities = edges = 0.0; - /* early out if there is no need for SSAO */ - if (ssao_factor_cavity == 0.0 && ssao_factor_edge == 0.0) { + + float depth = texture(depthBuffer, screenco).x; + + /* Early out if background and infront. */ + if (depth == 1.0 || depth == 0.0) { return; } - /* take the normalized ray direction here */ - vec3 noise = texture(ssao_jitter, screenco.xy * jitter_tilling).rgb; + vec3 position = view_position_from_depth(screenco, depth, world_data.viewvecs, ProjectionMatrix); + vec3 normal = workbench_normal_decode(texture(normalBuffer, screenco)); + + vec2 jitter_co = (screenco * world_data.viewport_size.xy) * world_data.cavity_jitter_scale; + vec3 noise = texture(cavityJitter, jitter_co).rgb; /* find the offset in screen space by multiplying a point * in camera space at the depth of the point by the projection matrix. */ vec2 offset; - float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3]; - offset.x = WinMatrix[0][0] * ssao_distance / homcoord; - offset.y = WinMatrix[1][1] * ssao_distance / homcoord; + float homcoord = ProjectionMatrix[2][3] * position.z + ProjectionMatrix[3][3]; + offset.x = ProjectionMatrix[0][0] * world_data.cavity_distance / homcoord; + offset.y = ProjectionMatrix[1][1] * world_data.cavity_distance / homcoord; /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */ offset *= 0.5; - int num_samples = int(ssao_samples_num); - /* Note. Putting noise usage here to put some ALU after texture fetch. */ vec2 rotX = noise.rg; vec2 rotY = vec2(-rotX.y, rotX.x); - for (int x = 0; x < num_samples; x++) { - int sample_index = x + (int(ssao_iteration) * num_samples); - if (sample_index > 500) { - continue; - } - /* ssao_samples[x].xy is sample direction (normalized). - * ssao_samples[x].z is sample distance from disk center. */ - + int sample_start = world_data.cavity_sample_start; + int sample_end = world_data.cavity_sample_end; + for (int i = sample_start; i < sample_end && i < 512; i++) { + /* sample_coord.xy is sample direction (normalized). + * sample_coord.z is sample distance from disk center. */ + vec3 sample_coord = samples_coords[i].xyz; /* Rotate with random direction to get jittered result. */ - vec2 dir_jittered = vec2(dot(ssao_samples[sample_index].xy, rotX), - dot(ssao_samples[sample_index].xy, rotY)); - dir_jittered.xy *= ssao_samples[sample_index].z + noise.b; + vec2 dir_jittered = vec2(dot(sample_coord.xy, rotX), dot(sample_coord.xy, rotY)); + dir_jittered.xy *= sample_coord.z + noise.b; - vec2 uvcoords = screenco.xy + dir_jittered * offset; - - if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0) { + vec2 uvcoords = screenco + dir_jittered * offset; + /* Out of screen case. */ + if (any(greaterThan(abs(uvcoords - 0.5), vec2(0.5)))) { continue; } - - float depth_new = texture(depthBuffer, uvcoords).r; - + /* Sample depth. */ + float s_depth = texture(depthBuffer, uvcoords).r; /* Handle Background case */ - bool is_background = (depth_new == 1.0); - + bool is_background = (s_depth == 1.0); /* This trick provide good edge effect even if no neighbor is found. */ - vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new); + s_depth = (is_background) ? depth : s_depth; + vec3 s_pos = view_position_from_depth( + uvcoords, s_depth, world_data.viewvecs, ProjectionMatrix); if (is_background) { - pos_new.z -= ssao_distance; + s_pos.z -= world_data.cavity_distance; } - vec3 dir = pos_new - position; + vec3 dir = s_pos - position; float len = length(dir); float f_cavities = dot(dir, normal); float f_edge = -f_cavities; float f_bias = 0.05 * len + 0.0001; - float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation)); + float attenuation = 1.0 / (len * (1.0 + len * len * world_data.cavity_attenuation)); /* use minor bias here to avoid self shadowing */ if (f_cavities > -f_bias) { @@ -82,11 +92,10 @@ void ssao_factors(in float depth, edges += f_edge * attenuation; } } - - cavities /= ssao_samples_num; - edges /= ssao_samples_num; + cavities *= world_data.cavity_sample_count_inv; + edges *= world_data.cavity_sample_count_inv; /* don't let cavity wash out the surface appearance */ - cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0); - edges = edges * ssao_factor_edge; + cavities = clamp(cavities * world_data.cavity_valley_factor, 0.0, 1.0); + edges = edges * world_data.cavity_ridge_factor; } |