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] = []
然后我将Texture附加到该数组。 在MTLRenderCommandEncoder
let myRange: CountableRange = 0..<2
commandEncoder.setFragmentTextures(textureArray, range: myRange)
在着色器中
texture2d_array<float , access::sample> texture [[ texture(0) ]]
在Shader中采样
float4 color = texture.sample(defaultSampler, float2(params.textureCoordinates),0) * float4(1,0,0,1.0);
我目前正在这样做,但是我无法获得正确的Texture输出
答案 0 :(得分:2)
您不必更改应用程序代码。由于您使用的是连续的纹理索引,因此您只需将三个单独的参数替换为绑定到索引0的单个纹理数组参数,绑定将使用您从应用程序代码提供的纹理将数组的元素连接起来。>
换句话说,如果您声明一个大小为3并绑定到纹理索引0的纹理数组,则该数组的元素将从纹理索引0、1和2中获取。
针对您已编辑的问题进行更新:
您正在混淆 个纹理数组(也称为纹理数组)和一个数组纹理。术语令人困惑。
您使用了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);