小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

圖片Premultiplied Alpha到底是干嘛用的

 老匹夫 2019-10-21

Premultiplied Alpha 這個(gè)概念做游戲開發(fā)的人都不會(huì)不知道。Xcode 的工程選項(xiàng)里有一項(xiàng) Compress PNG Files,會(huì)對(duì) PNG 進(jìn)行 Premultiplied Alpha,Texture Packer 中也有Premultiplied Alpha 的選項(xiàng)。那么問題來了,Premultiplied Alpha 是什么呢?我被這個(gè)問題困惑了很久,之前搜到過 Nvidia的這篇文章,其實(shí)說的很清楚,只是當(dāng)時(shí)有很多相關(guān)概念沒搞清楚,所以沒看懂。直到前幾天讀《Real Time Rendering》時(shí)終于搞懂了。

Alpha Blending

要搞清楚這個(gè)問題,先得理解Alpha通道的工作原理,如果你已經(jīng)了解可以直接跳過。

最常見的像素表示格式是RGBA8888即 (r, g, b, a),每個(gè)通道8位,0-255。例如紅色60%透明度就是 (255, 0, 0, 153),為了表示方便alpha通道一般記成正規(guī)化后的0-1的浮點(diǎn)數(shù),也就是 (255, 0, 0, 0.6)。而 Premultiplied Alpha 則是把RGB通道乘以透明度也就是 (r a, g a, b * a, a),50%透明紅色就變成了(153, 0, 0, 0.6)。

透明通道在渲染的時(shí)候通過 Alpha Blending 產(chǎn)生作用,如果一個(gè)透明度為 as 的顏色 Cs 渲染到顏色 Cd上,混合后的顏色通過以下公式計(jì)算,

Co=αsCs+(1?αs)Cd

以60%透明的紅色渲染到白色背景為例:

Co=(255,0,0)?0.6+(255,255,255)?(1?0.6)=(255,102,102)

也就是說,從視覺上,(255, 0, 0, 0.6)渲染到白色背景上 和 (255, 102, 102) 是同一個(gè)顏色。如果顏色以 Premultiplied Alpha 形式存儲(chǔ),也就是Cs已經(jīng)乘以透明度了,所以混合公式變成了:
Co=Cs+(1?αs)Cd

為什么要 Premultiplied Alpha 呢?

Premultiplied Alpha 后的像素格式變得不直觀,因?yàn)樵诋媹D的時(shí)候都是先從調(diào)色板中選出一個(gè)RGB顏色,再單獨(dú)設(shè)置透明度,如果RGB乘以透明度就搞不清楚原色是什么了。從前面的 Alpha Blending 公式可以看出,Premultiplied Alpha 之后,混合的時(shí)候可以少一次乘法,這可以提高一些效率,但這并不是最主要的原因。最主要的原因是:

沒有 Premultiplied Alpha 的紋理無法進(jìn)行 Texture Filtering(除非使用最近鄰插值)。

以最常見的 filtering 方式線性插值為例,一個(gè)寬2px高1px的圖片,左邊的像素是紅色,右邊是綠色10%透明度,如果把這個(gè)圖片縮放到1x1的大小,那么縮放后1像素的顏色就是左右兩個(gè)像素線性插值的結(jié)果,也就是把兩個(gè)像素各個(gè)通道加起來除以2。如果使用沒有 Premultiplied Alpha 的顏色進(jìn)行插值,那么結(jié)果就是:

((255,0,0,1)+(0,255,0,0.1))?0.5=(127,127,0,0.55)

如果綠色 Premultiplied Alpha,也就是 (0, 255 * 0.1, 0, 0.1),和紅色混合后:

((255,0,0,1)+(0,25,0,0.1))?0.5=(127,25,0,0.55)

圖片描述

從上面的圖里第三個(gè)顏色是沒有 Premultiplied Alpha 的混合結(jié)果,對(duì)比第四個(gè) Premultiplied Alpha 后顏色的結(jié)果,顯然第四個(gè)顏色更符合直覺,第三個(gè)顏色太綠了,因?yàn)榫G色通道沒有乘以透明度,所以在線性插值的時(shí)候占了過大的權(quán)重。

所以 Premultiplied Alpha 最重要的意義是使得帶透明度圖片紋理可以正常的進(jìn)行線性插值。這樣旋轉(zhuǎn)、縮放或者非整數(shù)的紋理坐標(biāo)才能正常顯示,否則就會(huì)像上面的例子一樣,在透明像素邊緣附近產(chǎn)生奇怪的顏色。

紋理處理

我們使用的PNG圖片紋理,一般是不會(huì) Premultiplied Alpha 的。游戲引擎在載入PNG紋理后回手動(dòng)處理,然后再glTexImage2D傳給GPU,比如 Cocos2D-x 中的 CCImage::premultipliedAlpha:

void Image::premultipliedAlpha() {
    unsigned int* fourBytes = (unsigned int*)_data;
    for (int i = 0; i < _width * _height; i++) {
        unsigned char* p = _data + i * 4;
        fourBytes[i] = CC_RGB_PREMULTIPLY_ALPHA(p[0], p[1], p[2], p[3]);
    }  
    _hasPremultipliedAlpha = true;
}

而GPU專用的紋理格式,比如 PVR、ETC 一般在生成紋理都是默認(rèn) Premultiplied Alpha 的,這些格式一般是GPU硬解碼,引擎用CPU處理會(huì)很慢。

總之 glTexImage2D 傳給 GPU 的紋理數(shù)據(jù)最好都是 Multiplied Alpha 的,要么在生成紋理時(shí)由紋理工具 Pre-multiplied,要么載入紋理后由游戲引擎或UI框架 Post-multiplied。

原文地址:http:///2015/07/wh...

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多