如何在Scenekit中确定几何曲面的方向



我正在尝试编写一个着色器,以便在SceneKit中为自定义几何体着色。我想设置颜色,使面朝上的水平曲面为白色,面朝下的水平曲面是黑色,而中间的所有其他曲面都是基于其方向的灰色阴影。我使用材质的表面入口点调用以下着色器

vec4 normal = vec4(_surface.normal, 1.0);
// Assume value is [-1, 1], scale to [0, 1]
float color = normal.z * 0.5 + 0.5;
_surface.diffuse = vec4(color, color, color, 1.0);

normal.z似乎是相对于摄影机(或视图(的。我想我需要转换值,这样它就在另一个空间中。我尝试了多个变换(以及变换的组合(,例如u_inverseViewTransform,但结果似乎都在视图空间中。有人知道如何根据几何体表面的方向为其着色吗?

由于_surface.normal是视图空间中的向量,因此必须将该向量转换为世界空间。

点形式的世界空间到视图空间的转换是由u_viewTransform完成的,因此(从视图空间到世界空间的(逆运算可以由u_inverseViewTransform完成。

_surface.normal是一个方向矢量,但不是一个点。向量必须通过正规矩阵进行变换,正规矩阵是4*4矩阵左上角3*3矩阵的转置逆矩阵:

transpose(inverse(mat3(u_viewTransform)))

请参见为什么模型视图矩阵的转置逆用于变换法向量?,为什么要用模型视图矩阵的逆矩阵的转置来变换法线?

但由于u_viewTransformu_inverseViewTransform是正交矩阵,所以可以跳过转置、逆,因为逆矩阵和转置矩阵是相等的。请参见在哪些情况下,逆矩阵等于转置?。

如下所示,您必须通过mat3(u_inverseViewTransform):进行转换

vec3 normal = mat3(u_inverseViewTransform) * _surface.normal;
float color = normal.z * 0.5 + 0.5;
_surface.diffuse = vec4(color, color, color, 1.0);

最新更新