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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-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
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.cc25
-rw-r--r--source/blender/gpu/metal/mtl_shader.mm1
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl162
-rw-r--r--source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh39
13 files changed, 950 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
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 0ce4011b2b4..a322922e86e 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -297,6 +297,7 @@ set(GLSL_SRC
shaders/gpu_shader_3D_polyline_frag.glsl
shaders/gpu_shader_3D_polyline_geom.glsl
shaders/gpu_shader_3D_polyline_vert.glsl
+ shaders/gpu_shader_3D_polyline_vert_no_geom.glsl
shaders/gpu_shader_3D_smooth_color_vert.glsl
shaders/gpu_shader_3D_smooth_color_frag.glsl
shaders/gpu_shader_3D_passthrough_vert.glsl
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index a18fdcd32df..ff7aa65f03f 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -305,6 +305,31 @@ void gpu_shader_create_info_init()
draw_resource_id_new = draw_resource_id_fallback;
}
+ /* Metal-specific alternatives for Geometry shaders. */
+ if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_METAL)) {
+
+ /* 3D polyline. */
+ gpu_shader_3D_polyline_uniform_color = gpu_shader_3D_polyline_uniform_color_no_geom;
+ gpu_shader_3D_polyline_flat_color = gpu_shader_3D_polyline_flat_color_no_geom;
+ gpu_shader_3D_polyline_smooth_color = gpu_shader_3D_polyline_smooth_color_no_geom;
+ gpu_shader_3D_polyline_uniform_color_clipped =
+ gpu_shader_3D_polyline_uniform_color_clipped_no_geom;
+
+ /* Overlay Edit Mesh. */
+ overlay_edit_mesh_edge = overlay_edit_mesh_edge_no_geom;
+ 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 Armature Shape outline. */
+ overlay_armature_shape_outline = overlay_armature_shape_outline_no_geom;
+ overlay_armature_shape_outline_clipped = overlay_armature_shape_outline_clipped_no_geom;
+
+ /* Overlay Motion Path Line. */
+ overlay_motion_path_line = overlay_motion_path_line_no_geom;
+ overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom;
+ }
+
for (ShaderCreateInfo *info : g_create_infos->values()) {
if (info->do_static_compilation_) {
info->builtins_ |= gpu_shader_dependency_get_builtins(info->vertex_source_);
diff --git a/source/blender/gpu/metal/mtl_shader.mm b/source/blender/gpu/metal/mtl_shader.mm
index 3b27b60bca0..006d3394378 100644
--- a/source/blender/gpu/metal/mtl_shader.mm
+++ b/source/blender/gpu/metal/mtl_shader.mm
@@ -539,6 +539,7 @@ void MTLShader::push_constant_bindstate_mark_dirty(bool is_dirty)
{
push_constant_modified_ = is_dirty;
}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl
new file mode 100644
index 00000000000..0ae39dde4c1
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl
@@ -0,0 +1,162 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+/* Local vars to store results per input vertex. */
+#if !defined(UNIFORM)
+vec4 finalColor_g[2];
+#endif
+
+#ifdef CLIP
+float clip_g[2];
+#endif
+
+#define SMOOTH_WIDTH 1.0
+
+/* 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(int index, vec4 pos, vec2 ofs, float flip)
+{
+#if defined(UNIFORM)
+ interp.final_color = color;
+
+#elif defined(FLAT)
+ /* WATCH: Assuming last provoking vertex. */
+ interp.final_color = finalColor_g[index];
+
+#elif defined(SMOOTH)
+ interp.final_color = finalColor_g[index];
+#endif
+
+#ifdef CLIP
+ interp.clip = clip_g[index];
+#endif
+
+ interp.smoothline = flip * (lineWidth + SMOOTH_WIDTH * float(lineSmooth)) * 0.5;
+ gl_Position = pos;
+ gl_Position.xy += flip * ofs * pos.w;
+}
+
+void main()
+{
+ /** Determine output quad primitive structure. */
+ /* Index of the quad primitive. Each quad corresponds to one line in the input primitive. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the quad (A, B, C)(A, C, D).*/
+ int quad_vertex_id = gl_VertexID % 6;
+
+ uint src_index_a;
+ uint src_index_b;
+ if (vertex_fetch_get_input_prim_type() == GPU_PRIM_LINE_STRIP) {
+ src_index_a = quad_id;
+ src_index_b = quad_id + 1;
+ }
+ else if (vertex_fetch_get_input_prim_type() == GPU_PRIM_LINES) {
+ src_index_a = quad_id * 2;
+ src_index_b = quad_id * 2 + 1;
+ }
+ else if (vertex_fetch_get_input_prim_type() == GPU_PRIM_LINE_LOOP) {
+ src_index_a = quad_id;
+ src_index_b = quad_id + 1;
+ if (quad_id == vertex_fetch_get_input_vert_count() - 1) {
+ src_index_b = 0;
+ }
+ }
+ else {
+ src_index_a = 0;
+ src_index_b = 0;
+ }
+
+ /* Fetch input attributes for line prims -- either provided as vec2 or vec3 -- So we need to
+ * query the type. */
+ vec3 in_pos0, in_pos1;
+ in_pos0 = vec3(0.0);
+ in_pos1 = vec3(0.0);
+ if (vertex_fetch_get_attr_type(pos) == GPU_SHADER_ATTR_TYPE_VEC4) {
+ in_pos0 = vertex_fetch_attribute(src_index_a, pos, vec4).xyz;
+ in_pos1 = vertex_fetch_attribute(src_index_b, pos, vec4).xyz;
+ }
+ else if (vertex_fetch_get_attr_type(pos) == GPU_SHADER_ATTR_TYPE_VEC3) {
+ in_pos0 = vertex_fetch_attribute(src_index_a, pos, vec3);
+ in_pos1 = vertex_fetch_attribute(src_index_b, pos, vec3);
+ }
+ else if (vertex_fetch_get_attr_type(pos) == GPU_SHADER_ATTR_TYPE_VEC2) {
+ in_pos0 = vec3(vertex_fetch_attribute(src_index_a, pos, vec2), 0.0);
+ in_pos1 = vec3(vertex_fetch_attribute(src_index_b, pos, vec2), 0.0);
+ }
+#if !defined(UNIFORM)
+ vec4 in_color0 = vec4(0.0);
+ vec4 in_color1 = vec4(0.0);
+
+ if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_VEC4) {
+ in_color0 = vertex_fetch_attribute(src_index_a, color, vec4);
+ in_color1 = vertex_fetch_attribute(src_index_b, color, vec4);
+ }
+ else if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_VEC3) {
+ in_color0 = vec4(vertex_fetch_attribute(src_index_a, color, vec3), 1.0);
+ in_color1 = vec4(vertex_fetch_attribute(src_index_b, color, vec3), 1.0);
+ }
+ else if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_UCHAR4_NORM) {
+ in_color0 = vec4(vertex_fetch_attribute(src_index_a, color, uchar4)) / vec4(255.0);
+ in_color1 = vec4(vertex_fetch_attribute(src_index_b, color, uchar4)) / vec4(255.0);
+ }
+ else if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_UCHAR3_NORM) {
+ in_color0 = vec4(vec3(vertex_fetch_attribute(src_index_a, color, uchar3)) / vec3(255.0), 1.0);
+ in_color1 = vec4(vec3(vertex_fetch_attribute(src_index_b, color, uchar3)) / vec3(255.0), 1.0);
+ }
+#endif
+
+ /* Calculate Vertex shader for both points in Line. */
+ vec4 out_pos0 = ModelViewProjectionMatrix * vec4(in_pos0, 1.0);
+ vec4 out_pos1 = ModelViewProjectionMatrix * vec4(in_pos1, 1.0);
+#if !defined(UNIFORM)
+ finalColor_g[0] = in_color0;
+ finalColor_g[1] = in_color1;
+#endif
+#ifdef CLIP
+ clip_g[0] = dot(ModelMatrix * vec4(in_pos0, 1.0), ClipPlane);
+ clip_g[1] = dot(ModelMatrix * vec4(in_pos1, 1.0), ClipPlane);
+#endif
+
+ /*** Geometry Shader Alternative. ***/
+ vec4 p0 = clip_line_point_homogeneous_space(out_pos0, out_pos1);
+ vec4 p1 = clip_line_point_homogeneous_space(out_pos1, out_pos0);
+ vec2 e = normalize(((p1.xy / p1.w) - (p0.xy / p0.w)) * viewportSize.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 /= viewportSize.xy;
+ ofs *= lineWidth + SMOOTH_WIDTH * float(lineSmooth);
+
+ if (quad_vertex_id == 0) {
+ do_vertex(0, p0, ofs, 1.0);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+ do_vertex(0, p0, ofs, -1.0);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+ do_vertex(1, p1, ofs, 1.0);
+ }
+ else if (quad_vertex_id == 4) {
+ do_vertex(1, p1, ofs, -1.0);
+ }
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
index 396ee64454c..b486674082e 100644
--- a/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
+++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
@@ -29,12 +29,31 @@ GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline)
.fragment_source("gpu_shader_3D_polyline_frag.glsl")
.additional_info("gpu_srgb_to_framebuffer_space");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_no_geom)
+ .define("SMOOTH_WIDTH", "1.0")
+ .push_constant(Type::MAT4, "ModelViewProjectionMatrix")
+ .push_constant(Type::VEC2, "viewportSize")
+ .push_constant(Type::FLOAT, "lineWidth")
+ .push_constant(Type::BOOL, "lineSmooth")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_out(gpu_shader_3D_polyline_iface)
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("gpu_shader_3D_polyline_vert_no_geom.glsl")
+ .fragment_source("gpu_shader_3D_polyline_frag.glsl")
+ .additional_info("gpu_srgb_to_framebuffer_space");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color)
.do_static_compilation(true)
.define("UNIFORM")
.push_constant(Type::VEC4, "color")
.additional_info("gpu_shader_3D_polyline");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_no_geom)
+ .do_static_compilation(true)
+ .define("UNIFORM")
+ .push_constant(Type::VEC4, "color")
+ .additional_info("gpu_shader_3D_polyline_no_geom");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_clipped)
.do_static_compilation(true)
/* TODO(fclem): Put in a UBO to fit the 128byte requirement. */
@@ -43,14 +62,34 @@ GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_clipped)
.define("CLIP")
.additional_info("gpu_shader_3D_polyline_uniform_color");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_clipped_no_geom)
+ .do_static_compilation(true)
+ /* TODO(fclem): Put in an UBO to fit the 128byte requirement. */
+ .push_constant(Type::MAT4, "ModelMatrix")
+ .push_constant(Type::VEC4, "ClipPlane")
+ .define("CLIP")
+ .additional_info("gpu_shader_3D_polyline_uniform_color_no_geom");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_flat_color)
.do_static_compilation(true)
.define("FLAT")
.vertex_in(1, Type::VEC4, "color")
.additional_info("gpu_shader_3D_polyline");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_flat_color_no_geom)
+ .do_static_compilation(true)
+ .define("FLAT")
+ .vertex_in(1, Type::VEC4, "color")
+ .additional_info("gpu_shader_3D_polyline_no_geom");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_smooth_color)
.do_static_compilation(true)
.define("SMOOTH")
.vertex_in(1, Type::VEC4, "color")
.additional_info("gpu_shader_3D_polyline");
+
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_smooth_color_no_geom)
+ .do_static_compilation(true)
+ .define("SMOOTH")
+ .vertex_in(1, Type::VEC4, "color")
+ .additional_info("gpu_shader_3D_polyline_no_geom");