diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-06-10 16:30:49 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-06-10 21:06:26 +0300 |
commit | 95894421cb4e9ccabb4cff393b561625b9bc4280 (patch) | |
tree | db343a83b911d7fe2ca2f1d4d7c9814598e19530 /source/blender/draw/engines/workbench/shaders | |
parent | b23d5132a90a0e8360a20199c8e7bb45174987c4 (diff) |
Workbench: Xray: Optimize and fix implementation.
There was a method explained in the Weighted Blended Order-Independent
Transparency paper to support hardware that does not support per render
target blending function.
So now only 2 geometry passes are required instead of 3 (one being the
outline/depth fill pass).
This also fix how the blending is done. There was some premult confusion
in the implementation.
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders')
4 files changed, 27 insertions, 35 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index 8908891d7e6..0b494aa019f 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -65,11 +65,11 @@ void fresnel(vec3 I, vec3 N, float ior, out float kr) // kt = 1 - kr; } -vec4 calculate_transparent_accum(vec4 premultiplied) { - float a = min(1.0, premultiplied.a) * 8.0 + 0.01; +float calculate_transparent_weight(float alpha) { + /* Eq 10 */ + float a = min(1.0, alpha) * 8.0 + 0.01; float b = -gl_FragCoord.z * 0.95 + 1.0; - float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2); - return premultiplied * w; + return alpha * clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e3); } vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl index f335e1a15bd..1d9f37274bd 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl @@ -2,9 +2,7 @@ out vec4 fragColor; uniform usampler2D objectId; uniform sampler2D transparentAccum; -#ifdef WORKBENCH_REVEALAGE_ENABLED uniform sampler2D transparentRevealage; -#endif uniform vec2 invertedViewportSize; layout(std140) uniform world_block { @@ -16,29 +14,24 @@ void main() ivec2 texel = ivec2(gl_FragCoord.xy); vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; uint object_id = texelFetch(objectId, texel, 0).r; - vec4 transparent_accum = texelFetch(transparentAccum, texel, 0); -#ifdef WORKBENCH_REVEALAGE_ENABLED - float transparent_revealage = texelFetch(transparentRevealage, texel, 0).r; -#endif - vec4 color; - vec4 bg_color; + + /* Listing 4 */ + vec4 trans_accum = texelFetch(transparentAccum, texel, 0); + float trans_revealage = trans_accum.a; + trans_accum.a = texelFetch(transparentRevealage, texel, 0).r; #ifdef V3D_SHADING_OBJECT_OUTLINE float outline = calculate_object_outline(objectId, texel, object_id); #else /* V3D_SHADING_OBJECT_OUTLINE */ float outline = 1.0; #endif /* V3D_SHADING_OBJECT_OUTLINE */ - bg_color = vec4(background_color(world_data, uv_viewport.y), 0.0); - if (object_id == NO_OBJECT_ID) { - color = bg_color; - } else { -#ifdef WORKBENCH_REVEALAGE_ENABLED - color = vec4((transparent_accum.xyz / max(transparent_accum.a, EPSILON)) * (1.0 - transparent_revealage), 1.0); - color = mix(bg_color, color, clamp(1.0 - transparent_revealage, 0.0, 1.0)); -#else - color = vec4(transparent_accum.xyz / max(transparent_accum.a, EPSILON), 1.0); -#endif - } - - fragColor = vec4(mix(world_data.object_outline_color.rgb, color.xyz, outline), 1.0); + vec3 bg_color = background_color(world_data, uv_viewport.y); + + /* TODO: Bypass the whole shader if there is no xray pass and no outline pass. */ + vec3 trans_color = trans_accum.rgb / clamp(trans_accum.a, 1e-4, 5e4); + vec3 color = mix(trans_color, bg_color, trans_revealage); + + color = mix(world_data.object_outline_color.rgb, color, outline); + + fragColor = vec4(color, 1.0); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index f1eacd281b1..53903a4af76 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -26,7 +26,7 @@ layout(std140) uniform material_block { }; layout(location=0) out vec4 transparentAccum; - +layout(location=1) out float revealageAccum; /* revealage actually stored in transparentAccum.a */ void main() { @@ -70,7 +70,13 @@ void main() vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color; - vec4 premultiplied = vec4(shaded_color.rgb * alpha, alpha); - transparentAccum = calculate_transparent_accum(premultiplied); + /* Based on : + * McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of + * Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013 + */ + /* Listing 4 */ + float weight = calculate_transparent_weight(alpha); + transparentAccum = vec4(shaded_color * weight, alpha); + revealageAccum = weight; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl deleted file mode 100644 index c591425b950..00000000000 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl +++ /dev/null @@ -1,7 +0,0 @@ -layout(location=0) out float transparentRevealage; -uniform float alpha = 0.5; -void main() -{ - transparentRevealage = alpha; -} - |