类Minecraft方块游戏unity开发笔记4-光照算法(优化)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011704730/article/details/55251946

光照计算的优化主要在提前初始化所有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采用一维数组也是为了提高取值速度。位运算主要用在三维到一维的变换。

展开阅读全文

没有更多推荐了,返回首页