Рисование связанных линий в OpenGL / GLSL

Я рендеринг некоторых циклов LineLoop на сфере (граничит с планетой) и хочу перетянуть их в более короткие линии, чтобы предотвратить попадание длинных линий в сферу.
Пример:
введите описание изображения здесь

Вот мой текущий исходный код:
C ++ Draw Call:

void Border::Draw() const
{
glBindVertexArray(_vao);

glPatchParameteri(GL_PATCH_VERTICES, 2);
glDrawArrays(GL_PATCHES, 0, _size);

glBindVertexArray(0);
}

Вершинный шейдер:

#version 400

in layout(location = 0) vec3 position;

void main()
{
gl_Position = vec4(position, 1.0);
}

Tessallation Control Shader:

#version 400

layout (vertices = 2) out;

void main()
{
if(gl_InvocationID == 0)
{
//get the distance between two points
float dist = length(gl_in[0].gl_Position - gl_in[1].gl_Position);
gl_TessLevelOuter[0] = 1;
//divide line in segments of size 1.0
gl_TessLevelOuter[1] = abs(dist);
}

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

Tessallation Evaluation Shader

#version 400

layout (isolines, equal_spacing) in;

uniform float planetRadius;
uniform mat4 view;
uniform mat4 projection;

void main()
{
vec4 p = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);

//offset point so it is on the spheres surface
p = normalize(p);
p *= planetRadius;

gl_Position = projection * view * p;
}

Фрагмент шейдера:

#version 400

out vec4 outColor;

void main()
{
outColor = vec4(1.0, 1.0, 1.0, 1.0);
}

Тессалляция, похоже, не работает, как я ожидаю, что она сработает (документация на изолинии тоже плохая).

Вот как это выглядело, когда я рисовал его с помощью LineLoops и только Vertex / Fragment Shader:

введите описание изображения здесь

и вот так это выглядит после того, как я реализовал свой tessallation:

введите описание изображения здесь

Линии также не выглядят сложными и имеют ту же длину, что и раньше.

Привет Джонни

Редактировать:
Нашел решение сам. Посмотрите в разделе ответов ниже, чтобы увидеть это.

2

Решение

Я нашел решение. Проблема заключается в неспособности тессалляционных шейдеров рисовать линейные полосы. Так что, если у вас есть линия полосы, определяемая точками {p1, p2, p3, p4, p5, p6} он рисует линии между:
p1 -> p2
p3 -> p4
p5 -> p6

Я исправил это, дав шейдеру каждую точку 2 раза, поэтому мой список выглядит так:
{p1, p2, p2, p3, p3, p4, p4, p5, p5, p6, p6, p1}
Тессалляционный шейдер создает следующие строки:
p1 -> p2
p2 -> p3
p3 -> p4
p4 -> p5
p5 -> p6
p6 -> p1

Мои шейдеры теперь выглядят так:

TessControl:

#version 430

layout (vertices = 2) out;

void main()
{
if(gl_InvocationID == 0)
{
float dist = length(gl_in[0].gl_Position.xyz - gl_in[1].gl_Position.xyz);

gl_TessLevelOuter[0] = 1;
gl_TessLevelOuter[1] = dist;
}

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

TessEval:

#version 430

layout (isolines, equal_spacing) in;

uniform float planetRadius;
uniform mat4 view;
uniform mat4 projection;

void main()
{
//only interpolate and normalize xyz coordinates. Thanks to @aslg
vec3 p = mix(gl_in[0].gl_Position.xyz, gl_in[1].gl_Position.xyz, gl_TessCoord.x);

p = normalize(p);
p *= planetRadius;

gl_Position = projection * view * vec4(p, 1.0);
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]