diff options
Diffstat (limited to 'source/blender/draw/engines')
7 files changed, 718 insertions, 0 deletions
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 |