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
217 lines
6.9 KiB
GLSL
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_infos.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);
|
|
}
|