최근 프로젝트에서 하드웨어 쪽 테셀레이션으로 작업하고 있습니다. 구현하고자하는 파이프 라인은 낮은 폴리 메쉬를 가져 와서 테셀레이션하고 변위 맵을 적용해야합니다.GLSL 테셀레이션 변위 매핑
테셀레이션은 잘 작동하고 잘 보이는 것처럼 보입니다. 그러나 테셀레이션 평가 쉐이더에서 변위 맵을 적용 할 때 어느 정도 랜덤 한 출력을 얻습니다.
이
는 변위없이 출력이 내가 같은 질감을 사용하여 (내 변위를 활성화 할 때 내가 무엇을 얻을(내 texCoords이 정확한지 여부를 확인하기 위해 텍스처로 하이트를 사용)입니다 착색 변위) 모두 :
는
셰이더 코드는 다음과 같다 : 012
3,516,// 정점 셰이더
#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);
}
}
누군가 나를 도와 줄 수 있으면 좋을 것입니다. @ AndonM.Coleman에
항상 변위가 이동할 것으로 보인다 일부 지역이 지금의 (a unorm 질감을 주어 표면에서 바깥쪽으로 향하게 변위 안 꼭지점 *** *** 실린더 안쪽)? 나는 TES에서 당신의 정상적인 계산에 문제가 있다고 생각합니다. 아마도 TES에서 계산 한 법선을 기하학/조각으로 전달하고 시각화하여 올바른 것으로 보았습니까? –
사실 : 출력 'gFacetNormal'은 기하 구조 쉐이더의 첫 번째 정점에 대해서만 정의됩니다. GLSL 명세에 따라'EmitVertex (...) '마다 출력을 설정해야합니다. 그렇지 않으면 정의되지 않습니다. 대부분의 구현에서는 마지막 값 세트를 다시 사용하지만이 동작을 이식 가능하게하려면이 동작에 의존 할 수 없습니다. 'EmitVertex' 전에'gFacetNormal'을 한 번 설정해야합니다. *'void EmitVertex()'- "현재 출력 프리미티브에 출력 변수의 현재 값을 내 보냅니다.이 호출에서 돌아 왔을 때 출력 변수의 값은 정의되지 않았습니다."* –
조언 주셔서 감사합니다 !!! 나는 이것이 트릭을 할 것이라고 생각하지 않았지만 실제로는 모든 것을 파열시킨 'gFacetNormal '이었다. 루틴을 구현하는 데 관심이있는 모든 사람들을 위해 코드를 편집합니다. –