Optimizing The Engine – III – The Lighting!

In one of my previous DevLog entries I had mentioned that I was switching to a single huge block array technique instead of array per chunk which eventually simplifies access to block data. Now I’m done with upgrading my lighting code to take advantage of new block array technique and results are great!

With the latest updates, ligthing is now 3.2 times faster! Wow, that’s a really great optimization which worth every single seconds I’ve worked for it! Here’s test results;

Test Parameters:
* View range: 5 chunks.
* Total chunks in view: 121 chunks.

     Old Lighting Technique - New Lighting Technique
 #1          1316 ms        -          498 ms
 #2          1291 ms        -          384 ms
 #3          1338 ms        -          384 ms
 #4          1293 ms        -          389 ms
 #5          1278 ms        -          387 ms
 #6          1324 ms        -          386 ms
 #7          1284 ms        -          377 ms
 #8          1281 ms        -          380 ms
 #9          1288 ms        -          389 ms
#10          1299 ms        -          381 ms
-----------------------------------------------------------
AVG.         1299 ms        -          395 ms ~ 3.2 faster!

So what changed?

First, the old technique was optimized for old block array per chunk storage. So within this to access a neighboring block, it had to access using chunks – as a neighbor block could be in another chunk. The below propagation functions first need to resolve the chunk that owns the asked block (as block arrays are per chunk) and then need to progress on.

PropagateSunLight(chunk, (byte) (x - 1), y, z, light);
PropagateSunLight(chunk, (byte) (x + 1), y, z, light);
PropagateSunLight(chunk, x, (byte) (y - 1), z, light);
PropagateSunLight(chunk, x, (byte) (y + 1), z, light);
PropagateSunLight(chunk, x, y, (byte) (z - 1), light);
PropagateSunLight(chunk, x, y, (byte) (z + 1), light);

Where as the new lighting technique really doesn’t care about which chunk does the block resides in and can directly access the block data from our single huge block array!

PropagateSunLight(blockIndex + BlockStorage.XStep, propagatedLight); // propagate light to block in east.
PropagateSunLight(blockIndex - BlockStorage.XStep, propagatedLight); // propagate light to block in west.
PropagateSunLight(blockIndex + BlockStorage.ZStep, propagatedLight); // propagate light to block in north.
PropagateSunLight(blockIndex - BlockStorage.ZStep, propagatedLight); // propagate light to block in south.
// DO NOT repropagete to upper block which we don't need to do so and may cause loops!
PropagateSunLight(blockIndex - 1, propagatedLight);   // propagate light to block down.

So What’s Next?
I’ll be also optimizing terrain generation & vertex-building code similarly.

Bonus Screenshot
Nothing new & fancy

Leave a Reply

Your email address will not be published. Required fields are marked *