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. Как я могу привязать три текстуры к массиву и передать ему шейдер.
На стороне процессора я создал три текстуры и создал массив 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);
Я делаю это в настоящее время, но я не смог получить правильный вывод текстуры





Вам не нужно менять код приложения. Поскольку вы используете последовательные индексы текстур, вы можете просто заменить три отдельных параметра одним параметром массива текстур, привязанным к индексу 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);
Вам нужно будет пройти тест, чтобы узнать. Я думаю, что использование массива текстур должно быть как минимум таким же быстрым, как и код ручного переключения.
Редактировал вопрос. Я пробовал описанным выше способом. Но мне не удалось получить правильную текстуру на экране и он мигает ... Раньше у меня без массива все работало нормально ... Что пошло не так ...