如何在金属中使用一系列纹理

Posted

技术标签:

【中文标题】如何在金属中使用一系列纹理【英文标题】:how to use an array of textures in metal 【发布时间】:2018-10-17 07:18:07 【问题描述】:

我想在金属着色器中使用纹理数组,但它崩溃了 运行我的应用程序(iPhone6,A8)时,这是错误日志:Failed to created pipeline state, error Error Domain=AGXMetalA8 Code=3 "Could not resolve texture/sampler references" UserInfo=NSLocalizedDescription=Could not resolve texture/sampler references

我已经尝试谷歌但没有找到有用的信息,谁能给我一些建议,谢谢。

这是我的代码:

fragment float4 fragment_texture (ShaderInput vert [[stage_in]],
                        array<texture2d<float>, 2> u_texture [[texture(0)]],
                        sampler _mtlsmp_u_texture [[sampler(0)]])

    float4 srcColor = u_texture[0].sample(_mtlsmp_u_texture, vert.v_texCoord);
    float4 materialColor = u_texture[1].sample(_mtlsmp_u_texture, vert.v_texCoord);
    float4 mixColor = mix(srcColor, materialColor, 0.5);
    return mixColor;

在我的应用代码中:

    [renderEncoder setFragmentTexture:_textureDemo
                              atIndex:0];

    [renderEncoder setFragmentTexture:_textureBlend
                              atIndex:1];

    [renderEncoder setFragmentSamplerState:_sampler atIndex:0];

更新问题

我尝试使用 Argument Buffers 来处理纹理数组,但在 ios 11.4 版本的 iPhone6 上仍然崩溃并得到相同的错误信息:Failed to create pipeline state, error Could not resolve texture/sampler references

以下是一些关键步骤:

在我的应用代码中,argumentEncoder 是一个 MTLArgumentEncoder 类型对象,我通过调用 setTexture:atIndex: 将纹理资源编码到参数缓冲区中

 [argumentEncoder setArgumentBuffer:_fragmentShaderArgumentBuffer offset:0];
 [argumentEncoder setTexture:_texture[0] atIndex:0];
 [argumentEncoder setTexture:_texture[1] atIndex:1];

调用 useResource:usage: 方法使 GPU 可以访问纹理资源:

[renderEncoder useResource:_texture[0] usage:MTLResourceUsageSample];
[renderEncoder useResource:_texture[1] usage:MTLResourceUsageSample];

并将参数缓冲区_fragmentShaderArgumentBuffer设置为片段函数的参数:

[renderEncoder setFragmentBuffer:_fragmentShaderArgumentBuffer
                              offset:0
                             atIndex:0];

在我的片段着色器中:

typedef struct FragmentShaderArguments 
    array<texture2d<float>, 2> exampleTextures  [[ id(0)  ]];
 FragmentShaderArguments;

fragment float4
fragmentShader(       RasterizerData            in                 [[ stage_in ]],
               device FragmentShaderArguments & fragmentShaderArgs [[ buffer(0) ]])

    constexpr sampler textureSampler (mag_filter::linear,
                                      min_filter::linear);

    float4 color = float4(0, 0, 0, 1);
    float4 color1 = fragmentShaderArgs.exampleTextures[0].sample(textureSampler, in.texCoord);
    float4 color2 = fragmentShaderArgs.exampleTextures[1].sample(textureSampler, in.texCoord);
    color = mix(color1, color2, 0.5);
    return color;

真诚希望有人能给我提供意见,谢谢!

【问题讨论】:

我无法在运行 iOS 12.1 beta 4 的 iPhone X 上重现此问题。您使用的是什么版本的 iOS? 是iPhone6,版本是iOS11.4 奇怪,我把手机升级到iOS 12.0.1,然后问题就解决了 【参考方案1】:

我升级到 iOS 12.0.1,运行良好。

【讨论】:

以上是关于如何在金属中使用一系列纹理的主要内容,如果未能解决你的问题,请参考以下文章

使用 3D 类型初始化金属纹理

如何在场景套件中显示金属质感

如何让 SKSpriteNode 不旋转纹理

金属着色器纹理读取与示例

闪烁的金属输出纹理...为啥?

你能改变金属着色器中采样器的边界吗?