Swift 从头开始创建纯色纹理
我正在创建一个引擎,需要一个虚拟的单像素纹理的对象没有一个所需的材料。它应该是4通道纹理,示例调用可以如下所示:Swift 从头开始创建纯色纹理,swift,metal,Swift,Metal,我正在创建一个引擎,需要一个虚拟的单像素纹理的对象没有一个所需的材料。它应该是4通道纹理,示例调用可以如下所示: let dummy = device.makeSolidTexture(device: device, color: simd_float4(0, 0, 1, 1))! 我正在使用的代码 extension MTLDevice { func makeSolidTexture(device: MTLDevice, col
let dummy = device.makeSolidTexture(device: device, color: simd_float4(0, 0, 1, 1))!
我正在使用的代码
extension MTLDevice {
func makeSolidTexture(device: MTLDevice,
color: simd_float4,
pixelFormat: MTLPixelFormat = .bgra8Unorm) -> MTLTexture? {
let descriptor = MTLTextureDescriptor()
descriptor.width = 1
descriptor.height = 1
descriptor.mipmapLevelCount = 1
descriptor.storageMode = .managed
descriptor.arrayLength = 1
descriptor.sampleCount = 1
descriptor.cpuCacheMode = .writeCombined
descriptor.allowGPUOptimizedContents = false
descriptor.pixelFormat = pixelFormat
descriptor.textureType = .type2D
descriptor.usage = .shaderRead
guard let texture = device.makeTexture(descriptor: descriptor) else {
return nil
}
let origin = MTLOrigin(x: 0, y: 0, z: 0)
let size = MTLSize(width: texture.width, height: texture.height, depth: texture.depth)
let region = MTLRegion(origin: origin, size: size)
withUnsafePointer(to: color) { ptr in
texture.replace(region: region, mipmapLevel: 0, withBytes: ptr, bytesPerRow: 4)
}
return texture
}
}
问题是,当我在捕获帧后检查纹理时,我看到:
我错过了什么?为什么是黑色的?原来我在那里犯了两个错误。首先,纹理必须对齐到256字节,因此考虑到像素格式满足要求,我将大小扩展到8 x 8。我的第二个错误是直接从float vector创建纹理。纹理的基本类型将数字存储在0-255范围内,因此传递给函数的浮点向量必须缩放,然后转换为
simd\u uchar4
类型
下面是它应该是什么样子
extension MTLDevice {
func makeSolid2DTexture(device: MTLDevice,
color: simd_float4,
pixelFormat: MTLPixelFormat = .bgra8Unorm) -> MTLTexture? {
let descriptor = MTLTextureDescriptor()
descriptor.width = 8
descriptor.height = 8
descriptor.mipmapLevelCount = 1
descriptor.storageMode = .managed
descriptor.arrayLength = 1
descriptor.sampleCount = 1
descriptor.cpuCacheMode = .writeCombined
descriptor.allowGPUOptimizedContents = false
descriptor.pixelFormat = pixelFormat
descriptor.textureType = .type2D
descriptor.usage = .shaderRead
guard let texture = device.makeTexture(descriptor: descriptor) else {
return nil
}
let origin = MTLOrigin(x: 0, y: 0, z: 0)
let size = MTLSize(width: texture.width, height: texture.height, depth: texture.depth)
let region = MTLRegion(origin: origin, size: size)
let mappedColor = simd_uchar4(color * 255)
Array<simd_uchar4>(repeating: mappedColor, count: 64).withUnsafeBytes { ptr in
texture.replace(region: region, mipmapLevel: 0, withBytes: ptr.baseAddress!, bytesPerRow: 32)
}
return texture
}
}
// bgra format in range [0, 1]
let foo = device.makeSolid2DTexture(device: device, color: simd_float4(1, 0, 0, 1))!