如何重新计算法线?

时间:2017-12-06 00:52:34

标签: unity3d shader unity5 shaderlab

我试图编写一个简单的着色器,用一个sin波移动所有顶点。

v.vertex.y += sin(_Time.y * _Speed + v.vertex.x * _Amount * v.vertex.z) * _Distance;

问题是在移动它们之后,法线是错误的,因此没有实时阴影。我经常搜索,发现我需要使用假邻居重新计算法线。这些实现都不适用于Unity Shaderlab,因此我无法复制和粘贴它们,而且我对着色器代码的了解非常基础,因此我无法将我发现的内容翻译成我需要的内容。

任何人都可以帮助我在移动顶点后重新计算法线的内容和方法吗?

3 个答案:

答案 0 :(得分:1)

正常计算背后的数学是交叉乘积。

从三角形中取出顶点A,B和C.然后创建向量AB和AC。 ABxAC将为您提供三角形的法线。 ACxAB将给出相反的法线(ABxAC = - ACxAB)。

en.wikipedia.org/wiki/Cross_product

如果要从Mesh类移动网格物体,则会有一个RecalculateNormals。但我想在你处理着色器时,这并不适用于此。

答案 1 :(得分:1)

表面的法线向量与其导数有关。在正弦波的情况下,它的导数只是余弦波 cos()。两者都可以在名为 sincos() 的单个操作中高效计算。

完美的介绍练习:)绘制两个并观察relationship

当您可以访问相邻顶点时,Everts的上一个答案可以正常工作,您通常不会在着色器中使用(但在CPU上会很好)。

答案 2 :(得分:-1)

我自己没有这样做,我做了一点googly并发现this shader,用于反转法线。它通过调整顶点信息来实现:

    void vert(inout appdata_full v) {
        v.normal.xyz = v.normal * -1;
    }

您应该可以调整着色器,根据其他更改重新计算法线方向,并以类似方式更新。