Files
test2/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl
Jacques Lucke cb795cc13a Cleanup: repeated typo
This changes `ouput`  to `output`.

Pull Request: https://projects.blender.org/blender/blender/pulls/139711
2025-06-02 08:36:43 +02:00

217 lines
6.9 KiB
GLSL

/* SPDX-FileCopyrightText: 2020-2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "infos/gpu_shader_3D_polyline_info.hh"
#include "gpu_shader_attribute_load_lib.glsl"
#include "gpu_shader_index_load_lib.glsl"
#include "gpu_shader_math_base_lib.glsl"
#include "gpu_shader_utildefines_lib.glsl"
VERTEX_SHADER_CREATE_INFO(gpu_shader_3D_polyline_flat_color)
struct VertIn {
float3 ls_P;
float4 final_color;
};
VertIn input_assembly(uint in_vertex_id)
{
uint v_i = gpu_index_load(in_vertex_id);
uint ofs = uint(gpu_vert_stride_count_offset.z);
VertIn vert_in;
vert_in.ls_P = float3(0.0f, 0.0f, 0.0f);
/* Need to support 1, 2 and 3 dimensional input (sigh). */
vert_in.ls_P.x = pos[gpu_attr_load_index(v_i, gpu_attr_0) + 0 + ofs];
if (gpu_attr_0_len >= 2) {
vert_in.ls_P.y = pos[gpu_attr_load_index(v_i, gpu_attr_0) + 1 + ofs];
}
if (gpu_attr_0_len >= 3) {
vert_in.ls_P.z = pos[gpu_attr_load_index(v_i, gpu_attr_0) + 2 + ofs];
}
if (gpu_attr_0_fetch_int) {
vert_in.ls_P = float3(floatBitsToInt(vert_in.ls_P));
}
#ifndef UNIFORM
vert_in.final_color = float4(0.0f, 0.0f, 0.0f, 1.0f);
/* Need to support 1, 2, 3 and 4 dimensional input (sigh). */
vert_in.final_color.x = color[gpu_attr_load_index(v_i, gpu_attr_1) + 0 + ofs];
if (gpu_attr_1_fetch_unorm8) {
vert_in.final_color = unpackUnorm4x8(floatBitsToUint(vert_in.final_color.x));
}
else {
if (gpu_attr_1_len >= 2) {
vert_in.final_color.y = color[gpu_attr_load_index(v_i, gpu_attr_1) + 1 + ofs];
}
if (gpu_attr_1_len >= 3) {
vert_in.final_color.z = color[gpu_attr_load_index(v_i, gpu_attr_1) + 2 + ofs];
}
if (gpu_attr_1_len >= 4) {
vert_in.final_color.w = color[gpu_attr_load_index(v_i, gpu_attr_1) + 3 + ofs];
}
}
#endif
return vert_in;
}
struct VertOut {
float4 gpu_position;
float4 final_color;
float clip;
};
VertOut vertex_main(VertIn vert_in)
{
VertOut vert_out;
vert_out.gpu_position = ModelViewProjectionMatrix * float4(vert_in.ls_P, 1.0f);
#ifndef UNIFORM
vert_out.final_color = vert_in.final_color;
#endif
#ifdef CLIP
vert_out.clip = dot(ModelMatrix * float4(vert_in.ls_P, 1.0f), ClipPlane);
#endif
return vert_out;
}
/* Clips point to near clip plane before perspective divide. */
float4 clip_line_point_homogeneous_space(float4 p, float4 q)
{
if (p.z < -p.w) {
/* Just solves p + (q - p) * A; for A when p.z / p.w = -1.0f. */
float denom = q.z - p.z + q.w - p.w;
if (denom == 0.0f) {
/* No solution. */
return p;
}
float A = (-p.z - p.w) / denom;
p = p + (q - p) * A;
}
return p;
}
struct GeomOut {
float4 gpu_position;
float4 final_color;
float clip;
float smoothline;
};
void export_vertex(GeomOut geom_out)
{
gl_Position = geom_out.gpu_position;
final_color = geom_out.final_color;
smoothline = geom_out.smoothline;
clip = geom_out.clip;
}
void strip_EmitVertex(const uint strip_index,
uint out_vertex_id,
uint out_primitive_id,
GeomOut geom_out)
{
bool is_odd_primitive = (out_primitive_id & 1u) != 0u;
/* Maps triangle list primitives to triangle strip indices. */
uint out_strip_index = (is_odd_primitive ? (2u - out_vertex_id) : out_vertex_id) +
out_primitive_id;
if (out_strip_index == strip_index) {
export_vertex(geom_out);
}
}
void do_vertex(const uint i,
uint out_vertex_id,
uint out_primitive_id,
VertOut geom_in[2],
float4 position,
float2 ofs)
{
GeomOut geom_out;
#if defined(UNIFORM)
geom_out.final_color = color;
#elif defined(FLAT)
/* WATCH: Assuming last provoking vertex. */
geom_out.final_color = geom_in[1].final_color;
#elif defined(SMOOTH)
geom_out.final_color = geom_in[i].final_color;
#endif
#ifdef CLIP
geom_out.clip = geom_in[i].clip;
#endif
geom_out.smoothline = (lineWidth + SMOOTH_WIDTH * float(lineSmooth)) * 0.5f;
geom_out.gpu_position = position;
geom_out.gpu_position.xy += ofs * position.w;
strip_EmitVertex(i * 2u + 0u, out_vertex_id, out_primitive_id, geom_out);
geom_out.smoothline = -(lineWidth + SMOOTH_WIDTH * float(lineSmooth)) * 0.5f;
geom_out.gpu_position = position;
geom_out.gpu_position.xy -= ofs * position.w;
strip_EmitVertex(i * 2u + 1u, out_vertex_id, out_primitive_id, geom_out);
}
void geometry_main(VertOut geom_in[2],
uint out_vertex_id,
uint out_primitive_id,
uint out_invocation_id)
{
float4 p0 = clip_line_point_homogeneous_space(geom_in[0].gpu_position, geom_in[1].gpu_position);
float4 p1 = clip_line_point_homogeneous_space(geom_in[1].gpu_position, geom_in[0].gpu_position);
float2 e = normalize(((p1.xy / p1.w) - (p0.xy / p0.w)) * viewportSize.xy);
#if 0 /* Hard turn when line direction changes quadrant. */
e = abs(e);
float2 ofs = (e.x > e.y) ? float2(0.0f, 1.0f / e.x) : float2(1.0f / e.y, 0.0f);
#else /* Use perpendicular direction. */
float2 ofs = float2(-e.y, e.x);
#endif
ofs /= viewportSize.xy;
ofs *= lineWidth + SMOOTH_WIDTH * float(lineSmooth);
do_vertex(0u, out_vertex_id, out_primitive_id, geom_in, p0, ofs);
do_vertex(1u, out_vertex_id, out_primitive_id, geom_in, p1, ofs);
}
void main()
{
/* Line list primitive. */
uint input_primitive_vertex_count = uint(gpu_vert_stride_count_offset.x);
/* Triangle list primitive (emulating triangle strip). */
constexpr uint output_primitive_vertex_count = 3u;
constexpr uint output_primitive_count = 2u;
constexpr uint output_invocation_count = 1u;
constexpr uint output_vertex_count_per_invocation = output_primitive_count *
output_primitive_vertex_count;
constexpr uint output_vertex_count_per_input_primitive = output_vertex_count_per_invocation *
output_invocation_count;
uint in_primitive_id = uint(gl_VertexID) / output_vertex_count_per_input_primitive;
uint in_primitive_first_vertex = in_primitive_id * input_primitive_vertex_count;
uint out_vertex_id = uint(gl_VertexID) % output_primitive_vertex_count;
uint out_primitive_id = (uint(gl_VertexID) / output_primitive_vertex_count) %
output_primitive_count;
uint out_invocation_id = (uint(gl_VertexID) / output_vertex_count_per_invocation) %
output_invocation_count;
/* Used to wrap around for the line loop case. */
uint input_total_vertex_count = uint(gpu_vert_stride_count_offset.y);
VertIn vert_in[2];
vert_in[0] = input_assembly(in_primitive_first_vertex + 0u);
vert_in[1] = input_assembly((in_primitive_first_vertex + 1u) % input_total_vertex_count);
VertOut vert_out[2];
vert_out[0] = vertex_main(vert_in[0]);
vert_out[1] = vertex_main(vert_in[1]);
/* Discard by default. */
gl_Position = float4(NAN_FLT);
geometry_main(vert_out, out_vertex_id, out_primitive_id, out_invocation_id);
}