在我最近的項目中我正在使用硬件方面鑲嵌。我想要實施的管道應採用低多邊形網格,鑲嵌它並應用位移貼圖。GLSL Tessellation位移映射
Tessellation工作正常,正如我預期的那樣。但是,當我在鑲嵌評估着色器中應用位移貼圖時,我得到的輸出有點隨機。
這是沒有移位輸出(我用的高度圖作爲紋理來驗證我的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;
}
// TESS CONTROL
#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;
}
// GEOMETRY
#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();
}
// FRAGMENT
#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);
}
}
如果有人能夠幫助我,那該多好。
不應該產生的位移始終從給予unorm紋理(現在你有其中位移出現移動的部分地區表面朝外頂點***內的***圓柱體)?我強烈懷疑TES中的正常計算有問題。也許你可以將你在TES中計算的正常值傳遞給geometry/fragment並將其可視化,看看它是否正確? –
事實上:輸出'gFacetNormal'只是爲幾何着色器中的第一個頂點定義的。根據GLSL規範,必須在每個'EmitVertex(...)'之後設置輸出,否則它們將不確定。許多實現重用了最後一個值集,但如果您希望它可以輕鬆地工作,則不能依賴此行爲。您需要在每個「EmitVertex」之前設置一次'gFacetNormal'。 *'void EmitVertex()' - 「將輸出變量的當前值發送到當前輸出原語。返回此調用時,輸出變量的值未定義。」* –
感謝您的建議!我不會認爲這會做到這一點,但實際上它確實是一切毀掉了一切的'gFacetNormal'。 我將編寫其他有興趣實現例程的代碼。 –