ios - Metal 中的纹理阵列

标签 ios swift metal metalkit

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。如何将三个纹理绑定(bind)到一个数组并将其传递给着色器。

在 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);

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

最佳答案

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

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


已编辑问题的更新:

您混淆了of 纹理数组(也称为纹理数组)和数组纹理。术语含糊不清。

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

您使用了 texture2d_array<...> .那是一个数组纹理。

对于纹理数组或纹理数组,您应该使用 array<texture2d<float, access::sample>, 3> clouds [[texture(0)]] .

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

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

关于ios - Metal 中的纹理阵列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54232666/

相关文章:

swift - 应用程序崩溃 - 未加载 AuthenticationServices 库

xcode - 启用 GPU 帧捕获

javascript - 在触摸设备上捏合缩放

ios - 关闭模态视图 Controller

ios - 失败: responseSerializationFailed(reason: Alamofire. AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

objective-c - 如何在 Swift 中采用具有一个属性的 Obj-C 协议(protocol)?

ios - 当应用程序进入后台时,iOS 显示的图像在纵向模式下显示倒置

ios - 应用程序在 iPhone 6 中崩溃

ios - 将 SkeneKit 场景捕获为视频

xcode - 将每个 .metal 文件编译成单独的 .metallib