opengl GLSL Tessandem Shader为每个面片绘制不同方向的三角形

3ks5zfa0  于 2024-01-07  发布在  其他
关注(0)|答案(1)|浏览(218)

我正在OpenGL上使用TesskingShaders和补丁构建一个简单的地形,但是我对OpenGL如何绘制这些补丁感到困惑。OpenGL生成的三角形在每个补丁的不同方向上绘制,如图所示。
Difference between triangles of neighbour patches
Overview of different patches
我想知道是否有一个简单的方法来解决这个问题,比如使用OpenGL内置参数,或者有必要手动重新定位三角形。
我用的是OpenGL 4.0。我总共创建了8个补丁,我的tessLevel设置为64。
现在,我的代码是这样的:

纹理控制着色器

  1. #version 400
  2. layout (vertices = 4) out;
  3. uniform int tessLevel;
  4. #define ID gl_InvocationID
  5. void Preset();
  6. void main()
  7. {
  8. gl_out[ID].gl_Position = gl_in[ID].gl_Position;
  9. if (ID == 0)
  10. {
  11. Preset();
  12. }
  13. }
  14. void Preset()
  15. {
  16. gl_TessLevelOuter[0] = tessLevel;
  17. gl_TessLevelOuter[1] = tessLevel;
  18. gl_TessLevelOuter[2] = tessLevel;
  19. gl_TessLevelOuter[3] = tessLevel;
  20. gl_TessLevelInner[0] = tessLevel;
  21. gl_TessLevelInner[1] = tessLevel;
  22. }

字符串

纹理评估着色器

  1. #version 400
  2. layout(quads, equal_spacing, cw) in;
  3. uniform vec3 lightPos;
  4. out vec3 tesLightDirection;
  5. vec4 CalculateInterpolatedPosition(float u, float v);
  6. void main()
  7. {
  8. float u = gl_TessCoord.x;
  9. float v = gl_TessCoord.y;
  10. vec4 interpolatedPosition = CalculateInterpolatedPosition(u, v);
  11. tesLightDirection = normalize(lightPos - interpolatedPosition.xyz);
  12. gl_Position = interpolatedPosition;
  13. }
  14. vec4 CalculateInterpolatedPosition(float u, float v)
  15. {
  16. vec4 p0 = gl_in[0].gl_Position;
  17. vec4 p1 = gl_in[1].gl_Position;
  18. vec4 p2 = gl_in[2].gl_Position;
  19. vec4 p3 = gl_in[3].gl_Position;
  20. return p0 * (1 - u) * (1 - v) +
  21. p1 * u * (1 - v) +
  22. p3 * v * (1 - u) +
  23. p2 * u * v;
  24. }


在我的C++程序中,我的补丁是以以下方式构建的:

  1. void Terrain::GenerateVertices()
  2. {
  3. for (int i = 0; i < totalPatches + 1; i++)
  4. {
  5. for (int j = 0; j < totalPatches + 1; j++)
  6. {
  7. vertices.push_back(vec3(j, 0, i));
  8. }
  9. }
  10. for (int i = 0; i < totalPatches; i++)
  11. {
  12. for (int j = 0; j < totalPatches; j++)
  13. {
  14. int startingPoint = i * (totalPatches + 1) + j;
  15. indices.push_back(startingPoint);
  16. indices.push_back(startingPoint + 1);
  17. indices.push_back(startingPoint + totalPatches + 2);
  18. indices.push_back(startingPoint + totalPatches + 1);
  19. }
  20. }
  21. }
  22. void Terrain::Render(mat4 projection, mat4 view)
  23. {
  24. shader.use();
  25. mat4 VPMatrix = projection * view;
  26. shader.setUniform("VP", VPMatrix);
  27. shader.setUniform("M", transform.modelMatrix());
  28. glBindVertexArray(vaoID);
  29. glPatchParameteri(GL_PATCH_VERTICES, 4);
  30. glDrawElements(GL_PATCHES, indices.size(), GL_UNSIGNED_INT, (GLubyte*)NULL);
  31. glBindVertexArray(0);
  32. }

yqkkidmi

yqkkidmi1#

你不能控制网格的三角剖分。有一些关于三角剖分如何工作的基本保证,但在这些之外,它取决于实现。所以无论你在tessellator中做什么,都需要能够与 * 任何 *(合理的)三角剖分一起工作。

相关问题