Workbench: Xray: Make nearest surfaces more clear

By using equation 7 from the paper, we make the surfaces nearest to the
viewpoint appear more "opaque". This gives better sense of ordering than
the previous weighting function that was really not doing anything.
This commit is contained in:
Clément Foucault 2018-06-10 17:31:28 +02:00
parent 15862e1990
commit e321fc4a7c
3 changed files with 34 additions and 6 deletions

View File

@ -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)

View File

@ -75,7 +75,8 @@ void main()
* Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122141, 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;
}

View File

@ -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;