2012-01-25 237 views
6

我正在使用OpenGL 2.0的2D iOS遊戲,我想知道是否有可能寫一個着色器,將輪廓圖像與輝光。所有的圖像都是2D精靈。我所看到的着色器示例是用於3D對象的,因此我不確定2D圖像是否可能。OpenGL ES着色器輪廓2D圖像

+0

所以你想添加的輝光就像是陰影? –

+0

圖像周圍會有柔和的邊緣。 –

回答

7

您是否接受邊緣檢測濾鏡(如Sobel),產生如the Wikipedia article所示的圖像,然後對其結果進行高斯模糊處理,以柔化邊緣並給予其更多輝光,然後合成該圖像到你的場景?

實際上,您可能只需重複使用您所見過的3d輪廓着色器 - 儘管您可以在理論上檢查深度數量(在ES中進行了一些擴展工作),但我見過的每一個對於渲染的圖像。

編輯:在進一步的考慮中,拉普拉斯可能比索貝爾更容易應用,因爲它可以作爲一個簡單的卷積着色器(如地址like this所述)完成。儘管爲了在移動設備上安全起見,您可能最多需要堅持使用3x3內核,併爲每種效果編寫不同的着色器,而不是使用數據來完成。所以例如粗略的高斯模糊,寫出長度:

void main() 
{ 
    mediump vec4 total = vec4(0.0); 
    mediump vec4 grabPixel; 

    total +=  texture2D(tex2D, texCoordVarying + vec2(-1.0/width, -1.0/height)); 
    total +=  texture2D(tex2D, texCoordVarying + vec2(1.0/width, -1.0/height)); 
    total +=  texture2D(tex2D, texCoordVarying + vec2(1.0/width, 1.0/height)); 
    total +=  texture2D(tex2D, texCoordVarying + vec2(-1.0/width, 1.0/height)); 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(0.0, -1.0/height)); 
    total += grabPixel * 2.0; 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(0.0, 1.0/height)); 
    total += grabPixel * 2.0; 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(-1.0/width, 0.0)); 
    total += grabPixel * 2.0; 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(1.0/width, 0.0)); 
    total += grabPixel * 2.0; 

    grabPixel = texture2D(tex2D, texCoordVarying); 
    total += grabPixel * 4.0; 

    total *= 1.0/16.0; 

    gl_FragColor = total; 
} 

而拉普拉斯邊緣檢測結果看起來相似,但具有不同的常量。

作爲一種優化,您應該儘可能在頂點着色器而不是片段着色器中計算相對採樣點,因爲這樣做會避免依賴紋理讀取。

+0

也許我沒有看正確的3D,但我看到的那些似乎在某種程度上對光源進行操作,而我沒有給出它的2D。我對着色器很陌生,所以我可能忽略了這裏的明顯。 –

+0

許多後噴射式無線電單元着色器通過將邊緣定義爲前向邊緣和後向邊緣之間的連接來使用相機位置來檢測邊緣。你顯然無法使用其中的一種。但是像索貝爾和拉普拉斯算子這樣的方法在二維圖像中尋找顏色不連續性以識別邊緣,所以完全合適。在卷積濾波器上進行讀取可能很明智,如果您還沒有,那麼可以研究拉普拉斯和高斯模糊。我爲後者添加了一些匆忙組裝的示例代碼。 – Tommy