【问题标题】:marching cubes, very small triangles行进立方体,非常小的三角形
【发布时间】:2016-01-31 09:18:56
【问题描述】:

所以我正在尝试使用行进立方体算法生成地形。此时我正在实现漫反射照明(片段着色器)。我计算了每个顶点的法线并得到了这个: result

图片的左侧显示法线(每个顶点和三角形)和线框,右侧是来自相同相机角度的照明景观。

所以,我很好奇,我做错了什么?

我是这样计算法线的:

for (int t = 0; t < all_triangles.size(); t++) {

        Vertex v0 = all_vertices[triangle.get_vertex(0)];
        Vertex v1 = all_vertices[triangle.get_vertex(1)];
        Vertex v2 = all_vertices[triangle.get_vertex(2)];

        QVector3D edge1 = v1 - v0;
        QVector3D edge2 = v2 - v0;

        QVector3D normal = QVector3D::crossProduct(edge1, edge2);
//        triangle.set_normal(normal.normalized());

        for (int v = 0; v < 3; v++) {
            all_vertices[triangle.get_vertex(v)].add_normal(normal.normalized());
        }
    }

    for (int v = 0; v < all_vertices.size(); v++) {
        auto normal = all_vertices[v].get_normal();
        normal.normalize();
        all_vertices[v].set_normal(normal);

    }

更新:vcs

bitbucket source

【问题讨论】:

  • 是不是故意在循环中不使用t
  • @4386427 是的,我正在使用宏,抱歉我没有发布它#define triangle all_triangles[t]
  • get_normal()add_normal(...)的作用是什么?能否提供这些方法的代码。
  • @GuillaumeGris: get_normal() 返回顶点的法线 (return this-&gt;normal;),add_normal(QVector3D n) 这样做:this-&gt;normal += n;
  • 您是否在算法之前将法线初始化为零?

标签: c++ qt opengl lighting marching-cubes


【解决方案1】:

这对于行进立方体来说是正常的。这是算法的一个已知问题,具有一些技术名称,例如冗余三角形。如果您需要较少的三角形并且不介意为每个顶点添加比较等号线,则有一个非常简单的调整,如果它们距离立方体的角超过 95%,则修复方法是将 iso 值捕捉到立方体的角上。 MC 优化非常酷,最好的方法是对使用的立方体进行八叉树感应,并根据该区域表面的复杂性或平面度调整立方体的大小。关于这个主题有很棒的论文。

这是一个快速修复的演示,如果边缘交叉点与拐角的接近度低于 5% 或超过 95%,则只需将值捕捉到拐角,可调整,如果需要,可以尝试 90%。

通用 MC:

最简单的优化:

SnapMC 类似:

【讨论】:

    【解决方案2】:

    你的数学是正确的。 你的法线看起来很好,但很难 100% 理解你的图片。

    调试此类问题的常用方法是: - 平坦的阴影(没有正常的平滑) - 使用三角形/顶点法线作为颜色来可视化法线

    还请分享您的着色代码。

    【讨论】:

    • 所以我得到了that,看起来很随意。我的下一步可能是什么?为什么使用几何着色器渲染法线会给出合理的结果,而这看起来很乱?
    • 你能分享你的代码吗? github/bitbucket/whatever?
    • 大部分法线必须是蓝色的,但你的法线是绿色的。尝试逆向量。 (乘以 -1 或更改叉积中的边顺序)
    • 我没有 Qt 所以不能直接运行/调试你的代码。我发现你没有做数学。平均您的累积法线。例如: void Vertex::calc_avg_normal() { this->normal = (this->normal / triangles.size()).normalized(); }
    • 有必要吗?我对累积法线做normal.normalize();。然后在 normalize() 之前除以某个值不会做任何事情,导致除法/乘法线意味着向量的缩放,而 .normalize() 会将其缩放回单位向量。
    【解决方案3】:

    一些尝试:

    (1) 加权法线。 add_normal(normal.normalized()*weight),其中权重可以是很多东西,比如三角形的面积,或者内角

    (2) 从你的领域计算一个法线。你得到一个 f(x,y,z)=0 的表面。评估为 f(x-eps,y,z)-f(x+eps,y,z) 以获得正常的 x,对于 y,z 也是如此。

    (3) 只是模糊它。对于每个顶点,按边添加所有相邻的法线,然后平均。

    我想你想要 (2)。尤其是对于地形。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 2019-11-03
      • 1970-01-01
      相关资源
      最近更新 更多