【问题标题】:Texture array in MetalMetal中的纹理数组
【发布时间】:2019-06-11 11:03:24
【问题描述】:
fragment half4 fragmen_shader_test(WaterColorCloudOut params[[stage_in]],
                                                         texture2d<float , access::sample>cloud1 [[texture(0)]],
                                                         texture2d<half, access::sample> cloud2 [[texture(1)]],
                                                         texture2d<half, access::sample> cloud3 [[texture(2)]]
                                                         )
{
    constexpr sampler defaultSampler;
    float4 color1;

    if(params.index == 0){
        color1= float4(cloud1.sample(defaultSampler, float2(params.textureCoordinates)))  * params.color ;
    }
    else if(params.index == 1){
        color1= float4(cloud2.sample(defaultSampler, float2(params.textureCoordinates)))  * params.color ;
    } else{
        color1= float4(cloud3.sample(defaultSampler, float2(params.textureCoordinates)))  * params.color ;
    }

 return half4(color1);
}

这里我使用了三个纹理,因为 If-else 条件会随着时间的推移而下降。我觉得如果我将纹理数组发送到着色器,则无需执行 if else 语句。在 CPU 中,我有三个 MTLTexture。如何将三个纹理绑定到一个数组并传递给它着色器。

在 CPU 方面我创建了三个纹理并创建了一个 MTLTexture 数组

 var textureArray:[MTLTexture] = [] 

然后我将纹理附加到该数组。 在 MTLRenderCommandEncoder

let myRange: CountableRange = 0..<2
commandEncoder.setFragmentTextures(textureArray, range: myRange)

在着色器中

texture2d_array<float ,  access::sample> texture [[ texture(0) ]]

在着色器中采样时

float4 color = texture.sample(defaultSampler, float2(params.textureCoordinates),0) * float4(1,0,0,1.0);

我目前正在这样做但我无法获得正确的纹理输出

【问题讨论】:

    标签: ios swift metal metalkit


    【解决方案1】:

    您不必更改应用代码。由于您使用的是连续的纹理索引,因此您只需将三个单独的参数替换为绑定到索引 0 的单个纹理数组参数,并且绑定会将数组的元素与您从应用程序代码中提供的纹理连接起来。

    换句话说,如果你声明一个大小为 3 且绑定到纹理索引 0 的纹理数组,则数组的元素取自纹理索引 0、1 和 2。


    更新您编辑的问题:

    您混淆了 of 纹理数组(也称为纹理数组)和纹理数组。这个术语很微妙。

    • 阵列纹理是其中包含多个 2D 平面的单个纹理。所有平面都具有相同的大小和像素格式。在着色器编译时不必知道纹理中的平面数量。
    • 纹理数组是独立纹理的数组,可能具有不同的大小或像素格式。数组的长度是编译时常量。

    您使用了texture2d_array&lt;...&gt;。那是一个数组纹理。

    对于纹理数组或纹理数组,您应该使用array&lt;texture2d&lt;float, access::sample&gt;, 3&gt; clouds [[texture(0)]]

    要从数组中的纹理中采样,首先要对数组进行索引,然后在该元素上调用纹理函数:

    float4 color = clouds[params.index].sample(defaultSampler, float2(params.textureCoordinates)) * float4(1,0,0,1.0);
    

    【讨论】:

    • 我编辑了这个问题。我尝试了上述方式。但我无法在屏幕上获得正确的纹理并且它正在闪烁......之前我没有阵列它工作正常......出了什么问题......
    • 您必须进行测试才能找到答案。我认为使用纹理数组至少应该和手动切换代码一样快。
    猜你喜欢
    • 2015-06-22
    • 2016-04-24
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2018-06-09
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多