foxostro / GutsyStorm

Game with voxel graphics similar to Minecraft. (Restart GutsyStorm with Objective-C/Cocoa)
Other
12 stars 4 forks source link

Store less sunlight data per chunk. #61

Closed foxostro closed 11 years ago

foxostro commented 12 years ago

In order to accurately calculate indirect sunlight propagation, GSChunkVoxelData needs to compute indirect sunlight for an area which includes all of its neighbors and itself. In order to interpolate light properly across chunk boundaries, GSChunkGeometryData needs sunlight data for the chunk and a one voxel wide border of that neighboring data.

Currently, the game satisfies both needs by calculating a large buffer of indirect sunlight values and holding on to it forever. Instead, calculate lighting values for an area just large enough to avoid lighting artifacts and copy that buffer to a smaller one which is just large enough for GSChunkGeometry data to do its thing.

With a chunk size of 16x128x16, this reduces the amount of memory we need to hold on to for a single chunk's sunlight buffer from 288KB to 40.5KB. That is quite a large win.

foxostro commented 12 years ago

Additionally, changes should be made so that changing the max light propagation distance from 15 to 7 would reduce the amount of memory needed for sunlight generation. The combined voxel data buffer could actually be CHUNK_SIZE_X+CHUNK_LIGHT_MAX*2 wide, for example.

Though, I do like the way light looks with a propagation distance of 15. So, I don't know whether any wins here would actually be realized.

foxostro commented 12 years ago

Another idea would be to pack sunlight into 4 bits instead of 8, halving the amount of memory used to store sunlight.

foxostro commented 11 years ago

Sunlight is stored in a GSLightingBuffer, which uses uint8_t internally. Since light values must always fall within [0,min(CHUNK_SIZE_X,CHUNK_SIZE_Z)-1], and CHUNKSIZE{X,Z} is always going to be less than 256, 4-bit lighting can be accomplished by making changes to GSLightingBuffer alone.

EDIT: ...except that the class exposes the lighting buffer directly as a property. So, changes would have to be made to all places that access the buffer too. (It was left exposed to avoid a high objc_sendMsg overhead in already CPU-bound code.)

foxostro commented 11 years ago

What I ended up doing is allocating a combined neighborhood the size of all nine chunks, performing sunlight propagation on that, and then copying to a much smaller buffer in _sunlight.lightingBuffer.