2013-03-19 78 views
0

我在純Java中創建2D自上而下的平鋪遊戲,現在我試圖實現一種照明方式。Java中的2D軟件照明問題

首先,我如何渲染一些細節:有一個屏幕類來處理所有的渲染。像素放在int[width * height]陣列內,該陣列使用BufferedImageGraphics.drawImage()在實際屏幕上繪製。

我現在正在照明的方式是通過創建第二個int[width * height]數組來保存應從實際像素中減去的所有亮度。我嘗試使用浮動範圍從0f1f來表示RGB強度。

因此,作爲一個例子,存在0.3f的環境照明。我所做的是像素到像素操作,其中對於將要繪製的每個像素,其RGB值將被分解,減少70%(1f - 0.3f),重新組合爲一個int並存儲在次要int[width * height]陣列中。將像素傳輸到BufferedImage時,我會減去次級陣列中的相應值,並按預期得到較暗的圖像。

這是一個使圖像變暗的例子,它可以很好地工作,問題出現在實際點亮它們時:我給玩家一個lightRadius和三個淺色分量浮動(RGB)。而呈現播放器,我也使其通過執行的輔助陣列內照明如下:

int mask = subtractMask[xx + yy * width]; 

int mr = (mask >> 16) & 255; 
int mg = (mask >> 8) & 255; 
int mb = mask & 255; 

mr -= (int) (dist * light.r * mr); 
mg -= (int) (dist * light.g * mg); 
mb -= (int) (dist * light.b * mb); 

subtractMask[xx + yy * width] = mr << 16 | mg << 8 | mb; 

凡DIST是一個數字範圍從0f1f這使得從源極和light.r/g/b被遠處的光褪色來自玩家的光的每個組成部分。 這段代碼的功能基本上是「將一點像素從像素中提取出來」。正如你所看到的,mr,mg和mb被製作得較小( - =),然後在從相應像素中減去的數字內部組成,從而使得減法的結果變得更大(更輕)。 對於白光我獲得所需的結果:

While light with 50 pixel radius

問題是,當我只用藍色分量(R = 0F,G = 0F,B = 1F),得到這樣的:Blue Light with the same 50 pixel radius

當然,這可以通過瓦片具有非常小的藍色值的事實來解釋,使得環境光線佔據它的一小部分,並使得照明將其一小部分帶回(正如您可以看到的最大效果是在玩家的褲子上,這是藍色的)。 我仍然無法想到的一種方法是使照明不受像素帶走多少亮度的影響,以及以任何方式將各個組件合併在一起看起來不錯的東西(我期望得到的第二張圖像的結果是亮度像第一個一樣,但藍色)。那麼我怎麼能實現這樣的效果呢?

此外,爲了使照明循環,我只需計算一些光x^2 + y^2 < = radius^2,如果這句話是真的,像素應該點亮,執行我已經顯示的代碼之前。有更快的方法來計算這個嗎? (我在這個效果上損失了近50 FPS)。

編輯:我想要的效果就像2D遊戲Tibia。這是藍光在棕色像素:Tibia - Blue Light

+0

藍色是RGB中最不亮的分量(在YUV色彩空間中計算Y的經典公式是R * 0.299 + G * 0.587 + B * 0.114)。因此,如果您只應用藍光並且仍然希望具有與使用白光時相似的亮度,則必須根據您使用較暗光源的事實進行調整。 – Michael 2013-03-19 20:29:20

+0

對不起,但我並不知道YUV色彩空間的存在。我該怎麼做這樣的修正? – Thiago 2013-03-19 20:37:26

+0

它看起來像你展示的例子,大多數圖像至少有一些藍色的成分,所以光線能夠點亮它。這只是一個物理學的事實,如果你有一個物體只反射紅光和綠光,而你用純藍光點亮它,你什麼也得不到。 – 2013-03-19 21:03:36

回答

1

我認爲,可能的工作最好是添加環境和玩家的光度值第一,夾到[0 ... 1]範圍,然後乘像素值。

所以:

環境光:[0.3,0.3,0.3]
播放器的光(在某些位置):[0.0,0.0,1.0]
總光線:[0.3,0.3,1.0]

原始像素值:[100,200,100]
輸出像素值:[30,60,100]

如果這樣做,也可以只具有靜態浮動[]表示的量在每個像素點亮,changin只有當週圍環境或播放器燈光發生變化時才需要。然後,您不需要計算每幀的亮度,只需將其應用於整個圖像即可。

+0

但是我認爲通過這樣做,每個像素都有藍色的組件(比如綠草)就不會亮起來,就像現在發生的那樣。其實,我希望他們點亮,不管他們的顏色。那可能嗎? – Thiago 2013-03-19 20:31:48

+0

一種選擇是讓你的播放器變成藍色,但也有一些其他的顏色。如果是我,我會讓燈光在中心(玩家)始終處於白色,但讓紅色和綠色部件更快地褪色,以使照明區域的邊緣呈現藍色。這往往給人一個清晰的藍光印象,同時讓靠近玩家的物體仍然可以區分。 – 2013-03-19 20:37:13

+0

我認爲同樣的問題會發生:我嘗試了一些r和g的組合,並與1f的藍色相對應,我主要看到的只是r和g的影響,我認爲我做事情的方式只是照亮像素基於他們的原始顏色... – Thiago 2013-03-19 20:48:27