我想为SCNMaterial
(使用SCNShaderModifierEntryPointSurface
)创建着色器修改器,并将Metal texture2d_array
作为自定义输入传递。为此,我尝试使用类型为SCNMaterialProperty
的键值编码设置参数。来自SCNMaterialProperty
属性contents
上的SceneKit手册:
您可以使用以下任何类型为此属性设置值:
所以,我构建了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);
我得到了:
回溯:
我还尝试直接使用[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传递给着色器修饰符?有可能吗?我可以使用金属命令缓冲区手动绑定,但是如何根据每种材料访问它?
谢谢大家。
答案 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")