I want to create a shader modifier for SCNMaterial(c SCNShaderModifierEntryPointSurface) and pass Metal texture2d_arrayas user input. For this, I am trying to use a parameter setting for encoding a type key value SCNMaterialProperty. From the SceneKit manual to the SCNMaterialPropertyproperty contents:
You can set a value for this property using any of the following types:
- ...
- Texture (SKTexture, MDLTexture, MTLTexture , or GLKTextureInfo)
- ...
So, I will build MTLTexture:
- Create
MTLTextureDescriptorwith typeMTLTextureType2DArray - Create
MTLTextureusing MTLDevicenewTextureWithDescriptor: - Fill the texture with data using
[texture replaceRegion:mipmapLevel:withBytes:bytesPerRow:];
Then I create SCNMaterialProperty, assign the created MTLTextureone contentsand transfer it to the material:
[material setValue:aTexture forKey:@"tex"];
Then I add this shader modifier:
#pragma arguments
texture2d_array tex;
#pragma body
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 the texture directly using [material setValue:aTexture forKey:@"tex"];But then I get an 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].'
In addition, I tried to pass the contents MTLTexture2Dto SCNMaterialProperty, and the failure failed in the exception of type C3DImageGetImage. Passing MTLTexture2Ddirectly through [material setValue:forKey]results in all white being displayed - the texture is wrong.
When I analyze the output of the "Capture GPU Frame", I see that the wrong texture is connected during the drawing call.
Maybe someone managed to pass texture2d_array to the shader modifier? Is it even possible? I could use a metal command buffer for manual binding, but how do I access it based on material?
.