2013-02-19 100 views
7

我想在WebGL中做一些圖像處理。但是,如果我嘗試在移動設備上的GLSL紋理中加載大圖片(來自相機 - 8 MP),則瀏覽器會崩潰。小圖片工作正常。所以我認爲它的內存不足。WebGL - 如何渲染大質感?

我搜索了很多,但沒有找到解決方案。我認爲最好的方法是實施「基於圖塊」的渲染。將8MP圖片分成較小的部分,渲染並粘貼在一起。但會有問題,如應用模糊效果。你會看到「子渲染」的邊緣。所以我必須渲染重疊像素並將它們「淡化」在一起。聽起來不太好。

有沒有我沒有想到的解決方案?如何在移動設備上使用真正巨大的紋理?

+0

我見過一個很好的基於圖片的WebGL處理的例子[here](http://media.tojicode.com/zelda/lttp.html)。它適用於我的Nexus 7。 – 2013-02-19 08:44:54

+0

不是我要找的。他在一塊大帆布上畫了許多瓷磚。我正在尋找將着色器效果應用到大圖像的解決方案。不知道最好的方法是什麼。使用「基於圖塊的渲染」我的意思是,將大圖片分割成許多小圖片並將着色器應用於每個小圖片。把所有的東西放在一起。但是這對於一些效果不太好,比如模糊效果。在模糊(或銳化)時,您必須考慮周圍的像素。所以,如果你模糊每一個小圖像並把它們放在一起,你會看到每個小圖像的邊緣。 – 2013-02-19 11:07:12

+0

所以我的問題是,如何處理WebGL中的大圖像/紋理?那裏有什麼可能性? – 2013-02-19 11:08:20

回答

3

你需要做什麼才能讓你的瓷磚工作,在邊界處提供足夠的輸入以覆蓋圖像處理效果的非局部性 - 例如,模糊內核的半徑。我能想到的最簡單的事情是:

對於輸出圖像的每個拼貼,加載對應的輸入拼貼及其8個鄰居。然後使用全部9作爲輸入來運行模糊濾鏡:在那裏你通常會調用texture2D,而不是使用一個(自定義)函數,該函數會獲取座標並在9個紋理中的適當紋理中查找它們。

要使用較少的紋理,請將輸出切片與輸入切片相比在兩個維度上偏移一半邊長;那麼您只需要爲每個瓦片計算使用4個輸入瓦片,但是如果使用足夠的瓦片來覆蓋所有輸入,則在輸出瓦片中將會有額外的邊框。 (另一方面,如果你在後面修剪時很聰明,這可能是件好事;例如,如果我將陰影應用於輸入圖像,就像那樣會使陰影放大輸出,而不是在原始邊界處被截斷)。

如果您正確地做到了這一點,應該有瓷磚邊界的工件。 (免責聲明:雖然這個解決方案對我來說看起來很簡單,明顯並且正確,但我不是圖像處理或GPU資源保護方面的專家。可能有這樣的理由:爲什麼這種方法實際上並不奏效,或者有更好的想法在那裏。)

+0

這是一個非常好的主意,不需要爲每個瓷磚添加一些「邊距」和「褪色」在一起計算。您的解決方案應該更易於實施。謝謝! :)也許有更好的GLSL解決方案?任何專業人士? – 2013-02-20 07:31:04

2

這是不可能的,一個8mp圖像將超過可用的RAM。在RGB(字節)它將佔用24MB的內存。即使在半浮點精度,它也會是50MB的內存。 ARM系統使用統一的RAM架構,GPU和CPU共享內存。 iPhone例如有1g的ram可用。

紋理支持應達到所需的大小(例如3264x2248),這對高端手機來說似乎沒有問題(81% of mobiles支持4096x4096)。

最大繪圖緩衝區大小可能小於最大支持的紋理大小(可以是query that)。

除此之外,您可能只是遇到了一個煩人的bug。所以處理這個問題的方法是,將圖像細分爲更小的圖塊並逐個處理每個圖塊。

如果您有過濾器內核,您可以通過兩種方式處理邊界。

  • 你可以通過在9個紋理和紋理查找分支來解決正確的(可能是緩慢的,有些GPU不支持分支,將執行所有codepaths)。邊框紋理只是2x2,所以會有很小的內存佔用。請注意,紋理之間不會有插值,所以不要依賴它,或者替換自己的。
  • 在預處理步驟中,您可以在每個圖塊周圍添加半個內核大小的邊框,以獲取來自相鄰圖塊的像素。
+0

這非常有幫助,非常感謝!在桌面瀏覽器中,所有工作都很好,在移動設備上崩潰。我想到了有限的記憶,但你說得對,應該有足夠的內存。所以我將首先實現一些GL函數調用日誌記錄,並查看它在哪個調用中崩潰。再次感謝您的精彩文章! – 2013-02-23 15:38:11