diff options
3 files changed, 34 insertions, 6 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 0b494aa019f..c56e02e72d6 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,38 @@ void fresnel(vec3 I, vec3 N, float ior, out float kr) // kt = 1 - kr; } -float calculate_transparent_weight(float alpha) { - /* Eq 10 */ - float a = min(1.0, alpha) * 8.0 + 0.01; +float calculate_transparent_weight(float z, float alpha) +{ +#if 0 + /* Eq 10 : Good for surfaces with varying opacity (like particles) */ + float a = min(1.0, alpha * 10.0) + 0.01; float b = -gl_FragCoord.z * 0.95 + 1.0; - return alpha * clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e3); + float w = a * a * a * 3e2 * b * b * b; +#else + /* Eq 7 put more emphasis on surfaces closer to the view. */ + // float w = 10.0 / (1e-5 + pow(abs(z) / 5.0, 2.0) + pow(abs(z) / 200.0, 6.0)); /* Eq 7 */ + // float w = 10.0 / (1e-5 + pow(abs(z) / 10.0, 3.0) + pow(abs(z) / 200.0, 6.0)); /* Eq 8 */ + // float w = 10.0 / (1e-5 + pow(abs(z) / 200.0, 4.0)); /* Eq 9 */ + /* Same as eq 7, but optimized. */ + float a = abs(z) / 5.0; + float b = abs(z) / 200.0; + b *= b; + float w = 10.0 / ((1e-5 + a * a) + b * (b * b)); /* Eq 7 */ +#endif + return alpha * clamp(w, 1e-2, 3e2); +} + +/* Special function only to be used with calculate_transparent_weight(). */ +float linear_zdepth(float depth, vec4 viewvecs[3], mat4 proj_mat) +{ + if (proj_mat[3][3] == 0.0) { + float d = 2.0 * depth - 1.0; + return -proj_mat[3][2] / (d + proj_mat[2][2]); + } + else { + /* Return depth from near plane. */ + return depth * viewvecs[1].z; + } } 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_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index 53903a4af76..4a7d195a56a 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 @@ -75,7 +75,8 @@ void main() * Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013 */ /* Listing 4 */ - float weight = calculate_transparent_weight(alpha); + float z = linear_zdepth(gl_FragCoord.z, viewvecs, ProjectionMatrix); + float weight = calculate_transparent_weight(z, alpha); transparentAccum = vec4(shaded_color * weight, alpha); revealageAccum = weight; } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index fb949cd02c9..4e97fc730a3 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -172,6 +172,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data( psl->transparent_accum_pass); DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_float(grp, "alpha", &wpd->shading.xray_alpha, 1); + DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3); workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix); material->object_id = engine_object_data->object_id; copy_v4_v4(material->material_data.diffuse_color, material_template.material_data.diffuse_color); @@ -185,7 +186,6 @@ static WORKBENCH_MaterialData *get_or_create_material_data( DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirectangular_radiance_gputexture); } if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) { - DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); } break; |