0

私のテッセレーション シェーダーは、2 つの頂点のベジェ曲線を生成します。頂点は 2 つの座標 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);
}
4

1 に答える 1

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.
}

そして、それはそれです。フラグメント シェーダーは入力として a を受け取りますvec4 color

また、小さな注意: これはベジェ スプラインではありません。ベジェ スプラインには、2 箇所ではなく 4 箇所のパッチが必要です。他の 2 つの値を合成した方法では、それらが正しくなりません。

于 2012-03-06T02:12:51.200 に答える