mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-01 01:35:23 -04:00
Make light occlusion take block shape and other properties into account
This commit is contained in:
parent
e4b259aaad
commit
3a2613fa56
@ -142,7 +142,7 @@ static void LightQueue_Resize(struct LightQueue* queue) {
|
|||||||
}
|
}
|
||||||
capacity = queue->capacity * 2;
|
capacity = queue->capacity * 2;
|
||||||
if (capacity < 32) capacity = 32;
|
if (capacity < 32) capacity = 32;
|
||||||
entries = (IVec3*)Mem_Alloc(capacity, sizeof(IVec3), "Block queue");
|
entries = (IVec3*)Mem_Alloc(capacity, sizeof(IVec3), "Light queue");
|
||||||
for (i = 0; i < queue->count; i++) {
|
for (i = 0; i < queue->count; i++) {
|
||||||
idx = (queue->head + i) & queue->mask;
|
idx = (queue->head + i) & queue->mask;
|
||||||
entries[i] = queue->entries[idx];
|
entries[i] = queue->entries[idx];
|
||||||
@ -203,7 +203,7 @@ static void ModernLighting_InitPalette(void) {
|
|||||||
float blockLerp;
|
float blockLerp;
|
||||||
cc_uint8 R, G, B;
|
cc_uint8 R, G, B;
|
||||||
|
|
||||||
defaultBlockLight = PackedCol_Make(255, 238, 204, 255); /* A very mildly orange tinted light color */
|
defaultBlockLight = PackedCol_Make(150, 112, 79, 255); /* A very mildly orange tinted light color */
|
||||||
darkestShadow = PackedCol_Lerp(Env.ShadowCol, 0, 0.75f); /* Use a darkened version of shadow color as the darkest color in sun ramp */
|
darkestShadow = PackedCol_Lerp(Env.ShadowCol, 0, 0.75f); /* Use a darkened version of shadow color as the darkest color in sun ramp */
|
||||||
|
|
||||||
for (sunLevel = 0; sunLevel < MODERN_LIGHTING_LEVELS; sunLevel++) {
|
for (sunLevel = 0; sunLevel < MODERN_LIGHTING_LEVELS; sunLevel++) {
|
||||||
@ -217,7 +217,7 @@ static void ModernLighting_InitPalette(void) {
|
|||||||
sunColor = PackedCol_Lerp(darkestShadow, Env.ShadowCol, sunLevel / (float)(MODERN_LIGHTING_LEVELS - 2));
|
sunColor = PackedCol_Lerp(darkestShadow, Env.ShadowCol, sunLevel / (float)(MODERN_LIGHTING_LEVELS - 2));
|
||||||
}
|
}
|
||||||
blockLerp = blockLevel / (float)(MODERN_LIGHTING_LEVELS - 1);
|
blockLerp = blockLevel / (float)(MODERN_LIGHTING_LEVELS - 1);
|
||||||
blockLerp *= blockLerp;
|
//blockLerp *= blockLerp;
|
||||||
blockLerp *= (MATH_PI / 2);
|
blockLerp *= (MATH_PI / 2);
|
||||||
blockLerp = Math_Cos(blockLerp);
|
blockLerp = Math_Cos(blockLerp);
|
||||||
blockColor = PackedCol_Lerp(0, defaultBlockLight, 1 - blockLerp);
|
blockColor = PackedCol_Lerp(0, defaultBlockLight, 1 - blockLerp);
|
||||||
@ -293,6 +293,19 @@ static cc_uint8 GetBlocklight(int x, int y, int z) {
|
|||||||
return chunkLightingData[chunkIndex][localIndex] & MODERN_LIGHTING_MAX_LEVEL;
|
return chunkLightingData[chunkIndex][localIndex] & MODERN_LIGHTING_MAX_LEVEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cc_bool CanLightPass(BlockID thisBlock, Face face) {
|
||||||
|
/* If it's not opaque and it doesn't block light, or it's fullbright, we can always pass through */
|
||||||
|
if ((Blocks.Draw[thisBlock] > DRAW_OPAQUE && !Blocks.BlocksLight[thisBlock]) || Blocks.FullBright[thisBlock]) { return true; }
|
||||||
|
/* Light can always pass through leaves and water */
|
||||||
|
if (Blocks.Draw[thisBlock] == DRAW_TRANSPARENT_THICK || Blocks.Draw[thisBlock] == DRAW_TRANSLUCENT) { return true; }
|
||||||
|
|
||||||
|
/* Light can never pass through a block that's full sized and blocks light */
|
||||||
|
/* We can assume a block is full sized if none of the LightOffset flags are 0 */
|
||||||
|
if (Blocks.BlocksLight[thisBlock] && Blocks.LightOffset[thisBlock] == 0xFF) { return false; }
|
||||||
|
|
||||||
|
/* Is stone's face hidden by thisBlock? */
|
||||||
|
return !Block_IsFaceHidden(BLOCK_STONE, thisBlock, face);
|
||||||
|
}
|
||||||
static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
||||||
|
|
||||||
SetBlocklight(blockLight, x, y, z);
|
SetBlocklight(blockLight, x, y, z);
|
||||||
@ -308,11 +321,14 @@ static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
|||||||
Platform_Log1("but there were still %i entries left...", &lightQueue.capacity);
|
Platform_Log1("but there were still %i entries left...", &lightQueue.capacity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
BlockID thisBlock = World_GetBlock(curNode.X, curNode.Y, curNode.Z);
|
||||||
|
|
||||||
|
|
||||||
curNode.X--;
|
curNode.X--;
|
||||||
if (curNode.X > 0 &&
|
if (curNode.X > 0 &&
|
||||||
curBlockLight-1 > 1 &&
|
curBlockLight-1 > 1 &&
|
||||||
!Blocks.BlocksLight[World_GetBlock(curNode.X, curNode.Y, curNode.Z)] &&
|
CanLightPass(thisBlock, FACE_XMAX) &&
|
||||||
|
CanLightPass(World_GetBlock(curNode.X, curNode.Y, curNode.Z), FACE_XMIN) &&
|
||||||
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight-1
|
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight-1
|
||||||
) {
|
) {
|
||||||
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
||||||
@ -322,7 +338,8 @@ static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
|||||||
curNode.X += 2;
|
curNode.X += 2;
|
||||||
if (curNode.X < World.MaxX &&
|
if (curNode.X < World.MaxX &&
|
||||||
curBlockLight - 1 > 1 &&
|
curBlockLight - 1 > 1 &&
|
||||||
!Blocks.BlocksLight[World_GetBlock(curNode.X, curNode.Y, curNode.Z)] &&
|
CanLightPass(thisBlock, FACE_XMIN) &&
|
||||||
|
CanLightPass(World_GetBlock(curNode.X, curNode.Y, curNode.Z), FACE_XMAX) &&
|
||||||
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
||||||
) {
|
) {
|
||||||
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
||||||
@ -334,7 +351,8 @@ static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
|||||||
curNode.Y--;
|
curNode.Y--;
|
||||||
if (curNode.Y > 0 &&
|
if (curNode.Y > 0 &&
|
||||||
curBlockLight - 1 > 1 &&
|
curBlockLight - 1 > 1 &&
|
||||||
!Blocks.BlocksLight[World_GetBlock(curNode.X, curNode.Y, curNode.Z)] &&
|
CanLightPass(thisBlock, FACE_YMAX) &&
|
||||||
|
CanLightPass(World_GetBlock(curNode.X, curNode.Y, curNode.Z), FACE_YMIN) &&
|
||||||
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
||||||
) {
|
) {
|
||||||
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
||||||
@ -344,7 +362,8 @@ static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
|||||||
curNode.Y += 2;
|
curNode.Y += 2;
|
||||||
if (curNode.Y < World.MaxY &&
|
if (curNode.Y < World.MaxY &&
|
||||||
curBlockLight - 1 > 1 &&
|
curBlockLight - 1 > 1 &&
|
||||||
!Blocks.BlocksLight[World_GetBlock(curNode.X, curNode.Y, curNode.Z)] &&
|
CanLightPass(thisBlock, FACE_YMIN) &&
|
||||||
|
CanLightPass(World_GetBlock(curNode.X, curNode.Y, curNode.Z), FACE_YMAX) &&
|
||||||
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
||||||
) {
|
) {
|
||||||
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
||||||
@ -356,7 +375,8 @@ static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
|||||||
curNode.Z--;
|
curNode.Z--;
|
||||||
if (curNode.Z > 0 &&
|
if (curNode.Z > 0 &&
|
||||||
curBlockLight - 1 > 1 &&
|
curBlockLight - 1 > 1 &&
|
||||||
!Blocks.BlocksLight[World_GetBlock(curNode.X, curNode.Y, curNode.Z)] &&
|
CanLightPass(thisBlock, FACE_ZMAX) &&
|
||||||
|
CanLightPass(World_GetBlock(curNode.X, curNode.Y, curNode.Z), FACE_ZMIN) &&
|
||||||
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
||||||
) {
|
) {
|
||||||
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
||||||
@ -366,20 +386,14 @@ static void CalcBlockLight(cc_uint8 blockLight, int x, int y, int z) {
|
|||||||
curNode.Z += 2;
|
curNode.Z += 2;
|
||||||
if (curNode.Z < World.MaxZ &&
|
if (curNode.Z < World.MaxZ &&
|
||||||
curBlockLight - 1 > 1 &&
|
curBlockLight - 1 > 1 &&
|
||||||
!Blocks.BlocksLight[World_GetBlock(curNode.X, curNode.Y, curNode.Z)] &&
|
CanLightPass(thisBlock, FACE_ZMIN) &&
|
||||||
|
CanLightPass(World_GetBlock(curNode.X, curNode.Y, curNode.Z), FACE_ZMAX) &&
|
||||||
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
GetBlocklight(curNode.X, curNode.Y, curNode.Z) < curBlockLight - 1
|
||||||
) {
|
) {
|
||||||
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
SetBlocklight(curBlockLight - 1, curNode.X, curNode.Y, curNode.Z);
|
||||||
IVec3 entry = { curNode.X, curNode.Y, curNode.Z };
|
IVec3 entry = { curNode.X, curNode.Y, curNode.Z };
|
||||||
LightQueue_Enqueue(&lightQueue, entry);
|
LightQueue_Enqueue(&lightQueue, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Step 5: Look at all neighbouring voxels to that node.
|
|
||||||
// if that node is in bounds of the world
|
|
||||||
// AND if light is allowed to spread to that node,
|
|
||||||
// AND if that node's light level is 2 or more levels less than the current node,
|
|
||||||
// then set their light level to the current nodes light level - 1,
|
|
||||||
// and then add that node to the queue.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
|
static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
|
||||||
@ -406,10 +420,6 @@ static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
|
|||||||
|
|
||||||
BlockID curBlock = World_GetBlock(x, y, z);
|
BlockID curBlock = World_GetBlock(x, y, z);
|
||||||
if (Blocks.FullBright[curBlock]) {
|
if (Blocks.FullBright[curBlock]) {
|
||||||
|
|
||||||
//String_InitArray(msg, msgBuffer);
|
|
||||||
//String_Format3(&msg, "found bright block at %i %i %i", &x, &y, &z);
|
|
||||||
//Chat_Add(&msg);
|
|
||||||
CalcBlockLight(15, x, y, z);
|
CalcBlockLight(15, x, y, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user