我可以将类型sampler2D
的自定义参数传递给Metal fragment function
的{{1}},并且我可以进行第二次传递:
PList:
SCNTechnique
...
<key>inputs</key>
<dict>
<key>imageFromPass1</key>
<string>COLOR</string>
<key>myCustomImage</key>
<string>myCustomImage_sym</string>
</dict>
相关的Obj-C代码:
<key>symbols</key>
<dict>
<key>myCustomImage_sym</key>
<dict>
<key>type</key>
<string>sampler2D</string>
</dict>
</dict>
金属功能参数:
[technique setValue: UIImagePNGRepresentation(myCustomTexture) forKey:@"myCustomImage_sym"];
我在着色器功能中访问并使用所有这些输入。可行!
但是,当我添加另一个fragment half4 myFS(out_vertex_t vert [[stage_in]],
texture2d<float, access::sample> imageFromPass1 [[texture(0)]],
texture2d<float, access::sample> myCustomImage [[texture(1)]],
constant SCNSceneBuffer& scn_frame [[buffer(0)]]) { ...
类型的自定义参数时...
float
...
<key>blob_pos</key>
<string>blob_pos_sym</string>
<key>blob_pos_sym</key>
<dict>
<key>type</key>
<string>float</string>
</dict>
[_sceneView.technique setValue:[NSNumber numberWithFloat:0.5f] forKey:@"blob_pos_sym"];
...传递的值永远不会到达着色器功能。
将浮点数包装在结构中
constant float& blob_pos [[buffer(2)]]
...全部失败。
然后我看了handleBindingOfSymbol:usingBlock: ...,但这只是GLSL。
我发现它是Metal的handleBindingOfBufferNamed:frequency:usingBlock: ...,在SCNTechnique中不可用。
我用Google搜索SCNTechnique Metal ...并意识到所有个项目仅使用了sampler2D参数。
最后,我了解到这不是新事物,而是bugs developers for years。
在我将此浮点编码为纹理之前,请让我知道缺少的部分,以使其按预期方式工作。
答案 0 :(得分:3)
您必须使用结构来包装输入符号,并确保使用[SCNTechnique setObject:forKeyedSubscript:]
将符号值传递给技术。 setObject:forKeyedSubscript:的文档中提到了Metal,但是不幸的是,它没有解释如何在Metal函数中接收值。
使用您的示例:
技术定义:
"inputs": [
"imageFromPass1": "COLOR",
"myCustomImage": "myCustomImage_sym",
"blob_pos": "blob_pos_sym",
],
...
"symbols": [
"myCustomImage_sym": ["type": "sampler2D"],
"blob_pos_sym": ["type": "float"]
]
Obj-C:
[_sceneView.technique setObject:[NSNumber numberWithFloat:0.5f] forKeyedSubscript:@"blob_pos_sym"];
金属:
typedef struct {
float blob_pos; // Must be spelled exactly the same as in inputs dictionary.
} Inputs;
fragment half4 myFS(out_vertex_t vert [[stage_in]],
texture2d<float, access::sample> imageFromPass1 [[texture(0)]],
texture2d<float, access::sample> myCustomImage [[texture(1)]],
constant Inputs& myInputs [[buffer(0)]]) {
float blob_pos = myInputs.blob_pos;
...