1

我正在尝试在 GPU 上为一个简单的球体应用细分。这种镶嵌非常适合简单的计划,但不适用于球体。当然,我知道坐标映射不一样,我尝试了很多方法来做到这一点。例如,我尝试在曲面细分评估中使用 gl_TessCoord(x 和 y)作为映射到平面的经度和纬度。然后将它们转换为球坐标,但它“真的”没有用。

对于镶嵌控制,我只是将所有补丁分成 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; 
}

为了绘制球体,我遵循了这个例子:使用 Visual C++ 在 Opengl 中创建一个 3D 球体,所以所有的功劳都归于他(顺便谢谢你!)。

这是显示结果的两张图片:

拳头形象 在此处输入图像描述

如果您有任何可以帮助我解决此问题的提示,那就太好了。谢谢你。注意:如果您需要任何其他信息,请询问我,我会发布它们。

4

1 回答 1

0

似乎您只取第一个顶点(位于球体上),然后仅通过 gl_TessCoord.xy 水平偏移(在 xz 平面上):

vec4 position = gl_in[0].gl_Position;
position.xz += gl_TessCoord.xy * 2.0 - 1.0; 

由于您正在制作四边形,因此您需要gl_in4 个点。你只对前三个感兴趣。因此,您的最终位置可以通过以下方式进行插值:

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);

来源

那应该可以解决您的问题。

PS 对于法线,请执行以下操作(如果您的球体围绕原点生成):

vec3 normal = mat3x3(viewMatrix*transformMatrix) * normalize(position.xyz);
于 2015-04-14T17:09:10.533 回答