mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Add a fast-path for sunlight propagation in uniform air chunks.
fixes #320, terrain generation in single-player is now ~30% faster.
This commit is contained in:
parent
9cacd64c4d
commit
cb2c7f07c3
@ -702,6 +702,7 @@ pub const ChunkMesh = struct {
|
||||
self.mutex.unlock();
|
||||
self.lightingData[0].propagateLights(lightEmittingBlocks.items, true);
|
||||
sunLight: {
|
||||
var allSun: bool = self.chunk.data.paletteLength == 1 and self.chunk.data.palette[0].typ == 0;
|
||||
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
||||
var index: usize = 0;
|
||||
const lightStartMap = mesh_storage.getLightMapPieceAndIncreaseRefCount(self.pos.wx, self.pos.wy, self.pos.voxelSize) orelse break :sunLight;
|
||||
@ -715,10 +716,16 @@ pub const ChunkMesh = struct {
|
||||
if(relHeight < chunk.chunkSize*self.pos.voxelSize) {
|
||||
sunStarters[index] = .{x, y, chunk.chunkSize-1};
|
||||
index += 1;
|
||||
} else {
|
||||
allSun = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.lightingData[1].propagateLights(sunStarters[0..index], true);
|
||||
if(allSun) {
|
||||
self.lightingData[1].propagateUniformSun();
|
||||
} else {
|
||||
self.lightingData[1].propagateLights(sunStarters[0..index], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,6 +324,54 @@ pub const ChannelChunk = struct {
|
||||
self.propagateDirect(&lightQueue);
|
||||
}
|
||||
|
||||
pub fn propagateUniformSun(self: *ChannelChunk) void {
|
||||
std.debug.assert(self.isSun);
|
||||
self.mutex.lock();
|
||||
if(self.data.paletteLength != 1) {
|
||||
self.data.deinit();
|
||||
self.data.init();
|
||||
}
|
||||
self.data.palette[0] = .{255, 255, 255};
|
||||
self.mutex.unlock();
|
||||
const val = 255 -| 8*|@as(u8, @intCast(self.ch.pos.voxelSize));
|
||||
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
||||
defer lightQueue.deinit();
|
||||
for(chunk.Neighbors.iterable) |neighbor| {
|
||||
if(neighbor == chunk.Neighbors.dirUp) continue;
|
||||
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
||||
defer neighborMesh.decreaseRefCount();
|
||||
var list: [chunk.chunkSize*chunk.chunkSize]Entry = undefined;
|
||||
for(0..chunk.chunkSize) |x| {
|
||||
for(0..chunk.chunkSize) |y| {
|
||||
const entry = &list[x*chunk.chunkSize + y];
|
||||
switch(chunk.Neighbors.vectorComponent[neighbor]) {
|
||||
.x => {
|
||||
entry.x = if(chunk.Neighbors.isPositive[neighbor]) 0 else chunk.chunkSize - 1;
|
||||
entry.y = @intCast(x);
|
||||
entry.z = @intCast(y);
|
||||
entry.value = .{val, val, val};
|
||||
},
|
||||
.y => {
|
||||
entry.y = if(chunk.Neighbors.isPositive[neighbor]) 0 else chunk.chunkSize - 1;
|
||||
entry.x = @intCast(x);
|
||||
entry.z = @intCast(y);
|
||||
entry.value = .{val, val, val};
|
||||
},
|
||||
.z => {
|
||||
entry.z = if(chunk.Neighbors.isPositive[neighbor]) 0 else chunk.chunkSize - 1;
|
||||
entry.x = @intCast(x);
|
||||
entry.y = @intCast(y);
|
||||
entry.value = .{255, 255, 255};
|
||||
},
|
||||
}
|
||||
entry.activeValue = 0b111;
|
||||
entry.sourceDir = neighbor ^ 1;
|
||||
}
|
||||
}
|
||||
neighborMesh.lightingData[1].propagateFromNeighbor(&lightQueue, &list);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn propagateLightsDestructive(self: *ChannelChunk, lights: []const [3]u8) void {
|
||||
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
||||
defer lightQueue.deinit();
|
||||
|
Loading…
x
Reference in New Issue
Block a user