Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Fielder <jason_apple>2022-09-22 18:40:45 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-09-22 18:43:04 +0300
commit1514e1a5b7e15ec0c11cd40c2b9389982bd5d00e (patch)
tree3c7028d7d8e9a96b3047d2e5ad84f0c2276f2530 /source/blender/draw
parent697b447c2069bbbbaa9929aab0ea1f66ef8bf4d0 (diff)
Metal: First set of Geometry Shader alternative implementations using SSBO vertex shader fetch.
These implementations remove dependency on the Geometry pass by instead invoking one vertex shader instance for each expected output vertex, matching what a geometry shader would emit. Each vertex shader instance is then responsible for calculating the same output position based on its vertex_id as the logic would in the geometry shader version. SSBO Vertex fetch enables full random-access into a vertex buffer by binding it as a read-only SSBO. This enables each instance to read neighbouring vertex data to perform contextual calculations as a geometry shader would, for cases where attribute Multiload is not supported. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Differential Revision: https://developer.blender.org/D15901
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt4
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh21
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh55
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh20
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl182
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl16
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl236
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl188
8 files changed, 722 insertions, 0 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 8b61d8686cd..540041ed02a 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -555,6 +555,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl
engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl
engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl
+ engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl
engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl
engines/overlay/shaders/overlay_armature_shape_wire_vert.glsl
@@ -572,6 +573,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_depth_only_vert.glsl
engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl
engines/overlay/shaders/overlay_edit_curve_handle_vert.glsl
+ engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
engines/overlay/shaders/overlay_edit_curve_point_vert.glsl
engines/overlay/shaders/overlay_edit_curve_wire_vert.glsl
engines/overlay/shaders/overlay_edit_gpencil_canvas_vert.glsl
@@ -587,6 +589,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_edit_mesh_normal_vert.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
engines/overlay/shaders/overlay_edit_particle_point_vert.glsl
engines/overlay/shaders/overlay_edit_particle_strand_vert.glsl
engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl
@@ -619,6 +622,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_motion_path_line_frag.glsl
engines/overlay/shaders/overlay_motion_path_line_geom.glsl
engines/overlay/shaders/overlay_motion_path_line_vert.glsl
+ engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
engines/overlay/shaders/overlay_motion_path_point_vert.glsl
engines/overlay/shaders/overlay_outline_detect_frag.glsl
engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
index 9f2acceed97..0ab653ba29f 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
@@ -69,6 +69,11 @@ GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_outline_iface, "geom_in")
.smooth(Type::VEC4, "vColSize")
.flat(Type::INT, "inverted");
+GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_outline_no_geom_iface, "")
+ .flat(Type::VEC4, "finalColor")
+ .flat(Type::VEC2, "edgeStart")
+ .no_perspective(Type::VEC2, "edgePos");
+
GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
@@ -84,10 +89,26 @@ GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline)
.fragment_source("overlay_armature_wire_frag.glsl")
.additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_no_geom)
+ .do_static_compilation(true)
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::VEC3, "snor")
+ /* Per instance. */
+ .vertex_in(2, Type::VEC4, "color")
+ .vertex_in(3, Type::MAT4, "inst_obmat")
+ .vertex_out(overlay_armature_shape_outline_no_geom_iface)
+ .vertex_source("overlay_armature_shape_outline_vert_no_geom.glsl")
+ .fragment_source("overlay_armature_wire_frag.glsl")
+ .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_clipped)
.do_static_compilation(true)
.additional_info("overlay_armature_shape_outline", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_armature_shape_outline_no_geom", "drw_clipped");
+
GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_solid_iface, "")
.smooth(Type::VEC4, "finalColor")
.flat(Type::INT, "inverted");
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
index 9396a6d3f2f..92a35a049a4 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
@@ -22,6 +22,17 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common)
.vertex_source("overlay_edit_mesh_vert.glsl")
.additional_info("draw_modelmat", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common_no_geom)
+ .define("blender_srgb_to_framebuffer_space(a)", "a")
+ .sampler(0, ImageType::DEPTH_2D, "depthTex")
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .push_constant(Type::BOOL, "selectFaces")
+ .push_constant(Type::BOOL, "selectEdges")
+ .push_constant(Type::FLOAT, "alpha")
+ .push_constant(Type::IVEC4, "dataMask")
+ .vertex_source("overlay_edit_mesh_vert_no_geom.glsl")
+ .additional_info("draw_modelmat", "draw_globals");
+
GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_vert_iface, "")
.smooth(Type::VEC4, "finalColor")
.smooth(Type::FLOAT, "vertexCrease");
@@ -61,11 +72,28 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge)
.fragment_source("overlay_edit_mesh_frag.glsl")
.additional_info("overlay_edit_mesh_common");
+/* The Non-Geometry shader variant passes directly to fragment. */
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_no_geom)
+ .do_static_compilation(true)
+ .define("EDGE")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::UCHAR4, "data")
+ .vertex_in(2, Type::VEC3_101010I2, "vnor")
+ .push_constant(Type::BOOL, "do_smooth_wire")
+ .vertex_out(overlay_edit_mesh_edge_geom_iface)
+ .fragment_source("overlay_edit_mesh_frag.glsl")
+ .additional_info("overlay_edit_mesh_common_no_geom");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat)
.do_static_compilation(true)
.define("FLAT")
.additional_info("overlay_edit_mesh_edge");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_no_geom)
+ .do_static_compilation(true)
+ .define("FLAT")
+ .additional_info("overlay_edit_mesh_edge_no_geom");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face)
.do_static_compilation(true)
.define("FACE")
@@ -136,10 +164,18 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_edit_mesh_edge_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge_flat", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_edit_mesh_edge_flat_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_face", "drw_clipped");
@@ -326,10 +362,29 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle)
.fragment_source("overlay_varying_color.glsl")
.additional_info("draw_mesh", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_no_geom)
+ .do_static_compilation(true)
+ .typedef_source("overlay_shader_shared.h")
+ /* NOTE: Color already in Linear space. Which is what we want. */
+ .define("srgbTarget", "false")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::INT, "data")
+ .vertex_out(overlay_edit_curve_handle_iface)
+ .push_constant(Type::BOOL, "showCurveHandles")
+ .push_constant(Type::INT, "curveHandleDisplay")
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("overlay_edit_curve_handle_vert_no_geom.glsl")
+ .fragment_source("overlay_varying_color.glsl")
+ .additional_info("draw_mesh", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_curve_handle", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_edit_curve_handle_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_curve_point)
.do_static_compilation(true)
.typedef_source("overlay_shader_shared.h")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
index 5b50bbcaa55..4ebc83c27b0 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
@@ -183,6 +183,9 @@ GPU_SHADER_INTERFACE_INFO(overlay_motion_path_line_iface, "interp")
.flat(Type::VEC2, "ss_pos")
.smooth(Type::VEC4, "color");
+GPU_SHADER_INTERFACE_INFO(overlay_motion_path_line_no_geom_iface, "interp")
+ .smooth(Type::VEC4, "color");
+
GPU_SHADER_CREATE_INFO(overlay_motion_path_line)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
@@ -199,10 +202,27 @@ GPU_SHADER_CREATE_INFO(overlay_motion_path_line)
.fragment_source("overlay_motion_path_line_frag.glsl")
.additional_info("draw_view", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_motion_path_line_no_geom)
+ .do_static_compilation(true)
+ .vertex_in(0, Type::VEC3, "pos")
+ .push_constant(Type::IVEC4, "mpathLineSettings")
+ .push_constant(Type::BOOL, "selected")
+ .push_constant(Type::VEC3, "customColor")
+ .push_constant(Type::INT, "lineThickness") /* In pixels. */
+ .vertex_out(overlay_motion_path_line_no_geom_iface)
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("overlay_motion_path_line_vert_no_geom.glsl")
+ .fragment_source("overlay_motion_path_line_frag.glsl")
+ .additional_info("draw_view", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_motion_path_line_clipped)
.do_static_compilation(true)
.additional_info("overlay_motion_path_line", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_motion_path_line_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_motion_path_line_no_geom", "drw_clipped");
+
GPU_SHADER_INTERFACE_INFO(overlay_motion_path_point_iface, "").flat(Type::VEC4, "finalColor");
GPU_SHADER_CREATE_INFO(overlay_motion_path_point)
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
new file mode 100644
index 00000000000..191a9f98f02
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
@@ -0,0 +1,182 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(LineList, 2)
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define DISCARD_VERTEX \
+ gl_Position = finalColor = vec4(0.0); \
+ edgeStart = edgePos = vec2(0.0); \
+ return;
+
+/* Project to screen space. */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
+}
+
+void do_vertex_shader(mat4 in_inst_obmat,
+ vec3 in_pos,
+ vec3 in_snor,
+ out vec4 out_pPos,
+ out vec3 out_vPos,
+ out vec2 out_ssPos,
+ out vec2 out_ssNor,
+ out vec4 out_vColSize,
+ out int out_inverted,
+ out vec4 out_wpos)
+{
+ vec4 bone_color, state_color;
+ mat4 model_mat = extract_matrix_packed_data(in_inst_obmat, state_color, bone_color);
+
+ vec4 worldPosition = model_mat * vec4(in_pos, 1.0);
+ vec4 viewpos = ViewMatrix * worldPosition;
+ out_wpos = worldPosition;
+ out_vPos = viewpos.xyz;
+ out_pPos = ProjectionMatrix * viewpos;
+
+ out_inverted = int(dot(cross(model_mat[0].xyz, model_mat[1].xyz), model_mat[2].xyz) < 0.0);
+
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attribute. */
+ mat3 normal_mat = transpose(inverse(mat3(model_mat)));
+ /* TODO FIX: there is still a problem with this vector
+ * when the bone is scaled or in persp mode. But it's
+ * barely visible at the outline corners. */
+ out_ssNor = normalize(normal_world_to_view(normal_mat * in_snor).xy);
+
+ out_ssPos = proj(out_pPos);
+
+ out_vColSize = bone_color;
+}
+
+void main()
+{
+ /* Outputs a singular vertex as part of a LineList primitive, however, requires access to
+ * neighbouring 4 vertices. */
+ /* Fetch verts from input type lines adjacency. */
+ int line_prim_id = (gl_VertexID / 2);
+ int line_vertex_id = gl_VertexID % 2;
+ int base_vertex_id = line_prim_id * 2;
+
+ /* IF Input Primitive Type == Lines_Adjacency, then indices are accessed as per GL specification:
+ * i.e. 4 indices per unique prim (Provoking vert 4i-2)
+ *
+ * IF Input Primitive Type == LineStrip_Adjacency, then indices are accessed using:
+ * - 2 indices per unique prim, plus 1 index at each end, such that the strided
+ * - 4-index block can be walked. */
+ vec3 in_pos[4];
+ in_pos[0] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id), pos, vec3);
+ in_pos[1] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 1), pos, vec3);
+ in_pos[2] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 2), pos, vec3);
+ in_pos[3] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 3), pos, vec3);
+
+ vec3 in_snor[4];
+ in_snor[0] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id), snor, vec3);
+ in_snor[1] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 1), snor, vec3);
+ in_snor[2] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 2), snor, vec3);
+ in_snor[3] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 3), snor, vec3);
+
+ mat4 in_inst_obmat = vertex_fetch_attribute(gl_VertexID, inst_obmat, mat4);
+
+ /* Run original GL vertex shader implementation per vertex in adjacency list. */
+ vec4 pPos[4];
+ vec3 vPos[4];
+ vec2 ssPos[4];
+ vec2 ssNor[4];
+ vec4 vColSize[4];
+ int inverted[4];
+ vec4 wPos[4];
+
+ for (int v = 0; v < 4; v++) {
+ do_vertex_shader(in_inst_obmat,
+ in_pos[v],
+ in_snor[v],
+ pPos[v],
+ vPos[v],
+ ssPos[v],
+ ssNor[v],
+ vColSize[v],
+ inverted[v],
+ wPos[v]);
+ }
+
+ /* Geometry Shader equivalent to calculate vertex output position. */
+ finalColor = vec4(vColSize[0].rgb, 1.0);
+
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+
+ vec3 view_vec = (is_persp) ? normalize(vPos[1]) : vec3(0.0, 0.0, -1.0);
+ vec3 v10 = vPos[0] - vPos[1];
+ vec3 v12 = vPos[2] - vPos[1];
+ vec3 v13 = vPos[3] - vPos[1];
+
+ vec3 n0 = cross(v12, v10);
+ vec3 n3 = cross(v13, v12);
+
+ float fac0 = dot(view_vec, n0);
+ float fac3 = dot(view_vec, n3);
+
+ /* If one of the face is perpendicular to the view,
+ * consider it and outline edge. */
+ if (abs(fac0) > 1e-5 && abs(fac3) > 1e-5) {
+ /* If both adjacent verts are facing the camera the same way,
+ * then it isn't an outline edge. */
+ if (sign(fac0) == sign(fac3)) {
+ DISCARD_VERTEX
+ }
+ }
+
+ n0 = (inverted[0] == 1) ? -n0 : n0;
+ /* Don't outline if concave edge. */
+ if (dot(n0, v13) > 0.0001) {
+ DISCARD_VERTEX
+ }
+
+ vec2 perp = normalize(ssPos[2] - ssPos[1]);
+ vec2 edge_dir = vec2(-perp.y, perp.x);
+
+ vec2 hidden_point;
+ /* Take the farthest point to compute edge direction
+ * (avoid problems with point behind near plane).
+ * If the chosen point is parallel to the edge in screen space,
+ * choose the other point anyway.
+ * This fixes some issue with cubes in orthographic views.*/
+ if (vPos[0].z < vPos[3].z) {
+ hidden_point = (abs(fac0) > 1e-5) ? ssPos[0] : ssPos[3];
+ }
+ else {
+ hidden_point = (abs(fac3) > 1e-5) ? ssPos[3] : ssPos[0];
+ }
+ vec2 hidden_dir = normalize(hidden_point - ssPos[1]);
+
+ float fac = dot(-hidden_dir, edge_dir);
+ edge_dir *= (fac < 0.0) ? -1.0 : 1.0;
+
+ /* Output corresponding value based on which vertex this corresponds to in the
+ * original input primitive. */
+ if (line_vertex_id == 0) {
+ gl_Position = pPos[1];
+ /* Offset away from the center to avoid overlap with solid shape. */
+ gl_Position.xy += (edge_dir - perp) * drw_view.viewport_size_inverse * gl_Position.w;
+ /* Improve AA bleeding inside bone silhouette. */
+ gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
+ edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(wPos[1].xyz);
+#endif
+ }
+ else {
+ gl_Position = pPos[2];
+ /* Offset away from the center to avoid overlap with solid shape. */
+ gl_Position.xy += (edge_dir + perp) * drw_view.viewport_size_inverse * gl_Position.w;
+ /* Improve AA bleeding inside bone silhouette. */
+ gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
+ edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(wPos[2].xyz);
+#endif
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
new file mode 100644
index 00000000000..82b88a14961
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
@@ -0,0 +1,16 @@
+/* TODO(Metal): Implement correct SSBO implementation for geom shader workaround.
+ * Currently included as placeholder to unblock failing compilation in Metal. */
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+void main()
+{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+ vert.flag = data;
+
+ view_clipping_distances(world_pos);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
new file mode 100644
index 00000000000..dd0de683ae1
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
@@ -0,0 +1,236 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(overlay_edit_mesh_common_lib.glsl)
+
+#define DISCARD_VERTEX \
+ gl_Position = geometry_out.finalColorOuter = geometry_out.finalColor = vec4(0.0); \
+ geometry_out.edgeCoord = 0.0; \
+ return;
+
+bool test_occlusion(vec4 pos)
+{
+ vec3 ndc = (pos.xyz / pos.w) * 0.5 + 0.5;
+ return ndc.z > texture(depthTex, ndc.xy).r;
+}
+
+vec3 non_linear_blend_color(vec3 col1, vec3 col2, float fac)
+{
+ col1 = pow(col1, vec3(1.0 / 2.2));
+ col2 = pow(col2, vec3(1.0 / 2.2));
+ vec3 col = mix(col1, col2, fac);
+ return pow(col, vec3(2.2));
+}
+
+vec3 vec3_1010102_Inorm_to_vec3(vec3 data)
+{
+ return data;
+}
+
+vec3 vec3_1010102_Inorm_to_vec3(int data)
+{
+ vec3 out_vec;
+ out_vec.x = float(clamp(data, -512, 511)) / 511.0f;
+ out_vec.y = float(clamp(data >> 10, -512, 511)) / 511.0f;
+ out_vec.z = float(clamp(data >> 20, -512, 511)) / 511.0f;
+ return out_vec;
+}
+
+void do_vertex(vec4 color, vec4 pos, float coord, vec2 offset)
+{
+ geometry_out.finalColor = color;
+ geometry_out.edgeCoord = coord;
+ gl_Position = pos;
+ /* Multiply offset by 2 because gl_Position range is [-1..1]. */
+ gl_Position.xy += offset * 2.0 * pos.w;
+}
+
+void main()
+{
+ /* Index of the quad primitive -- corresponds to one line prim. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the output 2-triangle quad (A, B, C)(A, C, D). */
+ int quad_vertex_id = gl_VertexID % 6;
+
+ /* Base index of the line primitive:
+ * IF PrimType == LineList: base_vertex_id = quad_id*2
+ * IF PrimType == LineStrip: base_vertex_id = quad_id
+ *
+ * Note: This is currently used as LineList.
+ *
+ * Note: Primitive Restart Will not work with this setup as-is. We should avoid using
+ * input primitive types which use restart indices. */
+ int base_vertex_id = quad_id * 2;
+
+ /* Fetch attribute values for self and neighbouring vertex. */
+ vec3 in_pos0 = vertex_fetch_attribute(base_vertex_id, pos, vec3);
+ vec3 in_pos1 = vertex_fetch_attribute(base_vertex_id + 1, pos, vec3);
+ uchar4 in_data0 = vertex_fetch_attribute(base_vertex_id, data, uchar4);
+ uchar4 in_data1 = vertex_fetch_attribute(base_vertex_id + 1, data, uchar4);
+ vec3 in_vnor0 = vec3_1010102_Inorm_to_vec3(
+ vertex_fetch_attribute(base_vertex_id, vnor, vec3_1010102_Inorm));
+ vec3 in_vnor1 = vec3_1010102_Inorm_to_vec3(
+ vertex_fetch_attribute(base_vertex_id + 1, vnor, vec3_1010102_Inorm));
+
+ /* Calculate values for self and neighbouring vertex. */
+ vec4 out_finalColor[2];
+ vec4 out_finalColorOuter[2];
+ int selectOveride[2];
+
+ vec3 world_pos0 = point_object_to_world(in_pos0);
+ vec3 world_pos1 = point_object_to_world(in_pos1);
+ vec4 out_pos0 = point_world_to_ndc(world_pos0);
+ vec4 out_pos1 = point_world_to_ndc(world_pos1);
+ ivec4 m_data0 = ivec4(in_data0) & dataMask;
+ ivec4 m_data1 = ivec4(in_data1) & dataMask;
+
+#if defined(EDGE)
+# ifdef FLAT
+ out_finalColor[0] = EDIT_MESH_edge_color_inner(m_data0.y);
+ out_finalColor[1] = EDIT_MESH_edge_color_inner(m_data1.y);
+ selectOveride[0] = 1;
+ selectOveride[1] = 1;
+# else
+ out_finalColor[0] = EDIT_MESH_edge_vertex_color(m_data0.y);
+ out_finalColor[1] = EDIT_MESH_edge_vertex_color(m_data1.y);
+ selectOveride[0] = (m_data0.y & EDGE_SELECTED);
+ selectOveride[1] = (m_data1.y & EDGE_SELECTED);
+# endif
+
+ float crease0 = float(m_data0.z) / 255.0;
+ float crease1 = float(m_data1.z) / 255.0;
+ float bweight0 = float(m_data0.w) / 255.0;
+ float bweight1 = float(m_data1.w) / 255.0;
+ out_finalColorOuter[0] = EDIT_MESH_edge_color_outer(m_data0.y, m_data0.x, crease0, bweight0);
+ out_finalColorOuter[1] = EDIT_MESH_edge_color_outer(m_data1.y, m_data1.x, crease1, bweight1);
+
+ if (out_finalColorOuter[0].a > 0.0) {
+ out_pos0.z -= 5e-7 * abs(out_pos0.w);
+ }
+ if (out_finalColorOuter[1].a > 0.0) {
+ out_pos1.z -= 5e-7 * abs(out_pos1.w);
+ }
+
+ /* Occlusion done in fragment shader. */
+ bool occluded0 = false;
+ bool occluded1 = false;
+#endif
+
+ out_finalColor[0].a *= (occluded0) ? alpha : 1.0;
+ out_finalColor[1].a *= (occluded1) ? alpha : 1.0;
+
+#if !defined(FACE)
+ /* Facing based color blend */
+ vec3 vpos0 = point_world_to_view(world_pos0);
+ vec3 view_normal0 = normalize(normal_object_to_view(in_vnor0) + 1e-4);
+ vec3 view_vec0 = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos0) : vec3(0.0, 0.0, 1.0);
+ float facing0 = dot(view_vec0, view_normal0);
+ facing0 = 1.0 - abs(facing0) * 0.2;
+
+ vec3 vpos1 = point_world_to_view(world_pos1);
+ vec3 view_normal1 = normalize(normal_object_to_view(in_vnor1) + 1e-4);
+ vec3 view_vec1 = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos1) : vec3(0.0, 0.0, 1.0);
+ float facing1 = dot(view_vec1, view_normal1);
+ facing1 = 1.0 - abs(facing1) * 0.2;
+
+ /* Do interpolation in a non-linear space to have a better visual result. */
+ out_finalColor[0].rgb = non_linear_blend_color(
+ colorEditMeshMiddle.rgb, out_finalColor[0].rgb, facing0);
+ out_finalColor[1].rgb = non_linear_blend_color(
+ colorEditMeshMiddle.rgb, out_finalColor[1].rgb, facing1);
+#endif
+
+#ifdef USE_WORLD_CLIP_PLANES
+ float out_clipdistances0[6];
+ float out_clipdistances1[6];
+ vec4 clip_pos0 = vec4(world_pos0, 1.0);
+ out_clipdistances0[0] = dot(WorldClipPlanes[0], clip_pos0);
+ out_clipdistances0[1] = dot(WorldClipPlanes[1], clip_pos0);
+ out_clipdistances0[2] = dot(WorldClipPlanes[2], clip_pos0);
+ out_clipdistances0[3] = dot(WorldClipPlanes[3], clip_pos0);
+ out_clipdistances0[4] = dot(WorldClipPlanes[4], clip_pos0);
+ out_clipdistances0[5] = dot(WorldClipPlanes[5], clip_pos0);
+
+ vec4 clip_pos1 = vec4(world_pos1, 1.0);
+ out_clipdistances1[0] = dot(WorldClipPlanes[0], clip_pos1);
+ out_clipdistances1[1] = dot(WorldClipPlanes[1], clip_pos1);
+ out_clipdistances1[2] = dot(WorldClipPlanes[2], clip_pos1);
+ out_clipdistances1[3] = dot(WorldClipPlanes[3], clip_pos1);
+ out_clipdistances1[4] = dot(WorldClipPlanes[4], clip_pos1);
+ out_clipdistances1[5] = dot(WorldClipPlanes[5], clip_pos1);
+#endif
+
+ // -------- GEOM SHADER ALTERNATIVE ----------- //
+ vec2 ss_pos[2];
+
+ /* Clip line against near plane to avoid deformed lines. */
+ vec4 pos0 = out_pos0;
+ vec4 pos1 = out_pos1;
+ vec2 pz_ndc = vec2(pos0.z / pos0.w, pos1.z / pos1.w);
+ bvec2 clipped = lessThan(pz_ndc, vec2(-1.0));
+ if (all(clipped)) {
+ /* Totally clipped. */
+ DISCARD_VERTEX;
+ }
+
+ vec4 pos01 = pos0 - pos1;
+ float ofs = abs((pz_ndc.y + 1.0) / (pz_ndc.x - pz_ndc.y));
+ if (clipped.y) {
+ pos1 += pos01 * ofs;
+ }
+ else if (clipped.x) {
+ pos0 -= pos01 * (1.0 - ofs);
+ }
+
+ ss_pos[0] = pos0.xy / pos0.w;
+ ss_pos[1] = pos1.xy / pos1.w;
+
+ vec2 line = ss_pos[0] - ss_pos[1];
+ line = abs(line) * sizeViewport.xy;
+
+ geometry_out.finalColorOuter = out_finalColorOuter[0];
+ float half_size = sizeEdge;
+ /* Enlarge edge for flag display. */
+ half_size += (geometry_out.finalColorOuter.a > 0.0) ? max(sizeEdge, 1.0) : 0.0;
+
+#ifdef USE_SMOOTH_WIRE
+ /* Add 1 px for AA */
+ half_size += 0.5;
+#endif
+
+ vec3 edge_ofs = vec3(half_size * drw_view.viewport_size_inverse, 0.0);
+
+ bool horizontal = line.x > line.y;
+ edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
+
+ vec4 final_color = (selectOveride[0] == 0) ? out_finalColor[1] : out_finalColor[0];
+
+ /* Output specific Vertex data depending on quad_vertex_id. */
+ if (quad_vertex_id == 0) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances0);
+#endif
+ do_vertex(out_finalColor[0], pos0, half_size, edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances0);
+#endif
+ do_vertex(out_finalColor[0], pos0, -half_size, -edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances1);
+#endif
+ do_vertex(final_color, pos1, half_size, edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 4) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances1);
+#endif
+ do_vertex(final_color, pos1, -half_size, -edge_ofs.xy);
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
new file mode 100644
index 00000000000..731c384803e
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
@@ -0,0 +1,188 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define frameCurrent mpathLineSettings.x
+#define frameStart mpathLineSettings.y
+#define frameEnd mpathLineSettings.z
+#define cacheStart mpathLineSettings.w
+
+/* Project to screen space. */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
+}
+
+#define SET_INTENSITY(A, B, C, min, max) \
+ (((1.0 - (float(C - B) / float(C - A))) * (max - min)) + min)
+
+vec2 compute_dir(vec2 v0, vec2 v1)
+{
+ vec2 dir = normalize(v1 - v0 + 1e-8);
+ dir = vec2(-dir.y, dir.x);
+ return dir;
+}
+
+void do_vertex_shader(vec4 pos, int vertex_id, out vec2 out_sspos, out vec4 out_finalcolour)
+{
+ out_sspos = proj(pos);
+ out_finalcolour = vec4(0.0);
+
+ int frame = vertex_id + cacheStart;
+ float intensity; /* how faint */
+ vec3 blend_base = (abs(frame - frameCurrent) == 0) ?
+ colorCurrentFrame.rgb :
+ colorBackground.rgb; /* "bleed" cframe color to ease color blending */
+ bool use_custom_color = customColor.x >= 0.0;
+ /* TODO: We might want something more consistent with custom color and standard colors. */
+ if (frame < frameCurrent) {
+ if (use_custom_color) {
+ /* Custom color: previous frames color is darker than current frame */
+ out_finalcolour.rgb = customColor * 0.25;
+ }
+ else {
+ /* black - before frameCurrent */
+ if (selected) {
+ intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.25, 0.75);
+ }
+ else {
+ intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.68, 0.92);
+ }
+ out_finalcolour.rgb = mix(colorWire.rgb, blend_base, intensity);
+ }
+ }
+ else if (frame > frameCurrent) {
+ if (use_custom_color) {
+ /* Custom color: next frames color is equal to user selected color */
+ out_finalcolour.rgb = customColor;
+ }
+ else {
+ /* blue - after frameCurrent */
+ if (selected) {
+ intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.25, 0.75);
+ }
+ else {
+ intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.68, 0.92);
+ }
+
+ out_finalcolour.rgb = mix(colorBonePose.rgb, blend_base, intensity);
+ }
+ }
+ else {
+ if (use_custom_color) {
+ /* Custom color: current frame color is slightly darker than user selected color */
+ out_finalcolour.rgb = customColor * 0.5;
+ }
+ else {
+ /* green - on frameCurrent */
+ if (selected) {
+ intensity = 0.92f;
+ }
+ else {
+ intensity = 0.75f;
+ }
+ out_finalcolour.rgb = mix(colorBackground.rgb, blend_base, intensity);
+ }
+ }
+ out_finalcolour.a = 1.0;
+}
+
+void main()
+{
+ /** Determine Output Primitive ID and relative vertex. */
+ /* Index of the quad primitive. We generate one quad for each input line. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the quad (A, B, C)(A, C, D). */
+ int quad_vertex_id = gl_VertexID % 6;
+ /* Base index of the line primitive:
+ * - IF PrimType == LineList: base_vertex_id = quad_id*2
+ * - IF PrimType == LineStrip: base_vertex_id = quad_id
+ *
+ * Note: Primitive is LineStrip for this shader. */
+ int base_vertex_id = quad_id;
+
+ /* Fetch attributes for self and neighbouring vertex. */
+ vec3 in_pos0 = vertex_fetch_attribute(base_vertex_id, pos, vec3);
+ vec3 in_pos1 = vertex_fetch_attribute(base_vertex_id + 1, pos, vec3);
+
+ vec4 out_pos0 = ViewProjectionMatrix * vec4(in_pos0, 1.0);
+ vec4 out_pos1 = ViewProjectionMatrix * vec4(in_pos1, 1.0);
+
+ /* Final calculations required for Geometry Shader alternative.
+ * We need to calculate values for each vertex position to correctly determine the final output
+ * position. */
+ vec2 ssPos[2];
+ vec4 finalColor_geom[2];
+
+ do_vertex_shader(out_pos0, base_vertex_id, ssPos[0], finalColor_geom[0]);
+ do_vertex_shader(out_pos1, base_vertex_id + 1, ssPos[0], finalColor_geom[0]);
+
+ /* Calculate Vertex Clip distances. */
+#ifdef USE_WORLD_CLIP_PLANES
+ float out_ClipDistance0[6];
+
+ out_ClipDistance0[0] = dot(clipPlanes[0], out_pos0);
+ out_ClipDistance0[1] = dot(clipPlanes[1], out_pos0);
+ out_ClipDistance0[2] = dot(clipPlanes[2], out_pos0);
+ out_ClipDistance0[3] = dot(clipPlanes[3], out_pos0);
+ out_ClipDistance0[4] = dot(clipPlanes[4], out_pos0);
+ out_ClipDistance0[5] = dot(clipPlanes[5], out_pos0);
+
+ float out_ClipDistance1[6];
+ out_ClipDistance1[0] = dot(clipPlanes[0], out_pos1);
+ out_ClipDistance1[1] = dot(clipPlanes[1], out_pos1);
+ out_ClipDistance1[2] = dot(clipPlanes[2], out_pos1);
+ out_ClipDistance1[3] = dot(clipPlanes[3], out_pos1);
+ out_ClipDistance1[4] = dot(clipPlanes[4], out_pos1);
+ out_ClipDistance1[5] = dot(clipPlanes[5], out_pos1);
+#endif
+
+ /* Geometry shader alternative -- Output is trianglelist consisting of 6 vertices.
+ * Each vertex shader invocation is one vertex in the output primitive, so outptut
+ * required ID. */
+ vec2 t;
+ vec2 edge_dir = compute_dir(ssPos[0], ssPos[1]) * drw_view.viewport_size_inverse;
+
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+ float line_size = float(lineThickness) * sizePixel;
+
+ if (quad_vertex_id == 0) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance0);
+#endif
+
+ interp.color = finalColor_geom[0];
+ t = edge_dir * (line_size * (is_persp ? out_pos0.w : 1.0));
+ gl_Position = out_pos0 + vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance0);
+#endif
+
+ interp.color = finalColor_geom[0];
+ t = edge_dir * (line_size * (is_persp ? out_pos0.w : 1.0));
+ gl_Position = out_pos0 - vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance1);
+#endif
+
+ interp.color = finalColor_geom[1];
+ t = edge_dir * (line_size * (is_persp ? out_pos1.w : 1.0));
+ gl_Position = out_pos1 + vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 4) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance1);
+#endif
+
+ interp.color = finalColor_geom[1];
+ t = edge_dir * (line_size * (is_persp ? out_pos1.w : 1.0));
+ gl_Position = out_pos1 - vec4(t, 0.0, 0.0);
+ }
+} \ No newline at end of file