【问题标题】:Sphere Tessellation wrong coordinatesSphere Tessellation 坐标错误
【发布时间】:2015-04-14 16:38:41
【问题描述】:

我正在尝试在 GPU 上为简单的 Sphere 应用细分。这种镶嵌非常适合简单的计划,但不适用于球体。当然,我知道坐标映射不一样,我尝试了很多方法来做到这一点。例如,我尝试在曲面细分评估中使用 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; 
}

为了绘制球体,我遵循了这个例子:Creating a 3D sphere in Opengl using Visual C++ 所以所有的功劳都归他所有(顺便谢谢你!)。

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

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

【问题讨论】:

    标签: opengl tessellation


    【解决方案1】:

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

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

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

    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)

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

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

    vec3 normal = mat3x3(viewMatrix*transformMatrix) * normalize(position.xyz);
    

    【讨论】:

    • 嗨,我假设你想说gl_in[n].gl_Position?我去试试,谢谢你的回答。我会让你知道结果
    • 是的,抱歉,我有点着急。希望你明白:) 我会编辑我的答案
    • 此外,极点上可能存在错误,因为通常存在退化的四边形。基于四边形生成球体不是一个好主意。更好的方法是用一个二十面体作为底面,然后细分三角形。
    • Here's something on that - 这就是所谓的地球圈。
    • 当我使用你的解决方案时,它在 Z 轴上产生了一些奇怪的坐标,所以我认为它没有映射到好的 gl_ingl_in[2] 用于ygl_in[3] 用于zgl_in[0]or[1] 用于x 轴,现在它正在生成这个:imgur.com/11VYcTC 差不多了!我猜它与指数有关,你知道吗?谢谢你的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多