I want to create shader modifier for SCNMaterial (with SCNShaderModifierEntryPointSurface) and pass Metal texture2d_array as custom input. To achieve that I try to use key-value coding setting parameter of type SCNMaterialProperty. From SceneKit manual on SCNMaterialProperty property contents:
You can set a value for this property using any of the following types:
- ...
- A texture (SKTexture, MDLTexture, MTLTexture, or GLKTextureInfo)
- ...
So, I construct MTLTexture:
- Create
MTLTextureDescriptorwith typeMTLTextureType2DArray - Create
MTLTexturewithMTLDevice's newTextureWithDescriptor: - Fill texture with data using
[texture replaceRegion:mipmapLevel:withBytes:bytesPerRow:];
Then I create SCNMaterialProperty, assign my created MTLTexture to its contents and pass it to material:
[material setValue:aTexture forKey:@"tex"]; Then I attach this shader modifier:
#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); And I get:
Backtrace:
I also tried to pass texture directly with [material setValue:aTexture forKey:@"tex"]; But then I'm getting error:
/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].' Also, I tried passing MTLTexture2D in SCNMaterialProperty contents and It fails with exception in C3DImageGetImage type. Passing MTLTexture2D directly via [material setValue:forKey] results in everything white - wrong texture being sampled.
When analysing 'Capture GPU Frame' output, I see that wrong texture bound during draw call.
Maybe someone managed to pass texture2d_array to shader modifier? Is it possible at all? I could use metal command buffer to bind manually, but how to get access to it on per-material basis?
Thank you all.

