我的曲面细分着色器为两个顶点生成贝塞尔曲线。 顶点由两个坐标x和y(vec2)组成。 现在每个顶点都有一个颜色。 我的问题:如何在生成的曲线上插入每个顶点的颜色? 现在片段着色器设置默认颜色值(红色)。 但我希望他得到插值颜色。
例如:
vertex 1 [vec2(0.0, 0.0), vec4(1.0, 0.0, 0.0, 1.0)] // red
vertex 2 [vec2(1.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0)] // blue
因此应该有从红色到蓝色的渐变。 如何使用曲面细分着色器执行此操作?
顶点着色器:
#version 400
layout (location = 0 ) in vec2 in_position;
layout (location = 1 ) in vec4 in_color;
void main()
{
gl_Position = vec4(in_position, 0.0, 1.0);
}
曲面细分控制着色器:
#version 400
layout( vertices = 2 ) out;
uniform int NumSegments;
uniform int NumStrips;
void main()
{
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
gl_TessLevelOuter[0] = float(NumSegments);
gl_TessLevelOuter[1] = float(NumStrips);
}
曲面细分评估着色器:
#version 400
layout( isolines ) in;
uniform mat4 Projection;
uniform mat4 Modelview;
void main()
{
float u = gl_TessCoord.x;
vec3 p0 = gl_in[0].gl_Position.xyz;
vec3 p1 = vec3(0.5, gl_in[0].gl_Position.y, 0.0);
vec3 p2 = vec3(0.5, gl_in[1].gl_Position.y, 0.0);
vec3 p3 = gl_in[1].gl_Position.xyz;
float u1 = (1.0 - u);
float u2 = u * u;
// Bernstein polynomials
float b3 = u2 * u;
float b2 = 3.0 * u2 * u1;
float b1 = 3.0 * u * u1 * u1;
float b0 = u1 * u1 * u1;
// Cubic Bezier interpolation
vec3 p = p0 * b0 + p1 * b1 + p2 * b2 + p3 * b3;
gl_Position = Projection * Modelview * vec4(p, 1.0);
}
片段着色器:
#version 400
layout ( location = 0 ) out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
答案 0 :(得分:1)
这一切都非常简单。只需遵循现有输入和输出的模式。
您的顶点着色器输出gl_Position
值。因此,它还应输出颜色值:
layout (location = 0 ) in vec2 in_position;
layout (location = 1 ) in vec4 in_color;
out vec4 color;
void main()
{
gl_Position = vec4(in_position, 0.0, 1.0);
color = in_color;
}
您的细分控制着色器采用gl_Position
个数组。所以你采取一系列颜色。它还需要写入一组颜色:
layout( vertices = 2 ) out;
uniform int NumSegments;
uniform int NumStrips;
in vec4 color[];
out Tess
{
vec4 color;
} Out[];
void main()
{
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
Out[gl_InvocationID].color = color[gl_InvocationID];
gl_TessLevelOuter[0] = float(NumSegments);
gl_TessLevelOuter[1] = float(NumStrips);
}
在评估着色器中,您还需要获取一组输入和输出布局限定符。我们使用了一个名为Tess
的输出接口块,因此我们需要将它与同名的输入接口块匹配:
layout( isolines ) in;
uniform mat4 Projection;
uniform mat4 Modelview;
in Tess
{
vec4 color;
} In[];
out vec4 color;
void main()
{
float u = gl_TessCoord.x;
/** Do whatever interpolation stuff you do **/
// Cubic Bezier interpolation
vec3 p = p0 * b0 + p1 * b1 + p2 * b2 + p3 * b3;
gl_Position = Projection * Modelview * vec4(p, 1.0);
color = Interpolate(In[0].color, In[1].color, ...); //More interpolation stuff.
}
就是这样。您的片段着色器将vec4 color
作为输入。
另外,小记:这不是Bezier样条。 Bezier样条曲线需要4个位置的补丁,而不是2.你合成其他两个值的方法并不能使它们正确。