首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何引用任意id<MTLTexture>以便在SCNTechnique中使用?

如何引用任意id<MTLTexture>以便在SCNTechnique中使用?
EN

Stack Overflow用户
提问于 2019-04-23 13:33:17
回答 1查看 485关注 0票数 7

TL;DR:

如何引用“不在磁盘上”sampler2D符号并将其传递给SCNTechnique?如果我引用了包中的图像,我的技术就会奏效,但如果我不引用,我就无法找到将现有的id<MTLTexture>传递给我的技术设置的取样符号的方法。

Long:

我有一个有效的工作SCNTechnique,它使用自定义的sampler2D符号作为金属片段传递的输入。我试图传递一个外部的(而不是来自Scenekit)的id<MTLTexture>,它是我从硬件传感器获得的,作为后处理传递中的输入。

按照SCNShadable文档的状态,id<MTLTexture>可以通过具有适当内容集的SCNMaterialProperty作为着色器输入传递。这100%的工作在一个着色修饰符的通行证-但失败的SCNTecnique

代码语言:javascript
复制
let texture = CVMetalTextureGetTexture(textureRef!)

if self.material == nil
{
    self.material = SCNMaterialProperty(contents:texture)
}
else
{
    self.material?.contents = texture
}

self.currentTechnique?.setObject(self.material, forKeyedSubscript: "myTextureSamplerSymbol" as NSCopying)

对于SCNTechnique,我得到错误日志,指示“无纹理存储”,金属GPU帧捕获指示采样器设置了默认的4x4像素白色纹理(大概来自SCNTecnique?)。但是,我已经能够验证我的自定义id<MTLTexture>是有效的,并且调试器中有内容--它的格式、宽度、高度和内容都和预期的一样,我只是无法将任意纹理引用到场景工具包技术中。

如果我在SCNTechnique plist文件中声明我的符号以引用如下所示的图像:

代码语言:javascript
复制
<dict>
    <key>type</key>
    <string>sampler2D</string>
    <key>image</key>
    <string>star.png</string>
</dict>

我的通行证输入如下:

代码语言:javascript
复制
<dict>
    <key>colorSampler</key>
    <string>COLOR</string>
    <key>depthSampler</key>
    <string>DEPTH</string>
    <key> myTextureSampler</key>
    <dict>
        <key>target</key>
        <string> myTextureSamplerSymbol </string>
    </dict>
</dict>

然后我的pass工作并引用star.png纹理。

有人有这样的想法吗?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-26 11:40:44

我肯定能搞定这件事。

快速设置MTLTexture并将其设置到SCNTechnique中的代码。

代码语言:javascript
复制
let tech:SCNTechnique = getTechnique()

let textureLoader = MTKTextureLoader(device: MTLCreateSystemDefaultDevice()!)
let filePath = Bundle.main.url(forResource: "gradient", withExtension: "png")!

do {
    let gradTexture: MTLTexture = try textureLoader.newTexture(URL: filePath, options: nil)
    let matPropTexture = SCNMaterialProperty(contents: gradTexture)
    tech.setObject(matPropTexture, forKeyedSubscript: "myTexture" as NSCopying)
} catch {
    print("Unexpected error: \(error).")
}

scnView.technique = tech

gradient.png是一个256个x1px颜色梯度(蓝色、->、绿色、->、红色)图像,用于将单个值映射到伪颜色。(例如;

)

这里有一个完整的技术通行证定义,它来自我的plist中的pass dict。

代码语言:javascript
复制
<key>mix_outline</key>
<dict>
    <key>draw</key>
    <string>DRAW_QUAD</string>
    <key>metalVertexShader</key>
    <string>pass_through_vertex</string>
    <key>metalFragmentShader</key>
    <string>mix_outline_fragment</string>
    <key>inputs</key>
    <dict>
        <key>colorSampler</key>
        <string>color_scene</string>
        <key>depthSampler</key>
        <string>depth_outline</string>
        <key>myTextureSampler</key>
        <string>myTexture</string>
    </dict>
    <key>outputs</key>
    <dict>
        <key>color</key>
        <string>COLOR</string>
    </dict>
</dict>

myTexture也需要在技术文档的符号部分中定义。

代码语言:javascript
复制
<key>symbols</key>
<dict>
    <key>myTexture</key>
    <dict>
        <key>type</key>
        <string>sampler2D</string>
    </dict>
</dict>

当这个符号块不包括时,我也看到了"pass没有输入myTextureSampler的存储“错误消息。这可能是你的问题?

最后是片段着色器的定义。

代码语言:javascript
复制
fragment half4 mix_outline_fragment(out_vertex_t vert [[stage_in]],
                                    texture2d<float, access::sample> colorSampler [[texture(0)]],
                                    texture2d<float, access::sample> depthSampler [[texture(1)]],
                                    texture2d<float, access::sample> myTextureSampler [[texture(2)]])
{
    float4 myTextureColor = myTextureSampler.read(uint2(55, 0));
    float4 outline = depthSampler.sample( s, vert.uv);
    float4 scene_color = colorSampler.sample( s, vert.uv);
    // float4 fragment_color = mix(scene_color, float4(0.0, 0.0, 0.0, 0.0), outline.r);
    float4 fragment_color = mix(scene_color, myTextureColor, outline.r);
    return half4(fragment_color);
}

在这个技术中还有一些我没有包含的其他传递;只是为了给出一些上下文,它在一次传递中呈现场景,并在另一次传递中使用输出深度缓冲区与Sobel操作符一起生成边缘到depthSampler纹理中。上面的pass +片段着色器将这些边缘绘制在场景的原始渲染之上。我用的是纯黑的边缘,但是看了看之后,我似乎能够从我提供给SCNTechniqueSCNTechnique中读取一种颜色,并将其用于边缘。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55812462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档