Генерация градиентной текстуры изображения на iOS - PullRequest
0 голосов
/ 22 января 2019

Мне нужно сгенерировать текстуру 256x1 на iOS. У меня есть 4 цвета: красный, зеленый, желтый, синий с красным на одном конце и синий на другом, а также желтый и зеленый на 3/4-й и 1/4-й позиции соответственно. Цвета между ними должны быть линейно интерполированы. Мне нужно использовать эту текстуру в металле для поиска в шейдерном коде. Какой самый простой способ создать эту текстуру в коде?

1 Ответ

0 голосов
/ 23 января 2019

Поскольку MTKTextureLoader в настоящее время не поддерживает создание 1D-текстур (это было требованием к функциям как минимум с 2016 года), вам нужно будет создать свою текстуру вручную.

Предполагая, что ваше изображение уже загружено, вы можете запросить его CGImage, а затем использовать этот метод для извлечения данных пикселей и загрузки их в текстуру:

func texture1DForImage(_ cgImage: CGImage, device: MTLDevice) -> MTLTexture? {
    let width = cgImage.width
    let height = 0
    let bytesPerRow = width * 4 // RGBA, 8 bits per component

    let bitmapInfo: UInt32 = /* default byte order | */ CGImageAlphaInfo.premultipliedLast.rawValue
    let colorSpace = CGColorSpace(name: CGColorSpace.sRGB)!
    let context = CGContext(data: nil,
                            width: width,
                            height: height,
                            bitsPerComponent: 8,
                            bytesPerRow: bytesPerRow,
                            space: colorSpace,
                            bitmapInfo: bitmapInfo)!

    let bounds = CGRect(x: 0, y: 0, width: width, height: height)
    context.draw(cgImage, in: bounds)

    guard let data = context.data?.bindMemory(to: UInt8.self, capacity: bytesPerRow) else { return nil }

    let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .rgba8Unorm,
                                                                     width: width,
                                                                     height: height,
                                                                     mipmapped: false)
    textureDescriptor.textureType = .type1D
    textureDescriptor.usage = [ .shaderRead ]

    let texture = device.makeTexture(descriptor: textureDescriptor)!
    texture.replace(region: MTLRegionMake1D(0, width), mipmapLevel: 0, withBytes: data, bytesPerRow: bytesPerRow)

    return texture
}
...