寻找
我遇到了一个问题,无法获取渲染像素在世界空间中的z坐标。在SceneKit中,我正在寻找一个3D平面,其渲染颜色直接与渲染点的z坐标相关。
情况
我正在使用SpriteKit,并使用SK3DNode将SceneKit场景嵌入到我的SpriteKit场景中。对于SceneKit场景,我正在使用从Blender导出的.dae Collada文件,其中包含平面网格和灯光。我正在应用着色器修改器来修改几何形状和照明模型。
self.waterGeometry.shaderModifiers = @{
SCNShaderModifierEntryPointGeometry : self.geomModifier,
SCNShaderModifierEntryPointSurface : self.cellShadingModifier
};
几何修饰器代码(
self.geomModifier
):// Waves Modifier
float Amplitude = 0.02;
float Frequency = 15.0;
vec2 nrm = _geometry.position.xz;
float len = length(nrm)+0.0001; // for robustness
nrm /= len;
float a = len + Amplitude*sin(Frequency * _geometry.position.z + u_time * 1.6);
_geometry.position.xz = nrm * a;
几何修饰符将正弦变换应用于_surface属性,以模拟波浪。在下面的图像中,草图精灵是SpriteKit精灵,它们具有更高的zPosition并且不会干扰SK3DNode。请注意几何修改器的微妙波浪(z位移)的结果。
下一步,我希望基于点在世界空间中的z坐标计算输出颜色。这可能是_surface.diffuse或_output.color,这并不重要(这将意味着着色器修改器的不同插入点,但不是问题)。
我在surface修饰符(self.cellShadingModifier)中尝试了以下代码。
vec4 geometry = u_inverseViewTransform * vec4(_surface.position, 1.0);
if (geometry.y < 0.0) {
_surface.diffuse.rgb *= vec3(0.4);
}
_surface.position
是在视图空间中的,我希望通过使用 u_inverseViewTransform
将其转换为世界空间。根据苹果文档:
几何字段(例如位置和法线)是在视图空间中表示的。您可以使用 SceneKit 的 uniform(例如 u_inverseViewTransform)在不同的坐标空间中操作,[...]
如你所见,它在闪烁,似乎并不基于我刚刚修改的 geometry.position。我已经在模拟器和设备上进行了测试(iPad Air)。我认为我犯了一个简单的错误,因为我可能混淆了 _surface
和 _geometry
属性。
有人能告诉我在网格的当前着色点中获取 z 坐标(世界空间)的位置吗,这样我就可以在我的渲染方法中使用它?
注意
我还尝试在表面着色器修改器中访问 _geometry
,但我收到错误信息 Use of undeclared identifier '_geometry'
,这很奇怪,因为苹果文档说:
您可以在后面的入口点中使用早期入口点定义的结构。例如,与 SCNShaderModifierEntryPointFragment 入口点相关联的代码片段可以从 SCNShaderModifierEntryPointSurface 入口点定义的 _surface 结构中读取。
注意 2
我可以让 LightingModel 着色器基于生成的正弦波进行计算(并避免搜索 z 坐标),但在将来,我可能会添加其他波,并且使用 z 坐标更易于维护,更加优雅。