6

私の最近のプロジェクトでは、ハードウェア側のテッセレーションに取り組んでいます。実装したいパイプラインは、低ポリ メッシュを取得し、それをテッセレーションして、ディスプレイスメント マップを適用する必要があります。

テッセレーションは正常に機能し、期待どおりに見えます。ただし、テッセレーション評価シェーダーでディスプレイスメント マップを適用すると、多少ランダムな出力が得られます。

これはディスプレイスメントなしの出力です (高さマップをテクスチャとして使用して、texCoords が正確かどうかを確認しました)

ここに画像の説明を入力

これは、ディスプレイスメントを有効にすると得られるものです (カラーリングとディスプレイスメントの両方に同じテクスチャを使用)。

ここに画像の説明を入力

シェーダー コードは次のとおりです。

//頂点シェーダー

#version 430

layout(location = 0) in vec4 vertex;
layout(location = 1) in vec4 normal;
layout(location = 2) in vec2 texCoord;

out vec3 vPosition;
out vec3 vNormal;
out vec2 vTexCoord;

void main() {
    vPosition = vertex.xyz;
    vNormal = normal.xyz;
    vTexCoord = texCoord;
}

//テスコントロール

#version 430

layout(vertices = 3) out;

in vec3 vPosition[];
in vec3 vNormal[];
in vec2 vTexCoord[];
out vec3 tcPosition[];
out vec3 tcNormal[];
out vec2 tcTexCoord[];

uniform float innerTessLevel;
uniform float outerTessLevel;

void main(){

    float inTess  = innerTessLevel;
    float outTess = outerTessLevel;

    tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
    tcNormal[gl_InvocationID]   = vNormal[gl_InvocationID];
    tcTexCoord[gl_InvocationID] = vTexCoord[gl_InvocationID];
    if(gl_InvocationID == 0) {
        gl_TessLevelInner[0] = inTess;
        gl_TessLevelInner[1] = inTess;
        gl_TessLevelOuter[0] = outTess;
        gl_TessLevelOuter[1] = outTess;
        gl_TessLevelOuter[2] = outTess;
        gl_TessLevelOuter[3] = outTess;
    }
}

//TESS EVAL

#version 430

layout(triangles, equal_spacing, ccw) in;

in vec3 tcPosition[];
in vec3 tcNormal[];
in vec2 tcTexCoord[];
out vec3 tePosition;
out vec2 teTexCoord;

uniform mat4 ModelViewProjection;
uniform mat4 ModelView;

uniform sampler2D texHeight;

void main(){
    vec3 p0 = gl_TessCoord.x * tcPosition[0];
    vec3 p1 = gl_TessCoord.y * tcPosition[1];
    vec3 p2 = gl_TessCoord.z * tcPosition[2];
    vec3 pos = p0 + p1 + p2;

    vec3 n0 = gl_TessCoord.x * tcNormal[0];
    vec3 n1 = gl_TessCoord.y * tcNormal[1];
    vec3 n2 = gl_TessCoord.z * tcNormal[2];
    vec3 normal = normalize(n0 + n1 + n2);

    vec2 tc0 = gl_TessCoord.x * tcTexCoord[0];
    vec2 tc1 = gl_TessCoord.y * tcTexCoord[1];
    vec2 tc2 = gl_TessCoord.z * tcTexCoord[2];  
    teTexCoord = tc0 + tc1 + tc2;

    float height = texture(texHeight, teTexCoord).x;
    pos += normal * (height * 0.2f);

    gl_Position = ModelViewProjection * vec4(pos, 1);
    tePosition = vec3(ModelView * vec4(pos,1.0)).xyz;
}

//ジオメトリ

#version 430

layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

uniform mat4 ModelView;

in vec3 tePosition[3];
in vec3 tePatchDistance[3];
in vec2 teTexCoord[3];
out vec3 gFacetNormal;
out vec2 gTexCoord;

void main() {
    vec3 A = tePosition[2] - tePosition[0];
    vec3 B = tePosition[1] - tePosition[0];
    vec4 N = vec4( normalize(cross(A, B)) , 0.0);
    gFacetNormal = N.xyz;

    gTexCoord = teTexCoord[0];
    gl_Position = gl_in[0].gl_Position; EmitVertex();

    gTexCoord = teTexCoord[1];
    gl_Position = gl_in[1].gl_Position; EmitVertex();

    gTexCoord = teTexCoord[2];
    gl_Position = gl_in[2].gl_Position; EmitVertex();

    EndPrimitive();
}

//断片

#version 430

layout(location = 0) out vec4 fragColor;

in vec3 gFacetNormal;
in vec2 gTexCoord;

uniform float lit;
uniform vec3 light;
uniform sampler2D texHeight;

void main() {
    #ifndef ORANGE_PURPLE
        vec3 color = gl_FrontFacing ? vec3(1.0,0.0,0.0) : vec3(0.0,0.0,1.0);
    #else
        vec3 color = gl_FrontFacing ? vec3(1.0,0.6,0.0) : vec3(0.6,0.0,1.0);
    #endif
    if (lit > 0.5) {
        color = texture(texHeight, gTexCoord).xyz; 
        vec3 N = normalize(gFacetNormal);
        vec3 L = light;
        float df = abs(dot(N,L));
        color = df * color;

        fragColor = vec4(color,1.0);
    }
    else {
        fragColor = vec4(color,1.0);
    }
}

誰かが私を助けてくれたらいいのにと思います。

4

1 に答える 1