2011-01-08 39 views
1

以下是GLSL覆蓋摻合物算法的實現,從OpenGL的Shading®語言繪製,第三版:如何將GLSL疊加混合轉換爲OpenGL ES 1.1?

12年6月19日疊加

OVERLAY首先計算基準值的亮度 。

如果亮度值小於 0.5,則將混合值和基準值相乘。

如果亮度值大於0.5,則執行屏幕操作。

效果是基準值是 與混合值混合在一起,而不是 被替換。這允許 圖案和顏色覆蓋 基本圖像,但保留基礎圖像中的陰影和高光 。

在亮度 = 0.5時發生不連續。爲了提供平滑過渡,我們實際上對 範圍[0.45,0.55]內的兩個亮度等式進行了線性混合。

float luminance = dot(base, lumCoeff); 

if (luminance < 0.45) 

    result = 2.0 * blend * base; 

else if (luminance > 0.55) 

    result = white - 2.0 * (white - blend) * (white - base); 

else { 

    vec4 result1 = 2.0 * blend * base; 
    vec4 result2 = white - 2.0 * (white - blend) * (white - base); 
    result = mix(result1, result2, (luminance - 0.45) * 10.0); 

} 

我將如何實現在OpenGL ES 1.1類似(針對iPhone 3G),不使用着色?我可以使用混合函數或紋理合並來實現這一點嗎?

+0

布拉德,謝謝。 我發現石英2D具有混合函數CGContextSetBlendMode,我可以用它代替opengl-es – Cylon 2011-01-10 12:14:45

回答

1

有關記錄留下一個答案,假設沒有進一步的優化可以使的目的,你可以:

1)負載亮度值到alpha通道

設置一個幀緩衝對象,與原始紋理大小相同。使用glColorMask來啓用或禁用寫入不同的通道。首先,啓用紅色,綠色和藍色通道並禁用Alpha通道。正常繪製紋理。這將複製紋理的顏色信息。

然後啓用alpha通道和禁用紅色,綠色和藍色通道。使用DOT3延伸(從一開始就已經支持在iPhone上)與亮度值來填充目標alpha通道。

2)拆分紋理成三個紋理,基於亮度

一個簡單的方案將只是在亮度= 0.5分裂並忽略線性混合。如果你這樣做,你可以再次使用framebuffer對象來分割GPU上的紋理。此時使用Alpha函數(glAlphaFunc並且一定要啓用它)來傳遞所有這些領域與α大於0.50繪製一個紋理,繪圖到另一個時通過所有這些特徵與α小於0.50。

雖然可以做只有一個每像素阿爾法測試,這意味着不能在單個步驟中的範圍0.45分離出〜0.55,可以這樣做,在兩個步驟。

3)使用正常混合模式到複合材料中的兩個或三個紋理到您的幀緩衝區

可以顛覆照明系統,以抵消並在必要時在渲染期間縮放alpha通道。


顯然你會通過執行那些相同的每一個取水只有一次的步驟,在啓動優化。這可能意味着永久性地將當前一個紋理存儲爲兩個或三個紋理。

+0

很好的解決方案! – Cylon 2011-01-12 04:46:19