This is the first step of moving the create infos back inside shader sources. All info files are now treated as source files. However, they are not considered in the include tree yet. This will come in another following PR. Each shader source file now generate a `.info` file containing only the create info declarations. This renames all info files so that they do not conflict with their previous versions that were copied (non-generated). Pull Request: https://projects.blender.org/blender/blender/pulls/146676
130 lines
4.5 KiB
GLSL
130 lines
4.5 KiB
GLSL
/* SPDX-FileCopyrightText: 2018-2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/**
|
|
* 2D Cubic Bezier thick line drawing
|
|
*/
|
|
|
|
/**
|
|
* `uv.x` is position along the curve, defining the tangent space.
|
|
* `uv.y` is "signed" distance (compressed to [0..1] range) from the pos in expand direction
|
|
* `pos` is the verts position in the curve tangent space
|
|
*/
|
|
|
|
#include "infos/gpu_shader_2D_nodelink_infos.hh"
|
|
|
|
VERTEX_SHADER_CREATE_INFO(gpu_shader_2D_nodelink)
|
|
|
|
#include "gpu_shader_attribute_load_lib.glsl"
|
|
#include "gpu_shader_math_vector_compare_lib.glsl"
|
|
|
|
void main()
|
|
{
|
|
constexpr float start_gradient_threshold = 0.35f;
|
|
constexpr float end_gradient_threshold = 0.65f;
|
|
|
|
const NodeLinkData link = link_data_buf[gl_InstanceID];
|
|
|
|
const float2 P0 = link.bezier_P0;
|
|
const float2 P1 = link.bezier_P1;
|
|
const float2 P2 = link.bezier_P2;
|
|
const float2 P3 = link.bezier_P3;
|
|
|
|
const uint3 color_ids = gpu_attr_decode_uchar4_to_uint4(link.color_ids).xyz;
|
|
|
|
const float4 color_start = (color_ids[0] < 3u) ? link.start_color :
|
|
link_uniforms.colors[color_ids[0]];
|
|
const float4 color_end = (color_ids[1] < 3u) ? link.end_color :
|
|
link_uniforms.colors[color_ids[1]];
|
|
const float4 color_shadow = link_uniforms.colors[color_ids[2]];
|
|
float line_thickness = link.thickness;
|
|
|
|
/* Each instance contains both the outline and the "main" line on top. */
|
|
constexpr int mid_vertex = 65;
|
|
bool is_outline_pass = gl_VertexID < mid_vertex;
|
|
|
|
interp_flat.line_thickness = line_thickness;
|
|
interp_flat.is_main_line = (expand.y == 1.0f && !is_outline_pass) ? 1 : 0;
|
|
interp_flat.has_back_link = int(link.has_back_link);
|
|
interp_flat.aspect = link_uniforms.aspect;
|
|
/* Parameters for the dashed line. */
|
|
interp_flat.dash_length = link.dash_length;
|
|
interp_flat.dash_factor = link.dash_factor;
|
|
interp_flat.dash_alpha = link.dash_alpha;
|
|
/* Approximate line length, no need for real bezier length calculation. */
|
|
interp_flat.line_length = distance(P0, P3);
|
|
/* TODO: Incorrect U, this leads to non-uniform dash distribution. */
|
|
interp.line_uv = uv;
|
|
|
|
if ((expand.y == 1.0f) && link.has_back_link) {
|
|
/* Increase width because two links are drawn. */
|
|
line_thickness *= 1.7f;
|
|
}
|
|
|
|
if (is_outline_pass) {
|
|
/* Outline pass. */
|
|
interp.final_color = color_shadow;
|
|
}
|
|
else {
|
|
/* Second pass. */
|
|
if (uv.x < start_gradient_threshold) {
|
|
interp.final_color = color_start;
|
|
}
|
|
else if (uv.x > end_gradient_threshold) {
|
|
interp.final_color = color_end;
|
|
}
|
|
else {
|
|
float mixFactor = (uv.x - start_gradient_threshold) /
|
|
(end_gradient_threshold - start_gradient_threshold);
|
|
interp.final_color = mix(color_start, color_end, mixFactor);
|
|
}
|
|
line_thickness *= 0.65f;
|
|
if (link.do_muted) {
|
|
interp.final_color[3] = 0.65f;
|
|
}
|
|
}
|
|
interp.final_color.a *= link.dim_factor;
|
|
|
|
float t = uv.x;
|
|
float t2 = t * t;
|
|
float t2_3 = 3.0f * t2;
|
|
float one_minus_t = 1.0f - t;
|
|
float one_minus_t2 = one_minus_t * one_minus_t;
|
|
float one_minus_t2_3 = 3.0f * one_minus_t2;
|
|
|
|
float2 point = (P0 * one_minus_t2 * one_minus_t + P1 * one_minus_t2_3 * t +
|
|
P2 * t2_3 * one_minus_t + P3 * t2 * t);
|
|
|
|
float2 tangent = ((P1 - P0) * one_minus_t2_3 + (P2 - P1) * 6.0f * (t - t2) + (P3 - P2) * t2_3);
|
|
|
|
/* Tangent space at t. If the inner and outer control points overlap, the tangent is invalid.
|
|
* Use the vector between the sockets instead. */
|
|
tangent = is_zero(tangent) ? normalize(P3 - P0) : normalize(tangent);
|
|
float2 normal = tangent.yx * float2(-1.0f, 1.0f);
|
|
|
|
/* Position vertex on the curve tangent space */
|
|
point += (pos.x * tangent + pos.y * normal) * link_uniforms.arrow_size;
|
|
|
|
gl_Position = ModelViewProjectionMatrix * float4(point, 0.0f, 1.0f);
|
|
|
|
float2 exp_axis = expand.x * tangent + expand.y * normal;
|
|
|
|
/* rotate & scale the expand axis */
|
|
exp_axis = ModelViewProjectionMatrix[0].xy * exp_axis.xx +
|
|
ModelViewProjectionMatrix[1].xy * exp_axis.yy;
|
|
|
|
float expand_dist = line_thickness * (uv.y * 2.0f - 1.0f);
|
|
|
|
/* Expand into a line */
|
|
gl_Position.xy += exp_axis * link_uniforms.aspect * expand_dist;
|
|
|
|
/* If the link is not muted or is not a reroute arrow the points are squashed to the center of
|
|
* the line. Magic numbers are defined in `drawnode.cc`. */
|
|
if ((expand.x == 1.0f && !link.do_muted) ||
|
|
(expand.y != 1.0f && (pos.x < 0.70f || pos.x > 0.71f) && !link.do_arrow))
|
|
{
|
|
gl_Position.xy *= 0.0f;
|
|
}
|
|
}
|