我使用一个SKMutableTexture来渲染游戏中的可破坏地面。无论出于何种目的,这都非常有效,除非我想将透明像素渲染到可变纹理中已经存在非透明像素的位置。
我为RGBAColor创建了一个结构,如下所示:

struct RGBAColor {

    var r: UInt8
    var g: UInt8
    var b: UInt8
    var a: UInt8


    static var clear    = RGBAColor(r: 0, g: 0, b: 0, a: 0)
}

然后我修改SKMutableTexture,如下所示:
self.texture.modifyPixelData({ (voidptr, len) in

            let bytes = voidptr!.assumingMemoryBound(to: RGBAColor.self)

            for (index, color) in self.modifiedPixels {
                bytes[index] = color
                self.pixels[index] = color
            }

        })

.. 其中“modified pixels”是一个类似于[Int:RGBAColor]的字典(为了不更新纹理中的所有像素-仅更新已修改的像素)。
当颜色的alpha(a)>0时,它的工作原理与我的预期一致。。但不是当它是0(它就像像素渲染在现有纹理之上)。也不像你在修改实际的像素数据)。
我做错什么了吗?或者这是故意的行为?

最佳答案

SKMutableTexture文档中,
您提供的颜色组件应该已经被倍增了
按alpha值。
通常,如果你想要一种α为0.5的红色,你可以使用RGBA组件

(red:1.0, green:0.0, blue:0.0, alpha:0.5)

预乘alpha颜色的等价物是
(red:0.5, green:0.0, blue:0.0, alpha:0.5)

其中RGB分量已乘以alpha值。
对于您的特定情况,您可以向Color结构添加初始值设定项来执行乘法。有一种方法可以实现。。。
首先,定义一个扩展,将aUInt8按aFloat值缩放
extension UInt8 {
    func scaled(by value:Float) -> UInt8 {
        var scale = UInt(round(Float(self) * value))
        scale = Swift.min(scale, UInt(UInt8.max))
        return UInt8(scale)
    }
}

然后添加一个初始值设定项,该初始值设定项自动将组件乘以alpha值
struct Color {
    var red:UInt8
    var green:UInt8
    var blue:UInt8
    var alpha:UInt8

    init(red:UInt8,green:UInt8,blue:UInt8,alpha:UInt8) {
        let alphaScale = Float(alpha) / Float(UInt8.max)
        self.red = red.scaled(by: alphaScale)
        self.blue = blue.scaled(by: alphaScale)
        self.green = green.scaled(by: alphaScale)
        self.alpha = alpha
    }
}

然后,可以创建一种颜色,该颜色的alpha值为0.5
let color = Color(red:255, green:0, blue:0, alpha:127)

完全透明的颜色
let color = Color(red:255, green:0, blue:0, alpha:0)

09-10 00:40
查看更多