我正在尝试编写一个着色器来为 SceneKit 中的自定义几何图形着色。我想设置颜色,使朝上的水平表面为白色,朝下的水平表面为黑色,而介于两者之间的所有其他表面都是基于其方向的灰色阴影。我使用 Material 的表面入口点来调用以下着色器
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
相对于相机(或 View )。我假设我需要转换值,以便它在另一个空间中。我尝试了多种转换(和转换组合),例如 u_inverseViewTransform
,但结果似乎都在 View 空间中。有谁知道如何根据其表面的方向为几何图形着色?
最佳答案
由于_surface.normal
是 View 空间中的向量,您必须将向量转换为世界空间。u_viewTransform
将点形式的世界空间转换为 View 空间,所以逆运算(从 View 空间到世界空间)可以通过u_inverseViewTransform
来完成._surface.normal
是方向向量,但不是点。向量必须由法线矩阵进行变换,法线矩阵是 4*4 矩阵的左上角 3*3 矩阵的转置逆矩阵:
transpose(inverse(mat3(u_viewTransform)))
见 Why is the transposed inverse of the model view matrix used to transform the normal vectors? , Why transforming normals with the transpose of the inverse of the modelview matrix?
但是自从
u_viewTransform
和 u_inverseViewTransform
是 Orthogonal matrices转置,逆可以跳过,因为逆矩阵和转置矩阵是相等的。见 In which cases is the inverse matrix equal to the transpose? .这遵循您必须通过
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);
关于ios - 如何在 Scenekit 中确定几何表面的方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53795957/