Ios 在着色器修改器SceneKit中访问世界空间中的z坐标 寻找

Ios 在着色器修改器SceneKit中访问世界空间中的z坐标 寻找,ios,glsl,scenekit,Ios,Glsl,Scenekit,在世界空间中访问渲染像素的z坐标时遇到问题。在SceneKit中,我正在寻找其渲染颜色与渲染点的z坐标直接相关的3d平面 处境 我正在使用SpriteKit,并使用SK3DNode在SpriteKit场景中嵌入SceneKit场景。对于SceneKit场景,我使用从Blender导出的.dae Collada文件。它包含一个平面网格和一个灯光。 我正在应用着色器修改器来修改几何体和照明模型 self.waterGeometry.shaderModifiers = @{ SCNShad

在世界空间中访问渲染像素的z坐标时遇到问题。在SceneKit中,我正在寻找其渲染颜色与渲染点的z坐标直接相关的3d平面

处境 我正在使用SpriteKit,并使用SK3DNode在SpriteKit场景中嵌入SceneKit场景。对于SceneKit场景,我使用从Blender导出的.dae Collada文件。它包含一个平面网格和一个灯光。 我正在应用着色器修改器来修改几何体和照明模型

  self.waterGeometry.shaderModifiers = @{
    SCNShaderModifierEntryPointGeometry : self.geomModifier,
    SCNShaderModifierEntryPointSurface : self.cellShadingModifier
  };
几何体修改器代码(
self.geomModifier
):

“几何体”修改器将正弦变换应用于
\u曲面
属性以模拟波浪。在下图中,绘制的精灵是SpriteKit精灵,它具有较高的Z位置,并且不会干扰SK3DNode。请注意作为“几何体”修改器的结果的细微波(z位移)

下一步,我想输出基于点在世界空间中的z坐标计算的颜色。这可以是_surface.diffuse或_output.color,这对您没有多大关系(这意味着着色器修改器的插入点不同,但不是问题)

我试过了 曲面修改器中的以下代码(
self.cellShadingModifier

vec4几何体=u_inverseViewTransform*vec4(_surface.position,1.0);
if(几何体y<0.0){
_surface.diffuse.rgb*=vec3(0.4);
}
\u surface.position
在视图空间中,我希望通过使用
u\u inverseViewTransform
将其转换为世界空间。说:

几何字段(如位置和法线)在视图中表示 空间您可以使用SceneKit的制服(例如 在不同的坐标空间中操作, [……]

正如您所看到的,它正在闪烁,似乎不是基于我刚才修改的geometry.position。我已经在模拟器和设备(iPad Air)上对此进行了测试。我认为我犯了一个简单的错误,因为我可能混淆了
\u曲面
\u几何体
属性

有人能告诉我在哪里可以获得网格当前着色点的z坐标(世界空间),以便在渲染方法中使用它吗

注 我还尝试访问“曲面着色器”修改器中的
\u几何体
,但我得到错误
使用了未声明的标识符“\u几何体”
,这很奇怪,因为上面说:

您可以在以后的版本中使用由早期入口点定义的结构 入口点。例如,与 SCNShaderModifierEntryPointFragment入口点可以从 _由SCNShaderModifierEntryPoint曲面入口点定义的曲面结构

附注2
我可以让LightingModel着色器根据生成的正弦波进行计算(并避免搜索z坐标),但将来我可能会添加更多的波,使用z坐标将更易于维护,更不用说优雅了。

我还一直在学习如何使用着色器修改器。我有一个对我有用的解决方案,使用逆模型变换和逆视图变换

以下代码将使用红色色调绘制场景中心模型的右侧。您应该能够检查其他位置元素(我认为是y)以获得您想要的结果

vec4 orig = _surface.diffuse;
vec4 transformed_position = u_inverseModelTransform * u_inverseViewTransform * vec4(_surface.position, 1.0);
if (transformed_position.z < 0.0) {
    _surface.diffuse = mix(vec4(1.0,0.0,0.0,1.0), orig, 0.5);
}
vec4 orig=\u surface.diffuse;
vec4 transformed_position=u_inverseModelTransform*u_inverseViewTransform*vec4(_surface.position,1.0);
if(变换位置z<0.0){
_表面扩散=混合(vec4(1.0,0.0,0.0,1.0),原始,0.5);
}

文档有一半是正确的。可以在同一着色器阶段中使用来自早期入口点的信息。但几何体入口点在“顶点”阶段运行,曲面入口点在“碎片”阶段运行。(除非IIRC关闭了每像素照明。)
vec4 geometry = u_inverseViewTransform * vec4(_surface.position, 1.0);
if (geometry.y < 0.0) {
_surface.diffuse.rgb *= vec3(0.4);
}
vec4 orig = _surface.diffuse;
vec4 transformed_position = u_inverseModelTransform * u_inverseViewTransform * vec4(_surface.position, 1.0);
if (transformed_position.z < 0.0) {
    _surface.diffuse = mix(vec4(1.0,0.0,0.0,1.0), orig, 0.5);
}