将Metal texture2d_array传递给SceneKit着色器修饰符

时间:2016-05-20 13:52:17

标签: macos scenekit metal

我想为SCNMaterial(使用SCNShaderModifierEntryPointSurface)创建着色器修改器,并将Metal texture2d_array作为自定义输入传递。为此,我尝试使用类型为SCNMaterialProperty的键值编码设置参数。来自SCNMaterialProperty属性contents上的SceneKit手册:

您可以使用以下任何类型为此属性设置值:

  • ...
  • 纹理(SKTexture,MDLTexture, MTLTexture 或GLKTextureInfo)
  • ...

所以,我构建了MTLTexture

  • 使用MTLTextureDescriptor
  • 类型创建MTLTextureType2DArray
  • 使用MTLTexture的newTextureWithDescriptor创建MTLDevice
  • 使用[texture replaceRegion:mipmapLevel:withBytes:bytesPerRow:];
  • 使用数据填充纹理

然后我创建SCNMaterialProperty,将创建的MTLTexture分配给contents并将其传递给素材:

[material setValue:aTexture forKey:@"tex"];

然后我附上了这个着色器修饰符:

#pragma arguments
texture2d_array tex;

#pragma body
// do sampling from 1st slice
constexpr sampler smp(coord::normalized, address::repeat, filter::nearest);
_surface.diffuse = tex.sample(smp, _surface.diffuseTexcoord, 0);

我得到了:

exception

回溯:

enter image description here

我还尝试直接使用[material setValue:aTexture forKey:@"tex"];传递纹理但是我收到了错误:

/Library/Caches/com.apple.xbs/Sources/Metal/Metal-56.6/ToolsLayers/Debug/MTLDebugRenderCommandEncoder.mm:1600: 
failed assertion `textureType mismatch at texture binding at index 8 for tex[0].'

另外,我尝试在MTLTexture2D内容中传递SCNMaterialProperty,并且在C3DImageGetImage类型中失败并出现异常。直接通过MTLTexture2D传递[material setValue:forKey]会导致所有内容都变白 - 错误的纹理被采样。

分析'捕获GPU帧'输出,我在绘制调用期间看到错误的纹理绑定。

也许有人设法将texture2d_array传递给着色器修饰符?有可能吗?我可以使用金属命令缓冲区手动绑定,但是如何根据每种材料访问它?

谢谢大家。

1 个答案:

答案 0 :(得分:0)

        #include <metal_stdlib>
        #include <metal_texture>
        using namespace metal;
        #pragma arguments
        texture2d<float> mask;

        #pragma body
        constexpr sampler quadSampler(address::clamp_to_edge, filter::linear);

        _surface.diffuse = mask.sample(quadSampler, _surface.diffuseTexcoord);

然后迅速

let mask = SCNMaterialProperty(contents: MDLTexture(named: "gameFrame.png")!)
doorFrame.geometry?.firstMaterial?.setValue(mask, forKey: "mask")