64K色模式下的快速Alpha混合演算法(轉)
64K色模式下的快速Alpha混合演算法(轉)[@more@] 在32/64K色模式下,由於每個點的RGB值是放在一個字裡,以16位色為例,一般是按RGB或BGR 565存放。傳統的軟體Alpha混合演算法是先將RGB分離出來,分開運算,然後再合成。這造成了16位模式下的alpha混合比24位模式下慢 的現象,但使用16位色真的那麼慢嗎?我認為如果不使用MMX指令,15/16的比24位的快。因為我們可以使用一個小的技巧來同時計算RGB。而24位顏色,除非使用MMX指令,否則必須分開計算R、G、B。 先設顏色(color)是RGB 565的,那麼按二進位制看,這個顏色字是這樣分佈的: RRRRR GGGGGG BBBBB 5位 6位 5位 RGB成分 而386以上CPU都有32位的暫存器,我們只需要將16位RGB變形為: 00000 GGGGGG 00000 RRRRR 000000 BBBBB 5位 6位 5位 5位 6位 5位 變形後的RGB成分 儲存在32位暫存器中,(就是把綠色提到前16位裡)由於64K色下顏色深度是32級的,所以alpha也只用分32級就能滿足需要。那麼對上面變形過的雙字處理,可以同時算RGB了。(Color1*Alpha+Color2*(32-Alpha))/32能不能簡化為(Color1-Color2)*Alpha/32+Color2?我思考過這個問題,以為減法將產生負數,這樣再算乘法時有可能出問題,但是經過測試,這樣簡化似乎又沒有問題。畢竟極小的誤差是可以忽略的。 最近溫習了一下彙編,今天用NASM寫了個C可呼叫的Alpha混合函式(32位模式,我針對DJGPP寫的)並進行了Pentium最佳化(針對雙流水線,有錯請指出)。大家看看,有BUG,還能最佳化或有更快的方法也請一定告訴我。順便提一下,上面提到的化簡沒有體現到下面的程式中,而且,使用乘法本身是個錯誤。只是看看吧,如果你想實際運用,請參考Allegro程式庫的做法。 ; 對16位的color1與color2進行Alpha混合 ; R=(r1*alpha+r2*(32-alpha))/32 ; G=(g1*alpha+g2*(32-alpha))/32 ; B=(b1*alpha+b2*(32-alpha))/32 ; C 語言呼叫函式(32 位保護模式)Pentium雙流水線最佳化 ; By Cloud Wu (cloudwu@263.net) ; (~cloudwu) ; ------------------------------------------------------------------------- ; unsigned long alpha (unsigned long c1,unsigned long c2,unsigned long alpha); ; ------------------------------------------------------------------------- ; c1: 顏色1的RGB(565),c2: 顏色2的RGB(565),alpha: Alpha值(0~31) ; NASM 編譯透過 [BITS 32] [GLOBAL _alpha] [SECTION .text] _alpha: ; 初始化程式碼 push ebp ; ebp 壓棧 mov ebp,esp ; 儲存 esp 到 ebp mov edi,0x7e0f81f ; dx=00000111111000001111100000011111 add esp,8 ; esp 指向引數 c1 pop eax ; 彈出 c1 到 ax pop ebx ; 彈出 c2 到 bx ; 處理顏色 mov cx,ax ; cx=r1..b1 mov dx,bx ; dx=r2..b2 sal eax,16 ; eax=r1g1b1...... sal ebx,16 ; ebx=r2g2b2...... mov ax,cx ; eax=r1g1b1r1g1b1 mov bx,dx ; ebx=r2g2b2r2g2b2 and eax,edi ; eax=..g1..r1..b1 pop esi ; 彈出 alpha mul esi ; eax*=alpha neg esi ; -alpha and ebx,edi ; ebx=..g2..r2..b2 add esi,0x20 ; 32-alpha xchg eax,ebx ; 交換 eax,ebx mul esi ; c2*=(32-alpha) add eax,ebx ; c1*alpha+c2*(32-alpha) mov esp,ebp sar eax,5 ; color=(c1*alpha+c2*(32-alpha))/32 ;還原成 RGB 形式 pop ebp and eax,edi ; color=..g..r..b mov cx,ax ; sar eax,16 ; or ax,cx ; color=rgb (eax) ret 如果建一張256K的表來查表預處理RGB怎樣?經過嘗試,發現速度不僅沒有提高,反而降低了。分析的結論是,256K的表太大了,以至於不能放到快取(Cache)裡,反而沒有計算的方法快,畢竟計算的話,每行的程式碼都很快,而不必和記憶體打交道。真正加速的方法是什麼?借鑑Allegro程式庫裡的方法,建立32個函式分別計算每個alpha值的情況。這樣,alpha值變成固定的,從而可以使用LEA、ADD、SUB、SAL、SAR來替代緩慢的MUL。經過實踐,我重寫了Allegro程式庫裡的cblend15.c及cblend16.c,(使用程式庫自己的Test.exe,機器配置為Cyrix Gx/120 S3/375 4M)測試資料如下: 原有的混合函式 使用新演算法的混合函式 將Blender函式置為空 1402 per sec 1779 per sec 2002 per sec 呵呵,速度提高了一倍不是嗎?Allegro庫目前的版本已經使用了我寫的blender函式。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-952246/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用MMX最佳化64K色Alpha混合演算法(轉)演算法
- 16位Alpha混合的簡單演算法 (轉)演算法
- 遊戲開發學堂:2D模式下的alpha混合(轉)遊戲開發模式
- Shader 中的顏色混合模式(Blend Mode)模式
- 能是最快的演算法alpha blend彙編原始碼 (轉)演算法原始碼
- RGBa顏色 css3的Alpha通道支援CSSS3
- CSS 顏色混合的N種方式CSS
- 混合使用Direct3D立即模式和保留模式(轉)3D模式
- 使用CSS混合模式和SVG來動態更改產品圖片的顏色CSS模式SVG
- Golang三色標記、混合寫屏障GC模式圖文全分析GolangGC模式
- 專案化管理的快速模式(轉)模式
- Photoshop圖層混合模式計算公式大全(轉)模式公式
- 形形色色的自定義訊息(下) (轉)
- 樹型論壇的快速演算法 (轉)演算法
- 思科Dave West:世界未來必將轉向混合模式模式
- Alpha上安裝Linux(轉)Linux
- dui框架開發系列:32位和565BMP的ALPHA混合和資源打包UI框架
- PS圖層混合演算法之一(不透明度,正片疊底,顏色加深,顏色減淡)演算法
- 帶你認識Photoshop的混合模式模式
- [Golang三關-典藏版] Golang三色標記混合寫屏障GC模式全分析GolangGC模式
- C#演算法-------(四)快速排序 (轉)C#演算法排序
- 玩轉混合加密加密
- 混合式 App 開發模式下的熱更新技術方案,你知道多少?APP模式
- RenderTexture用在RawImage上時要注意的顏色混合問題
- MAC下嘗試PHP7 alpha版本的安裝MacPHP
- 強大的CSS:濾鏡和混合模式處理的圖片如何上傳下載?CSS模式
- 不可思議的混合模式 background-blend-mode模式
- 計算機中的顏色XIV——快速變換顏色的V分量計算機
- 配置方法數超過 64K 的應用
- 設計模式學習筆記(二)工廠模式、模板模式和策略模式的混合使用設計模式筆記
- 高斯混合模型(GMM)及其EM演算法的理解模型演算法
- 淺談顏色模式模式
- 顏色空間系列4: RGB和YDbDr顏色空間的轉換及優化演算法優化演算法
- 混合運算中資料型別的轉換 (轉)資料型別
- DarkMode(4):css濾鏡 顏色反轉實現深色模式CSS模式
- Mozilla Firefox 2.0 Alpha1 for Linux(轉)FirefoxLinux
- HexMap學習筆記(二)——單元格顏色混合筆記
- 一文詳解 OpenGL ES 紋理顏色混合