2011-11-10 21 views
0

テッセレーションシェーダは、2つの頂点のベジェ曲線を生成します。 頂点は2つの座標xとy(vec2)で構成されます。 すべての頂点に色が付いています。 私の質問:どのように生成された曲線上の頂点ごとの色を補間するのですか? フラグメントシェーダはデフォルトのカラー値(赤色)を設定します。 しかし、彼は補間された色を取得したい。例えばGLSLカラーテッセレーションシェーダの補間

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

'vs_alpha'と' in_alpha'とは何ですか? –

+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を取ります。

また、小さなメモ:これはベジェスプラインではありません。ベジェスプラインは、2つの位置ではなく4つの位置のパッチを必要とします。他の2つの値を合成した方法では、それらの値が正しいとは限りません。