#ios #macos #texture-mapping #metal #porter-duff
#iOS #macos #отображение текстур #Металлические #porter-duff
Вопрос:
В приложении Metal для iOS мне нужно отобразить полупрозрачную текстуру, прикрепленную к простому квадрату. Я не могу определить правильные коэффициенты цветового сочетания rgb и alpha.
Моя настройка:
1) Красное изображение, созданное в Photoshop с 50% непрозрачностью. Сохранено в формате PNG с прозрачностью. Изображение хранится в папке «Мои ресурсы проекта».
2) Я создаю текстуру металла, сначала создавая, UIImage
затем используя .cgImage
— CoreImage — field для извлечения данных изображения. Теперь это изображение в предварительно умноженном формате, поэтому можно применять классические формулы Портера-Даффа. Подробнее об этом позже.
// load hero texture
do {
let textureLoader = MTKTextureLoader(device: device)
guard let image = UIImage(named:"red_translucent") else {
fatalError("Error: Can not create UIImage")
}
if (image.cgImage?.alphaInfo == .premultipliedLast) {
print("texture uses premultiplied alpha. Rock.")
}
heroTexture = try textureLoader.newTexture(with: image.cgImage!, options: nil)
} catch {
fatalError("Error: Can not load texture")
}
3) Вот мой довольно скучный шейдер фрагмента текстуры
fragment float4 textureFragmentShader(_Vertex_ vert [[ stage_in ]], texture2d<float> texas [[ texture(0) ]]) {
constexpr sampler defaultSampler;
float4 rgba = texas.sample(defaultSampler, vert.st).rgba;
return rgba;
}
4) Это мои настройки коэффициента смешивания colorAttachment, которые являются формулой «поверх» Портера-Даффа:
descriptor.colorAttachments[ 0 ].isBlendingEnabled = true
descriptor.colorAttachments[ 0 ].rgbBlendOperation = .add
descriptor.colorAttachments[ 0 ].alphaBlendOperation = .add
descriptor.colorAttachments[ 0 ].sourceRGBBlendFactor = .one
descriptor.colorAttachments[ 0 ].sourceAlphaBlendFactor = .one
descriptor.colorAttachments[ 0 ].destinationRGBBlendFactor = .oneMinusSourceAlpha
descriptor.colorAttachments[ 0 ].destinationAlphaBlendFactor = .oneMinusSourceAlpha
5) Когда я визуализирую квадрат с этой красной полупрозрачной текстурой поверх белого фона, изображение получается слишком темным. Неправильный рендеринг (правильное изображение) равен rgb = (182, 127, 127). Правильное изображение из Photoshop — rgb (255, 127, 127):
Каковы правильные функции смешивания?
Обновить
Если люди хотят взглянуть на код, он находится на Github здесь:https://github.com/turner/HelloMetal/tree/2_pass_render
Комментарии:
1. Я не могу воспроизвести это с текстурой, сгенерированной вручную. Вы использовали
getBytes
для проверки фактических значений пикселей в текстуре? Вы также можете попробовать передатьMTKTextureLoaderOptionSRGB
(=false
) параметр при загрузке, чтобы убедиться, что вы случайно не получаете текстуру sRGB, которая может казаться темнее, если исходные данные на самом деле не находятся в пространстве sRGB.2. Привет, Уоррен, я попробую это. Проект находится на Github здесь, если вы хотите взглянуть: github.com/turner/HelloMetal/tree/2_pass_render . Это ветвь с именем 2_pass_render.
3. Бинго! отключение sRGB сделало свое дело. Неплохо. Спасибо, Уоррен,
Ответ №1:
Решением — по предложению Уоррена — было установить MTKTextureLoaderOptionSRGB
параметр на false
.