gpt4 book ai didi

3d - 如何引用任意 id 以在 SCNTechnique 中使用?

转载 作者:行者123 更新时间:2023-12-03 22:09:31 24 4
gpt4 key购买 nike

TL;博士:

如何引用“不在磁盘上”的 sampler2D 符号并将其传递给 SCNTechnique ?如果我从我的包中引用图像,我的技术就可以工作,但如果我不这样做,我就找不到传递现有 id<MTLTexture> 的方法。到我的技术设置的采样器符号。

长:

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

关注 SCNShadable说明 id<MTLTexture> 的文档可以通过 SCNMaterialProperty 作为着色器输入传递它具有正确的内容集。这 100% 在着色器修改器 channel 中有效 - 但在 SCNTecnique 中失败!

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 ,我收到错误日志指示“无纹理存储”,并且 Metal GPU 帧捕获指示采样器设置了默认的 4x4 像素白色纹理(大概来自 SCNTecnique ?)。但是,我已经能够验证我的自定义 id<MTLTexture>是有效的并且在调试器中有内容 - 它的格式、宽度、高度和内容都符合预期,我似乎无法正确地将任意纹理引用到场景套件技术传递中。

如果我在 SCNTechnique 中声明我的符号plist 文件来引用图像,如下所示:
<dict>
<key>type</key>
<string>sampler2D</string>
<key>image</key>
<string>star.png</string>
</dict>

我的通行证输入如下:
<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>

然后我的通行证工作并引用了 star.png 纹理。

有没有人得到这样的工作?

谢谢你。

最佳答案

相当肯定我得到了这个工作。

用于设置 MTLTexture 的 Swift 代码并将其设置为 SCNTechnique .

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 x 1px 的颜色渐变(蓝色 -> 绿色 -> 红色)图像,我用来将单个值映射到伪颜色。
(例如; enter image description here )

这是来自我的 plist 中的 pass dict 的完整技术传递定义。
<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还需要在技术 plist 的符号部分定义。
<key>symbols</key>
<dict>
<key>myTexture</key>
<dict>
<key>type</key>
<string>sampler2D</string>
</dict>
</dict>

当不包含此符号块时,我也看到了“pass has no storage for input myTextureSampler”错误消息。 这可能是你的问题?

最后是片段着色器定义。
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);
}

这个技术中还有一些其他的pass,我没有包括在内;只是为了提供一些上下文,它在一次传递中渲染场景,并在另一次传递中使用输出深度缓冲区和 Sobel 算子在 depthSampler 中生成边缘。质地。上面的 pass + fragment 着色器在场景的原始渲染之上绘制这些边缘。我在边缘使用纯黑色,但在研究这个之后,我似乎能够从 MTLTexture 中读出一种颜色。我提供给 SCNTechnique并将其用于边缘。

关于3d - 如何引用任意 id<MTLTexture> 以在 SCNTechnique 中使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55812462/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com