光照計算的優化主要在提前初始化所有block光照(skylight和pointlight),之前把光照的初始化和光照的更新、地形的加載同步進行,導致運算的重複性太高。比如初始化某一chunk的光照量,計算中,發現有光照影響到其他chunk,但是由於該chunk還未加載或是還未初始化(太陽光初始化),只能暫存該光源,等到chunk初始化好了,再重新算該光源影響,而且很大概率該chunk的光照又會影響之前chunk的光照,導致chunk的頻繁刷新,加重了計算量。
算法優化:
- 光照提前初始化,(避免重複運算)
- skylight和pointlight分開計算,(減少函數調用次數)
- block緩存變量,(加快取值速度)
- block存儲優化,三維數組改一維,(加快取值速度)
- 使用位運算,(加快取值速度)
光照提前初始化
1、太陽光init
2、太陽光漫反射
3、其他光源漫反射
以上光照的初始化在地形加載前計算好,有個弊端是必須所有block都要計算,會遇到內存佔用過多,此處可優化分塊計算(暫未實驗)。
skylight和pointlight分開計算
初始化好的光照進行更新就比較方便了,當有塊消除、添加或者添加光源時 就會刷新skylight和pointlight的值。兩者是獨立腳本完成的,邏輯基本相同,skylight比pointlight多一些額外處理,但大體都一樣。分開處理的原因是減少函數調用次數。比如添加塊時:
// set new block
chunk.SetBlock(idx, type, state);
// clear light
if (chunk.Blocks[idx].Transparent == false) {
LightPoint.UpdateLightDark(chunk, x, y, z);
LightSky.UpdateLightDark(chunk, x, y, z);
}
// new point light
if (chunk.Blocks[idx].LightSource) {
LightPoint.UpdateLightBright(chunk, x, y, z, light);
}
block緩存變量、block存儲優化、使用位運算
這幾項都是爲了提高取值速度,太高效率,比如block會cache Transparent(是否可透光),這些變量在光照計算中頻繁用到,所以提高獲取速度,block採用一維數組也是爲了提高取值速度。位運算主要用在三維到一維的變換。