网站搜索

javascript - 八顶点立方体的法向量


我今天在玩 WEBGL 时遇到了我的立方体顶点法线的问题。

我用从网上获取的立方体网格检查了我的代码,它运行得很棒。

问题是,网上的立方体有24个顶点(每个面4个 * 6个面),我认为对于一个立方体来说太多了。

摆弄我的立方体 | 摆弄互联网立方体(我的代码从第200行开始)

我发现一个立方体最多只需要8个顶点和12个索引。但是当我渲染我的立方体时,屏幕上出现了一个奇怪的形状(是因为法线吗?)

这是立方体形式的互联网,几乎处于和我的立方体相同的旋转位置:

这是我的立方体:

var cube = {
    "vertices" : [
        -0.5 , 0.5 , 0.5, // 0
         0.5 , 0.5 , 0.5, // 1
        -0.5 ,-0.5 , 0.5, // 2
         0.5 ,-0.5 , 0.5, // 3

        -0.5 , 0.5 , -0.5, // 4
         0.5 , 0.5 , -0.5, // 5
        -0.5 ,-0.5 , -0.5, // 6
         0.5 ,-0.5 , -0.5 // 7
    ],
    "normals" : [
        0.57    , 0.57      , -0.57 ,
        0.57    , -0.57     , -0.57 ,
        -0.57   , -0.57     , -0.57 ,
        -0.57   , 0.57      , -0.57 ,
        0.57    , 0.57      , 0.57 ,
        0.57    , -0.57     , 0.57 ,
        -0.57   , -0.57     , 0.57 ,
        -0.57   , 0.57      , 0.57 
    ],
    "indices" : [
        0 , 2 , 3 ,
        0 , 3 , 1 ,

        0 , 4 , 5 ,
        0 , 5 , 1 ,

        0 , 4 , 6 ,
        0 , 6 , 2 ,

        2 , 6 , 7 ,
        2 , 7 , 3 ,

        1 , 5 , 7 ,
        1 , 7 , 3 ,

        4 , 6 , 7 ,
        4 , 7 , 5 
    ]
}

我的问题是:

有可能为一个8顶点的立方体创建正确的法线吗?如果不行,有什么替代方案?

答案#1

你需要理解,vertex 不仅仅是空间中的一个点,它更是由多个不同属性组成的一个对象。这些属性包括位置,但也可能有法线、颜色、纹理坐标等。

在3D图形中,你经常需要两个或更多顶点放置在同一个位置,但具有不同的法线、颜色或纹理坐标。你的立方体就是这种情况——立方体通常只有8个角,但每个角连接3个面,每个面都有不同的法线,这就是为什么你看到的所有示例立方体都有24个顶点的原因。

实际上,你的立方体非常类似于球体,几何形状非常简单,以至于球体上的每个顶点只有一个法线,并且顶点周围的光照是平滑的。在立方体中,你需要将每一面都渲染为平面,所以构成立方体某一面的所有顶点都需要相同的法线。

如果你把立方体看作6个不同的四边形,并用独立的顶点创建所有这些四边形,可能会更容易理解。

答案#2

你可以使用一个通过几何着色器来绕过这个问题。

几何着色器接收一个形状并输出另一个形状(可以是相同类型的)。在你的情况下,它应该只输出它作为输入接收的同一个三角形。它还应该计算法线并将其传送到片段着色器。

在这里找到 VS、GS 和 FS 的代码:https://community.khronos.org/t/calculate-normals-in-vertex-shader/71573/4

有关几何着色器的更多信息,请查看此处的“可视化法线向量”:https://learnopengl.com/Advanced-OpenGL/Geometry-Shader