Passing Metal texture2d_array to the SceneKit shader modifier

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
// 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:

exception

Backtrace:

enter image description here

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?

.

+3

All Articles