ios - 如何在 Scenekit 中确定几何表面的方向

标签 ios glsl shader scenekit coordinate-transformation

我正在尝试编写一个着色器来为 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_viewTransformu_inverseViewTransformOrthogonal 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/

相关文章:

java - 如何在 OpenGL 中绘制镜像镜像?

java - 如何渲染从 Blender 导入的 3D 外星人?

opengl - 使用 SSBO 作为下一次绘制调用的 VBO 输入

iphone - iOS - 其他 View 中的 View

ios - 如何在 iOS 中调用带有 id 对象参数的方法?

opengl - 用 fwidth 确定 miplevel

java - LWJGL代码产生黑屏

javascript - 当我将位置传递给具有属性的着色器时,gl_Position 不会移动顶点吗?

iOS 使用带有部分文件名的文件

ios - 将 RLMFile 存储到 Realm swift 3.0 中的数组中