Overlay: Edit Mesh: Add anti-alising on normal lines #119146
@ -787,6 +787,9 @@ set(GLSL_SRC
|
||||
engines/overlay/shaders/overlay_edit_mesh_frag.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_geom.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_normal_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_normal_vert_no_geom.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_normal_geom.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_normal_frag.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
|
||||
|
@ -112,7 +112,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
/* Normals */
|
||||
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
(pd->edit_mesh.do_zbufclip ? DRW_STATE_BLEND_ALPHA : DRWState(0));
|
||||
DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->edit_mesh_normals_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_edit_mesh_normal();
|
||||
|
@ -8,6 +8,10 @@ GPU_SHADER_INTERFACE_INFO(overlay_edit_flat_color_iface, "").flat(Type::VEC4, "f
|
||||
GPU_SHADER_INTERFACE_INFO(overlay_edit_smooth_color_iface, "").smooth(Type::VEC4, "finalColor");
|
||||
GPU_SHADER_INTERFACE_INFO(overlay_edit_nopersp_color_iface, "")
|
||||
.no_perspective(Type::VEC4, "finalColor");
|
||||
GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_normale_iface, "interp")
|
||||
.smooth(Type::VEC4, "final_color");
|
||||
GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_normal_noperspective_iface, "interp_noperspective")
|
||||
.no_perspective(Type::FLOAT, "smoothline");
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Edit Mesh
|
||||
@ -150,6 +154,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_facedot)
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_normal)
|
||||
.do_static_compilation(true)
|
||||
.define("LINE_WIDTH", "1")
|
||||
.define("SMOOTH_WIDTH", "1")
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_in(1, Type::VEC4, "lnor")
|
||||
.vertex_in(2, Type::VEC4, "vnor")
|
||||
@ -159,12 +165,38 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_normal)
|
||||
.push_constant(Type::FLOAT, "normalScreenSize")
|
||||
.push_constant(Type::FLOAT, "alpha")
|
||||
.push_constant(Type::BOOL, "isConstantScreenSizeNormals")
|
||||
.vertex_out(overlay_edit_flat_color_iface)
|
||||
.vertex_out(overlay_edit_mesh_normale_iface)
|
||||
.geometry_layout(PrimitiveIn::LINES, PrimitiveOut::TRIANGLE_STRIP, 4)
|
||||
.geometry_out(overlay_edit_mesh_normale_iface)
|
||||
.geometry_out(overlay_edit_mesh_normal_noperspective_iface)
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.vertex_source("overlay_edit_mesh_normal_vert.glsl")
|
||||
.fragment_source("overlay_varying_color.glsl")
|
||||
.geometry_source("overlay_edit_mesh_normal_geom.glsl")
|
||||
.fragment_source("overlay_edit_mesh_normal_frag.glsl")
|
||||
.additional_info("draw_modelmat_instanced_attr", "draw_globals");
|
||||
|
||||
#ifdef WITH_METAL_BACKEND
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_normal_no_geom)
|
||||
.do_static_compilation(true)
|
||||
.define("LINE_WIDTH", "1")
|
||||
.define("SMOOTH_WIDTH", "1")
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_in(1, Type::VEC4, "lnor")
|
||||
.vertex_in(2, Type::VEC4, "vnor")
|
||||
.vertex_in(3, Type::VEC4, "norAndFlag")
|
||||
.sampler(0, ImageType::DEPTH_2D, "depthTex")
|
||||
.push_constant(Type::FLOAT, "normalSize")
|
||||
.push_constant(Type::FLOAT, "normalScreenSize")
|
||||
.push_constant(Type::FLOAT, "alpha")
|
||||
.push_constant(Type::BOOL, "isConstantScreenSizeNormals")
|
||||
.vertex_out(overlay_edit_mesh_normale_iface)
|
||||
.vertex_out(overlay_edit_mesh_normal_noperspective_iface)
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.vertex_source("overlay_edit_mesh_normal_vert_no_geom.glsl")
|
||||
.fragment_source("overlay_edit_mesh_normal_frag.glsl")
|
||||
.additional_info("draw_modelmat_instanced_attr", "draw_globals");
|
||||
#endif
|
||||
|
||||
GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_analysis_iface, "").smooth(Type::VEC4, "weightColor");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_analysis)
|
||||
|
@ -0,0 +1,10 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = interp.final_color;
|
||||
fragColor.a *= clamp(
|
||||
(LINE_WIDTH + SMOOTH_WIDTH) * 0.5 - abs(interp_noperspective.smoothline), 0.0, 1.0);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/* SPDX-FileCopyrightText: 2020-2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* Almost a copy of blender/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl */
|
||||
|
||||
/* Clips point to near clip plane before perspective divide. */
|
||||
vec4 clip_line_point_homogeneous_space(vec4 p, vec4 q)
|
||||
{
|
||||
if (p.z < -p.w) {
|
||||
/* Just solves p + (q - p) * A; for A when p.z / p.w = -1.0. */
|
||||
float denom = q.z - p.z + q.w - p.w;
|
||||
if (denom == 0.0) {
|
||||
/* No solution. */
|
||||
return p;
|
||||
}
|
||||
float A = (-p.z - p.w) / denom;
|
||||
p = p + (q - p) * A;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void do_vertex(const int i, vec4 pos, vec2 ofs)
|
||||
{
|
||||
interp_out.final_color = interp_in[1].final_color;
|
||||
|
||||
interp_noperspective.smoothline = (LINE_WIDTH + SMOOTH_WIDTH) * 0.5;
|
||||
gl_Position = pos;
|
||||
gl_Position.xy += ofs * pos.w;
|
||||
gpu_EmitVertex();
|
||||
|
||||
interp_noperspective.smoothline = -(LINE_WIDTH + SMOOTH_WIDTH) * 0.5;
|
||||
gl_Position = pos;
|
||||
gl_Position.xy -= ofs * pos.w;
|
||||
gpu_EmitVertex();
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 p0 = clip_line_point_homogeneous_space(gl_in[0].gl_Position, gl_in[1].gl_Position);
|
||||
vec4 p1 = clip_line_point_homogeneous_space(gl_in[1].gl_Position, gl_in[0].gl_Position);
|
||||
vec2 e = normalize(((p1.xy / p1.w) - (p0.xy / p0.w)) * sizeViewport.xy);
|
||||
|
||||
#if 0 /* Hard turn when line direction changes quadrant. */
|
||||
e = abs(e);
|
||||
vec2 ofs = (e.x > e.y) ? vec2(0.0, 1.0 / e.x) : vec2(1.0 / e.y, 0.0);
|
||||
#else /* Use perpendicular direction. */
|
||||
vec2 ofs = vec2(-e.y, e.x);
|
||||
#endif
|
||||
ofs /= sizeViewport.xy;
|
||||
ofs *= LINE_WIDTH + SMOOTH_WIDTH;
|
||||
|
||||
do_vertex(0, p0, ofs);
|
||||
do_vertex(1, p1, ofs);
|
||||
|
||||
EndPrimitive();
|
||||
}
|
@ -16,7 +16,7 @@ void main()
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
/* Avoid undefined behavior after return. */
|
||||
finalColor = vec4(0.0);
|
||||
interp.final_color = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
|
||||
vec3 nor;
|
||||
@ -26,21 +26,21 @@ void main()
|
||||
return;
|
||||
}
|
||||
nor = lnor.xyz;
|
||||
finalColor = colorLNormal;
|
||||
interp.final_color = colorLNormal;
|
||||
}
|
||||
else if (!all(equal(vnor.xyz, vec3(0)))) {
|
||||
if (vnor.w < 0.0) {
|
||||
return;
|
||||
}
|
||||
nor = vnor.xyz;
|
||||
finalColor = colorVNormal;
|
||||
interp.final_color = colorVNormal;
|
||||
}
|
||||
else {
|
||||
nor = norAndFlag.xyz;
|
||||
if (all(equal(nor, vec3(0)))) {
|
||||
return;
|
||||
}
|
||||
finalColor = colorNormal;
|
||||
interp.final_color = colorNormal;
|
||||
}
|
||||
|
||||
vec3 n = normalize(normal_object_to_world(nor));
|
||||
@ -66,7 +66,7 @@ void main()
|
||||
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
finalColor.a *= (test_occlusion()) ? alpha : 1.0;
|
||||
interp.final_color.a *= (test_occlusion()) ? alpha : 1.0;
|
||||
|
||||
view_clipping_distances(world_pos);
|
||||
}
|
||||
|
@ -0,0 +1,191 @@
|
||||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
|
||||
#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
/* "geometry" shader area */
|
||||
|
||||
/* Clips point to near clip plane before perspective divide. */
|
||||
vec4 clip_line_point_homogeneous_space(vec4 p, vec4 q)
|
||||
{
|
||||
if (p.z < -p.w) {
|
||||
/* Just solves p + (q - p) * A; for A when p.z / p.w = -1.0. */
|
||||
float denom = q.z - p.z + q.w - p.w;
|
||||
if (denom == 0.0) {
|
||||
/* No solution. */
|
||||
return p;
|
||||
}
|
||||
float A = (-p.z - p.w) / denom;
|
||||
p = p + (q - p) * A;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void do_vertex(uint index, vec4 pos, vec2 ofs, float flip)
|
||||
{
|
||||
interp_noperspective.smoothline = flip * (LINE_WIDTH + SMOOTH_WIDTH) * 0.5;
|
||||
gl_Position = pos;
|
||||
gl_Position.xy += flip * ofs * pos.w;
|
||||
}
|
||||
|
||||
/* "veretex" shader area */
|
||||
|
||||
bool test_occlusion()
|
||||
{
|
||||
vec3 ndc = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5;
|
||||
return (ndc.z - 0.00035) > texture(depthTex, ndc.xy).r;
|
||||
}
|
||||
|
||||
vec4 vertex_main(uint src_index, vec3 in_pos, vec4 in_lnor, vec4 in_vnor, vec4 in_norAndFlag)
|
||||
{
|
||||
/* Avoid undefined behavior after return. */
|
||||
interp.final_color = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
|
||||
vec3 nor;
|
||||
/* Select the right normal by checking if the generic attribute is used. */
|
||||
if (!all(equal(in_lnor.xyz, vec3(0)))) {
|
||||
if (in_lnor.w < 0.0) {
|
||||
return vec4(0, 0, 0, 0);
|
||||
}
|
||||
nor = in_lnor.xyz;
|
||||
interp.final_color = colorLNormal;
|
||||
}
|
||||
else if (!all(equal(in_vnor.xyz, vec3(0)))) {
|
||||
if (in_vnor.w < 0.0) {
|
||||
return vec4(0, 0, 0, 0);
|
||||
}
|
||||
nor = in_vnor.xyz;
|
||||
interp.final_color = colorVNormal;
|
||||
}
|
||||
else {
|
||||
nor = in_norAndFlag.xyz;
|
||||
if (all(equal(nor, vec3(0)))) {
|
||||
return vec4(0, 0, 0, 0);
|
||||
}
|
||||
interp.final_color = colorNormal;
|
||||
}
|
||||
|
||||
vec3 n = normalize(normal_object_to_world(nor));
|
||||
vec3 world_pos = point_object_to_world(in_pos);
|
||||
|
||||
if (src_index == 0) {
|
||||
if (isConstantScreenSizeNormals) {
|
||||
bool is_persp = (drw_view.winmat[3][3] == 0.0);
|
||||
if (is_persp) {
|
||||
float dist_fac = length(cameraPos - world_pos);
|
||||
float cos_fac = dot(cameraForward, cameraVec(world_pos));
|
||||
world_pos += n * normalScreenSize * dist_fac * cos_fac * pixelFac * sizePixel;
|
||||
}
|
||||
else {
|
||||
float frustrum_fac = mul_project_m4_v3_zfac(n) * sizePixel;
|
||||
world_pos += n * normalScreenSize * frustrum_fac;
|
||||
}
|
||||
}
|
||||
else {
|
||||
world_pos += n * normalSize;
|
||||
}
|
||||
}
|
||||
|
||||
interp.final_color.a *= (test_occlusion()) ? alpha : 1.0;
|
||||
view_clipping_distances(world_pos);
|
||||
|
||||
return point_world_to_ndc(world_pos);
|
||||
}
|
||||
|
||||
/* Real main */
|
||||
|
||||
#ifndef INT16_MAX
|
||||
# define INT16_MAX 32767
|
||||
#endif
|
||||
|
||||
typedef struct GPUPackedNormal {
|
||||
int x : 10;
|
||||
int y : 10;
|
||||
int z : 10;
|
||||
int w : 2;
|
||||
} GPUPackedNormal;
|
||||
|
||||
#define nor_to_vec4(index, in_data, out_vec) \
|
||||
{ \
|
||||
if (vertex_fetch_get_attr_type(in_data) == GPU_SHADER_ATTR_TYPE_SHORT) { \
|
||||
out_vec = (vec4)vertex_fetch_attribute(index, in_data, short4) / vec4(INT16_MAX); \
|
||||
} \
|
||||
else if (vertex_fetch_get_attr_type(in_data) == GPU_SHADER_ATTR_TYPE_INT1010102_NORM) { \
|
||||
GPUPackedNormal data = *(constant GPUPackedNormal *)(&vertex_fetch_attribute( \
|
||||
index, in_data, vec3_1010102_Inorm)); \
|
||||
out_vec.x = float(data.x) / 511.0; \
|
||||
out_vec.y = float(data.y) / 511.0; \
|
||||
out_vec.z = float(data.z) / 511.0; \
|
||||
out_vec.w = float(data.w); \
|
||||
} \
|
||||
else { \
|
||||
out_vec = vertex_fetch_attribute(index, in_data, vec4); \
|
||||
} \
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Index of the quad primitive. Each quad corresponds to one line in the input primitive. */
|
||||
int quad_id = gl_VertexID / 6;
|
||||
/* Determine vertex ID. */
|
||||
int quad_vertex_id = gl_VertexID % 6;
|
||||
|
||||
/* Get current point attributes. */
|
||||
uint src_index_a = quad_id * 2;
|
||||
uint src_index_b = quad_id * 2 + 1;
|
||||
|
||||
vec3 in_pos[2];
|
||||
in_pos[0] = vertex_fetch_attribute(src_index_a, pos, vec3);
|
||||
in_pos[1] = vertex_fetch_attribute(src_index_b, pos, vec3);
|
||||
|
||||
vec4 in_lnor[2];
|
||||
nor_to_vec4(src_index_a, lnor, in_lnor[0]);
|
||||
nor_to_vec4(src_index_b, lnor, in_lnor[1]);
|
||||
|
||||
vec4 in_vnor[2];
|
||||
nor_to_vec4(src_index_a, vnor, in_vnor[0]);
|
||||
nor_to_vec4(src_index_b, vnor, in_vnor[1]);
|
||||
|
||||
vec4 in_norAndFlag[2];
|
||||
nor_to_vec4(src_index_a, norAndFlag, in_norAndFlag[0]);
|
||||
nor_to_vec4(src_index_b, norAndFlag, in_norAndFlag[1]);
|
||||
|
||||
/* Convert to ndc space. Vertex shader main area. */
|
||||
vec4 out_pos[2];
|
||||
out_pos[0] = vertex_main(src_index_a, in_pos[0], in_lnor[0], in_vnor[0], in_norAndFlag[0]);
|
||||
out_pos[1] = vertex_main(src_index_b, in_pos[1], in_lnor[1], in_vnor[1], in_norAndFlag[1]);
|
||||
|
||||
/* Geometry shader main area. */
|
||||
vec4 clippedP[2];
|
||||
clippedP[0] = clip_line_point_homogeneous_space(out_pos[0], out_pos[1]);
|
||||
clippedP[1] = clip_line_point_homogeneous_space(out_pos[1], out_pos[0]);
|
||||
vec2 e = normalize(((clippedP[1].xy / clippedP[1].w) - (clippedP[0].xy / clippedP[0].w)) *
|
||||
sizeViewport.xy);
|
||||
|
||||
#if 0 /* Hard turn when line direction changes quadrant. */
|
||||
e = abs(e);
|
||||
vec2 ofs = (e.x > e.y) ? vec2(0.0, 1.0 / e.x) : vec2(1.0 / e.y, 0.0);
|
||||
#else /* Use perpendicular direction. */
|
||||
vec2 ofs = vec2(-e.y, e.x);
|
||||
#endif
|
||||
|
||||
ofs /= sizeViewport.xy;
|
||||
ofs *= LINE_WIDTH + SMOOTH_WIDTH;
|
||||
|
||||
if (quad_vertex_id == 0) {
|
||||
do_vertex(0, clippedP[0], ofs, 1.0);
|
||||
}
|
||||
else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
|
||||
do_vertex(0, clippedP[0], ofs, -1.0);
|
||||
}
|
||||
else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
|
||||
do_vertex(1, clippedP[1], ofs, 1.0);
|
||||
}
|
||||
else if (quad_vertex_id == 4) {
|
||||
do_vertex(1, clippedP[1], ofs, -1.0);
|
||||
}
|
||||
}
|
@ -494,6 +494,7 @@ void gpu_shader_create_info_init()
|
||||
overlay_edit_mesh_edge_flat = overlay_edit_mesh_edge_flat_no_geom;
|
||||
overlay_edit_mesh_edge_clipped = overlay_edit_mesh_edge_clipped_no_geom;
|
||||
overlay_edit_mesh_edge_flat_clipped = overlay_edit_mesh_edge_flat_clipped_no_geom;
|
||||
overlay_edit_mesh_normal = overlay_edit_mesh_normal_no_geom;
|
||||
overlay_edit_curve_handle = overlay_edit_curve_handle_no_geom;
|
||||
overlay_edit_curve_handle_clipped = overlay_edit_curve_handle_clipped_no_geom;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user