Sphere Tessellation 坐标错误
Sphere Tessellation wrong coordinates
我正在尝试在 GPU 上为一个简单的球体应用曲面细分。这种镶嵌非常适合简单的平面图,但不适用于球体。当然,我知道坐标映射不一样,我尝试了很多方法。例如,我尝试在曲面细分评估中使用 gl_TessCoord(x 和 y)作为映射到平面的经度和纬度。然后将它们转换为球坐标,但它 'really' 不起作用。
对于曲面细分控件,我只是将所有面片分成 2 个用于外部层级,2 个也用于内部层级。
这是我绘制球体的代码:
glBindVertexArray(vertexArrayObject);
glPatchParameteri(GL_PATCH_VERTICES, 4);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glDrawElements(GL_PATCHES, indices.length, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
这是我当前在细分评估中的代码:
#version 430
layout(quads, fractional_even_spacing, ccw) in;
uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;
uniform mat4 u_transformMatrix;
uniform float u_radius;
uniform vec3 u_cameraPosition;
void main(void){
vec4 position = gl_in[0].gl_Position;
position.xz += gl_TessCoord.xy * 2.0 - 1.0;
gl_Position = u_projectionMatrix * u_viewMatrix * u_transformMatrix * position;
}
索引如下:
int indPtr = 0;
for(int r=0; r< mRings-1; r++)
for(int s=0; s<mSectors-1; s++){
indices[indPtr++] = r * mSectors + s;
indices[indPtr++] = r * mSectors + (s+1);
indices[indPtr++] = (r+1) * mSectors + (s+1);
indices[indPtr++] = (r+1) * mSectors + s;
}
为了绘制球体,我遵循了这个例子:Creating a 3D sphere in Opengl using Visual C++ 所以所有的功劳都归于他(顺便谢谢你!)。
这是显示结果的两张图片:
如果您有任何提示可以帮助我解决这个问题,那就太好了。谢谢你。
注意:如果您需要任何其他信息,请询问我,我会 post 他们。
好像你只取了第一个顶点(位于球体上)然后仅水平偏移它(在 xz 平面上)gl_TessCoord.xy:
vec4 position = gl_in[0].gl_Position;
position.xz += gl_TessCoord.xy * 2.0 - 1.0;
由于您要生成四边形,因此您需要 gl_in
个大小为 4 的点。您只对前三个感兴趣。所以你的最终位置可以这样插值:
vec4 a = mix(gl_in[1].gl_Position, gl_in[0].gl_Position, gl_TessCoord.x);
vec4 b = mix(gl_in[2].gl_Position, gl_in[3].gl_Position, gl_TessCoord.x);
gl_Position = projectionMatrix * viewMatrix * transformMatrix * mix(a, b, gl_TessCoord.y);
(source)
这应该可以解决您的问题。
P.S。对于法线,执行以下操作(如果您的球体是围绕原点生成的):
vec3 normal = mat3x3(viewMatrix*transformMatrix) * normalize(position.xyz);
我正在尝试在 GPU 上为一个简单的球体应用曲面细分。这种镶嵌非常适合简单的平面图,但不适用于球体。当然,我知道坐标映射不一样,我尝试了很多方法。例如,我尝试在曲面细分评估中使用 gl_TessCoord(x 和 y)作为映射到平面的经度和纬度。然后将它们转换为球坐标,但它 'really' 不起作用。
对于曲面细分控件,我只是将所有面片分成 2 个用于外部层级,2 个也用于内部层级。
这是我绘制球体的代码:
glBindVertexArray(vertexArrayObject);
glPatchParameteri(GL_PATCH_VERTICES, 4);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glDrawElements(GL_PATCHES, indices.length, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
这是我当前在细分评估中的代码:
#version 430
layout(quads, fractional_even_spacing, ccw) in;
uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;
uniform mat4 u_transformMatrix;
uniform float u_radius;
uniform vec3 u_cameraPosition;
void main(void){
vec4 position = gl_in[0].gl_Position;
position.xz += gl_TessCoord.xy * 2.0 - 1.0;
gl_Position = u_projectionMatrix * u_viewMatrix * u_transformMatrix * position;
}
索引如下:
int indPtr = 0;
for(int r=0; r< mRings-1; r++)
for(int s=0; s<mSectors-1; s++){
indices[indPtr++] = r * mSectors + s;
indices[indPtr++] = r * mSectors + (s+1);
indices[indPtr++] = (r+1) * mSectors + (s+1);
indices[indPtr++] = (r+1) * mSectors + s;
}
为了绘制球体,我遵循了这个例子:Creating a 3D sphere in Opengl using Visual C++ 所以所有的功劳都归于他(顺便谢谢你!)。
这是显示结果的两张图片:
如果您有任何提示可以帮助我解决这个问题,那就太好了。谢谢你。 注意:如果您需要任何其他信息,请询问我,我会 post 他们。
好像你只取了第一个顶点(位于球体上)然后仅水平偏移它(在 xz 平面上)gl_TessCoord.xy:
vec4 position = gl_in[0].gl_Position;
position.xz += gl_TessCoord.xy * 2.0 - 1.0;
由于您要生成四边形,因此您需要 gl_in
个大小为 4 的点。您只对前三个感兴趣。所以你的最终位置可以这样插值:
vec4 a = mix(gl_in[1].gl_Position, gl_in[0].gl_Position, gl_TessCoord.x);
vec4 b = mix(gl_in[2].gl_Position, gl_in[3].gl_Position, gl_TessCoord.x);
gl_Position = projectionMatrix * viewMatrix * transformMatrix * mix(a, b, gl_TessCoord.y);
(source)
这应该可以解决您的问题。
P.S。对于法线,执行以下操作(如果您的球体是围绕原点生成的):
vec3 normal = mat3x3(viewMatrix*transformMatrix) * normalize(position.xyz);