问题描述
我想为SCNMaterial
(使用SCNShaderModifierEntryPointSurface
)创建着色器修改器,并将Metal texture2d_array
作为自定义输入传递.为此,我尝试使用类型为SCNMaterialProperty
的键值编码设置参数.从SCNMaterialProperty
属性contents
上的SceneKit手册中:
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:
- ...
- 纹理(SKTexture,MDLTexture, MTLTexture 或GLKTextureInfo)
- ...
- ...
- A texture (SKTexture, MDLTexture, MTLTexture, or GLKTextureInfo)
- ...
所以,我构造了MTLTexture
:
- 使用类型
MTLTextureType2DArray
创建 - 使用
MTLDevice
的newTextureWithDescriptor创建MTLTexture
: - 使用
[texture replaceRegion:mipmapLevel:withBytes:bytesPerRow:];
用数据填充纹理
MTLTextureDescriptor
- Create
MTLTextureDescriptor
with typeMTLTextureType2DArray
- Create
MTLTexture
withMTLDevice
's newTextureWithDescriptor: - Fill texture with data using
[texture replaceRegion:mipmapLevel:withBytes:bytesPerRow:];
然后创建SCNMaterialProperty
,将创建的MTLTexture
分配给其contents
并将其传递给材料:
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);
然后我得到:
回溯:
我也尝试直接使用[material setValue:aTexture forKey:@"tex"];
传递纹理,但是随后出现错误:
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].'
此外,我尝试在SCNMaterialProperty
内容中传递MTLTexture2D
,但C3DImageGetImage类型的异常失败.直接通过[material setValue:forKey]
传递MTLTexture2D
会导致所有白色都被采样-错误的纹理被采样.
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.
在分析捕获GPU框架"输出时,我发现在绘制调用期间绑定了错误的纹理.
When analysing 'Capture GPU Frame' output, I see that wrong texture bound during draw call.
也许有人设法将texture2d_array传递给shader修改器?有可能吗?我可以使用金属命令缓冲区手动绑定,但是如何基于每种材料访问它呢?
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?
谢谢大家.
推荐答案
#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")
这篇关于将Metal Texture2d_Array传递给SceneKit着色器修改器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!