mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 06:24:12 +01:00
Solidly lit
- Upload a bitset for each section indicating if blocks are solid - When interpolating light, count the number of transparent blocks and divide to avoid the incorrect "AO" effect near the ground
This commit is contained in:
parent
8dce80ba61
commit
601b70704a
@ -8,6 +8,7 @@ import org.lwjgl.system.MemoryUtil;
|
|||||||
import dev.engine_room.flywheel.api.task.Plan;
|
import dev.engine_room.flywheel.api.task.Plan;
|
||||||
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
|
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
|
||||||
import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer;
|
import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
|
import dev.engine_room.flywheel.lib.math.MoreMath;
|
||||||
import dev.engine_room.flywheel.lib.task.SimplePlan;
|
import dev.engine_room.flywheel.lib.task.SimplePlan;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2IntMap;
|
import it.unimi.dsi.fastutil.longs.Long2IntMap;
|
||||||
@ -36,7 +37,10 @@ import net.minecraft.world.level.lighting.LayerLightEventListener;
|
|||||||
* <p>Thus, each section occupies 5832 bytes.
|
* <p>Thus, each section occupies 5832 bytes.
|
||||||
*/
|
*/
|
||||||
public class LightStorage {
|
public class LightStorage {
|
||||||
public static final long SECTION_SIZE_BYTES = 9 * 9 * 9 * 8;
|
public static final int BLOCKS_PER_SECTION = 18 * 18 * 18;
|
||||||
|
public static final int LIGHT_SIZE_BYTES = BLOCKS_PER_SECTION;
|
||||||
|
public static final int SOLID_SIZE_BYTES = MoreMath.ceilingDiv(BLOCKS_PER_SECTION, Integer.SIZE) * Integer.BYTES;
|
||||||
|
public static final int SECTION_SIZE_BYTES = SOLID_SIZE_BYTES + LIGHT_SIZE_BYTES;
|
||||||
private static final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64;
|
private static final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64;
|
||||||
private static final int INVALID_SECTION = -1;
|
private static final int INVALID_SECTION = -1;
|
||||||
|
|
||||||
@ -158,6 +162,8 @@ public class LightStorage {
|
|||||||
// Zero it out first. This is basically free and makes it easier to handle missing sections later.
|
// Zero it out first. This is basically free and makes it easier to handle missing sections later.
|
||||||
MemoryUtil.memSet(ptr, 0, SECTION_SIZE_BYTES);
|
MemoryUtil.memSet(ptr, 0, SECTION_SIZE_BYTES);
|
||||||
|
|
||||||
|
collectSolidData(ptr, section);
|
||||||
|
|
||||||
collectCenter(blockLight, skyLight, ptr, section);
|
collectCenter(blockLight, skyLight, ptr, section);
|
||||||
|
|
||||||
for (SectionEdge i : SectionEdge.values()) {
|
for (SectionEdge i : SectionEdge.values()) {
|
||||||
@ -175,6 +181,53 @@ public class LightStorage {
|
|||||||
collectCorners(blockLight, skyLight, ptr, section);
|
collectCorners(blockLight, skyLight, ptr, section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void collectSolidData(long ptr, long section) {
|
||||||
|
var blockPos = new BlockPos.MutableBlockPos();
|
||||||
|
int xMin = SectionPos.sectionToBlockCoord(SectionPos.x(section));
|
||||||
|
int yMin = SectionPos.sectionToBlockCoord(SectionPos.y(section));
|
||||||
|
int zMin = SectionPos.sectionToBlockCoord(SectionPos.z(section));
|
||||||
|
|
||||||
|
var bitSet = new BitSet(BLOCKS_PER_SECTION);
|
||||||
|
int index = 0;
|
||||||
|
for (int y = -1; y < 17; y++) {
|
||||||
|
for (int z = -1; z < 17; z++) {
|
||||||
|
for (int x = -1; x < 17; x++) {
|
||||||
|
blockPos.set(xMin + x, yMin + y, zMin + z);
|
||||||
|
|
||||||
|
boolean isFullBlock = level.getBlockState(blockPos)
|
||||||
|
.isCollisionShapeFullBlock(level, blockPos);
|
||||||
|
|
||||||
|
if (isFullBlock) {
|
||||||
|
bitSet.set(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var longArray = bitSet.toLongArray();
|
||||||
|
for (long l : longArray) {
|
||||||
|
MemoryUtil.memPutLong(ptr, l);
|
||||||
|
ptr += Long.BYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeSolid(long ptr, int index, boolean blockValid) {
|
||||||
|
if (!blockValid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int intIndex = index / Integer.SIZE;
|
||||||
|
int bitIndex = index % Integer.SIZE;
|
||||||
|
|
||||||
|
long offset = intIndex * Integer.BYTES;
|
||||||
|
|
||||||
|
int bitField = MemoryUtil.memGetInt(ptr + offset);
|
||||||
|
bitField |= 1 << bitIndex;
|
||||||
|
|
||||||
|
MemoryUtil.memPutInt(ptr + offset, bitField);
|
||||||
|
}
|
||||||
|
|
||||||
private void collectXStrip(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge y, SectionEdge z) {
|
private void collectXStrip(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge y, SectionEdge z) {
|
||||||
var pos = SectionPos.of(section);
|
var pos = SectionPos.of(section);
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
var blockData = blockLight.getDataLayerData(pos);
|
||||||
@ -303,7 +356,7 @@ public class LightStorage {
|
|||||||
|
|
||||||
long packedByte = (block & 0xF) | ((sky & 0xF) << 4);
|
long packedByte = (block & 0xF) | ((sky & 0xF) << 4);
|
||||||
|
|
||||||
MemoryUtil.memPutByte(ptr + offset, (byte) packedByte);
|
MemoryUtil.memPutByte(ptr + SOLID_SIZE_BYTES + offset, (byte) packedByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
const uint _FLW_LIGHT_SECTION_SIZE_BYTES = 18 * 18 * 18;
|
const uint _FLW_BLOCKS_PER_SECTION = 18 * 18 * 18;
|
||||||
|
const uint _FLW_LIGHT_SIZE_BYTES = _FLW_BLOCKS_PER_SECTION;
|
||||||
|
const uint _FLW_SOLID_SIZE_BYTES = ((_FLW_BLOCKS_PER_SECTION + 31) / 32) * 4;
|
||||||
|
const uint _FLW_LIGHT_START_BYTES = _FLW_SOLID_SIZE_BYTES;
|
||||||
|
const uint _FLW_LIGHT_SECTION_SIZE_BYTES = _FLW_SOLID_SIZE_BYTES + _FLW_LIGHT_SIZE_BYTES;
|
||||||
|
|
||||||
|
const uint _FLW_SOLID_START_INTS = 0;
|
||||||
|
const uint _FLW_LIGHT_START_INTS = _FLW_SOLID_SIZE_BYTES / 4;
|
||||||
const uint _FLW_LIGHT_SECTION_SIZE_INTS = _FLW_LIGHT_SECTION_SIZE_BYTES / 4;
|
const uint _FLW_LIGHT_SECTION_SIZE_INTS = _FLW_LIGHT_SECTION_SIZE_BYTES / 4;
|
||||||
|
|
||||||
|
const uint _FLW_COMPLETELY_SOLID = 0x7FFFFFFu;
|
||||||
|
const float _FLW_EPSILON = 1e-5;
|
||||||
|
|
||||||
uint _flw_indexLut(uint index);
|
uint _flw_indexLut(uint index);
|
||||||
|
|
||||||
uint _flw_indexLight(uint index);
|
uint _flw_indexLight(uint index);
|
||||||
@ -51,17 +61,28 @@ bool _flw_chunkCoordToSectionIndex(ivec3 sectionPos, out uint index) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
|
uvec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
|
||||||
uint byteOffset = blockInSectionPos.x + blockInSectionPos.z * 18u + blockInSectionPos.y * 18u * 18u;
|
uint byteOffset = blockInSectionPos.x + blockInSectionPos.z * 18u + blockInSectionPos.y * 18u * 18u;
|
||||||
|
|
||||||
uint uintOffset = byteOffset >> 2u;
|
uint uintOffset = byteOffset >> 2u;
|
||||||
uint bitOffset = (byteOffset & 3u) << 3;
|
uint bitOffset = (byteOffset & 3u) << 3;
|
||||||
|
|
||||||
uint raw = _flw_indexLight(sectionOffset + uintOffset);
|
uint raw = _flw_indexLight(sectionOffset + _FLW_LIGHT_START_INTS + uintOffset);
|
||||||
uint block = (raw >> bitOffset) & 0xFu;
|
uint block = (raw >> bitOffset) & 0xFu;
|
||||||
uint sky = (raw >> (bitOffset + 4u)) & 0xFu;
|
uint sky = (raw >> (bitOffset + 4u)) & 0xFu;
|
||||||
|
|
||||||
return vec2(block, sky);
|
return uvec2(block, sky);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _flw_isSolid(uint sectionOffset, uvec3 blockInSectionPos) {
|
||||||
|
uint bitOffset = blockInSectionPos.x + blockInSectionPos.z * 18u + blockInSectionPos.y * 18u * 18u;
|
||||||
|
|
||||||
|
uint uintOffset = bitOffset / 32u;
|
||||||
|
uint bitInWordOffset = bitOffset % 32u;
|
||||||
|
|
||||||
|
uint word = _flw_indexLight(sectionOffset + _FLW_SOLID_START_INTS + uintOffset);
|
||||||
|
|
||||||
|
return (word & (1u << bitInWordOffset)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flw_lightFetch(ivec3 blockPos, out vec2 lightCoord) {
|
bool flw_lightFetch(ivec3 blockPos, out vec2 lightCoord) {
|
||||||
@ -74,7 +95,7 @@ bool flw_lightFetch(ivec3 blockPos, out vec2 lightCoord) {
|
|||||||
|
|
||||||
uvec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
uvec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
||||||
|
|
||||||
lightCoord = _flw_lightAt(sectionOffset, blockInSectionPos) / 15.;
|
lightCoord = vec2(_flw_lightAt(sectionOffset, blockInSectionPos)) / 15.;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,14 +125,14 @@ bool flw_light(vec3 worldPos, out vec2 lightCoord) {
|
|||||||
// Fetch everything for trilinear interpolation
|
// Fetch everything for trilinear interpolation
|
||||||
// Hypothetically we could re-order these and do some calculations in-between fetches
|
// Hypothetically we could re-order these and do some calculations in-between fetches
|
||||||
// to help with latency hiding, but the compiler should be able to do that for us.
|
// to help with latency hiding, but the compiler should be able to do that for us.
|
||||||
vec2 light000 = _flw_lightAt(sectionOffset, lowestCorner);
|
vec2 light000 = vec2(_flw_lightAt(sectionOffset, lowestCorner));
|
||||||
vec2 light001 = _flw_lightAt(sectionOffset, lowestCorner + uvec3(0, 0, 1));
|
vec2 light001 = vec2(_flw_lightAt(sectionOffset, lowestCorner + uvec3(0, 0, 1)));
|
||||||
vec2 light010 = _flw_lightAt(sectionOffset, lowestCorner + uvec3(0, 1, 0));
|
vec2 light010 = vec2(_flw_lightAt(sectionOffset, lowestCorner + uvec3(0, 1, 0)));
|
||||||
vec2 light011 = _flw_lightAt(sectionOffset, lowestCorner + uvec3(0, 1, 1));
|
vec2 light011 = vec2(_flw_lightAt(sectionOffset, lowestCorner + uvec3(0, 1, 1)));
|
||||||
vec2 light100 = _flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 0, 0));
|
vec2 light100 = vec2(_flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 0, 0)));
|
||||||
vec2 light101 = _flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 0, 1));
|
vec2 light101 = vec2(_flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 0, 1)));
|
||||||
vec2 light110 = _flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 1, 0));
|
vec2 light110 = vec2(_flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 1, 0)));
|
||||||
vec2 light111 = _flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 1, 1));
|
vec2 light111 = vec2(_flw_lightAt(sectionOffset, lowestCorner + uvec3(1, 1, 1)));
|
||||||
|
|
||||||
vec2 light00 = mix(light000, light001, interpolant.z);
|
vec2 light00 = mix(light000, light001, interpolant.z);
|
||||||
vec2 light01 = mix(light010, light011, interpolant.z);
|
vec2 light01 = mix(light010, light011, interpolant.z);
|
||||||
@ -131,13 +152,19 @@ uint _flw_lightIndex(in uvec3 p) {
|
|||||||
|
|
||||||
/// Premtively collect all light in a 3x3x3 area centered on our block.
|
/// Premtively collect all light in a 3x3x3 area centered on our block.
|
||||||
/// Depending on the normal, we won't use all the data, but fetching on demand will have many duplicated fetches.
|
/// Depending on the normal, we won't use all the data, but fetching on demand will have many duplicated fetches.
|
||||||
vec2[27] _flw_lightFetch3x3x3(uint sectionOffset, ivec3 blockInSectionPos) {
|
uvec3[27] _flw_fetchLight3x3x3(uint sectionOffset, ivec3 blockInSectionPos, uint solid) {
|
||||||
vec2[27] lights;
|
uvec3[27] lights;
|
||||||
|
|
||||||
|
uint index = 0u;
|
||||||
|
uint mask = 1u;
|
||||||
for (int y = -1; y <= 1; y++) {
|
for (int y = -1; y <= 1; y++) {
|
||||||
for (int z = -1; z <= 1; z++) {
|
for (int z = -1; z <= 1; z++) {
|
||||||
for (int x = -1; x <= 1; x++) {
|
for (int x = -1; x <= 1; x++) {
|
||||||
lights[_flw_lightIndex(uvec3(x + 1, y + 1, z + 1))] = _flw_lightAt(sectionOffset, uvec3(blockInSectionPos + ivec3(x, y, z)));
|
// 0 if the block is solid, 1 if it's not.
|
||||||
|
uint flag = uint((solid & mask) == 0u);
|
||||||
|
lights[index] = uvec3(_flw_lightAt(sectionOffset, uvec3(blockInSectionPos + ivec3(x, y, z))), flag);
|
||||||
|
index++;
|
||||||
|
mask <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,6 +172,24 @@ vec2[27] _flw_lightFetch3x3x3(uint sectionOffset, ivec3 blockInSectionPos) {
|
|||||||
return lights;
|
return lights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint _flw_fetchSolid3x3x3(uint sectionOffset, ivec3 blockInSectionPos) {
|
||||||
|
uint ret = 0;
|
||||||
|
|
||||||
|
uint index = 0;
|
||||||
|
for (int y = -1; y <= 1; y++) {
|
||||||
|
for (int z = -1; z <= 1; z++) {
|
||||||
|
for (int x = -1; x <= 1; x++) {
|
||||||
|
bool flag = _flw_isSolid(sectionOffset, uvec3(blockInSectionPos + ivec3(x, y, z)));
|
||||||
|
ret |= uint(flag) << index;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculate the light for a direction by averaging the light at the corners of the block.
|
/// Calculate the light for a direction by averaging the light at the corners of the block.
|
||||||
///
|
///
|
||||||
/// To make this reusable across directions, c00..c11 choose what values relative to each corner to use.
|
/// To make this reusable across directions, c00..c11 choose what values relative to each corner to use.
|
||||||
@ -155,16 +200,26 @@ vec2[27] _flw_lightFetch3x3x3(uint sectionOffset, ivec3 blockInSectionPos) {
|
|||||||
/// @param lights The light data for the 3x3x3 area.
|
/// @param lights The light data for the 3x3x3 area.
|
||||||
/// @param interpolant The position within the center block.
|
/// @param interpolant The position within the center block.
|
||||||
/// @param c00..c11 4 offsets to determine which "direction" we are averaging.
|
/// @param c00..c11 4 offsets to determine which "direction" we are averaging.
|
||||||
vec2 _flw_lightForDirection(in vec2[27] lights, in vec3 interpolant, in uvec3 c00, in uvec3 c01, in uvec3 c10, in uvec3 c11) {
|
vec2 _flw_lightForDirection(in uvec3[27] lights, in vec3 interpolant, in uvec3 c00, in uvec3 c01, in uvec3 c10, in uvec3 c11) {
|
||||||
|
|
||||||
vec2 light000 = lights[_flw_lightIndex(c00 + uvec3(0u, 0u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 0u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 0u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 0u, 0u))];
|
uvec3 i000 = lights[_flw_lightIndex(c00 + uvec3(0u, 0u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 0u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 0u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 0u, 0u))];
|
||||||
vec2 light001 = lights[_flw_lightIndex(c00 + uvec3(0u, 0u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 0u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 0u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 0u, 1u))];
|
uvec3 i001 = lights[_flw_lightIndex(c00 + uvec3(0u, 0u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 0u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 0u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 0u, 1u))];
|
||||||
vec2 light010 = lights[_flw_lightIndex(c00 + uvec3(0u, 1u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 1u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 1u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 1u, 0u))];
|
uvec3 i010 = lights[_flw_lightIndex(c00 + uvec3(0u, 1u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 1u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 1u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 1u, 0u))];
|
||||||
vec2 light011 = lights[_flw_lightIndex(c00 + uvec3(0u, 1u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 1u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 1u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 1u, 1u))];
|
uvec3 i011 = lights[_flw_lightIndex(c00 + uvec3(0u, 1u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(0u, 1u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(0u, 1u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(0u, 1u, 1u))];
|
||||||
vec2 light100 = lights[_flw_lightIndex(c00 + uvec3(1u, 0u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 0u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 0u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 0u, 0u))];
|
uvec3 i100 = lights[_flw_lightIndex(c00 + uvec3(1u, 0u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 0u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 0u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 0u, 0u))];
|
||||||
vec2 light101 = lights[_flw_lightIndex(c00 + uvec3(1u, 0u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 0u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 0u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 0u, 1u))];
|
uvec3 i101 = lights[_flw_lightIndex(c00 + uvec3(1u, 0u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 0u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 0u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 0u, 1u))];
|
||||||
vec2 light110 = lights[_flw_lightIndex(c00 + uvec3(1u, 1u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 1u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 1u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 1u, 0u))];
|
uvec3 i110 = lights[_flw_lightIndex(c00 + uvec3(1u, 1u, 0u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 1u, 0u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 1u, 0u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 1u, 0u))];
|
||||||
vec2 light111 = lights[_flw_lightIndex(c00 + uvec3(1u, 1u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 1u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 1u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 1u, 1u))];
|
uvec3 i111 = lights[_flw_lightIndex(c00 + uvec3(1u, 1u, 1u))] + lights[_flw_lightIndex(c01 + uvec3(1u, 1u, 1u))] + lights[_flw_lightIndex(c10 + uvec3(1u, 1u, 1u))] + lights[_flw_lightIndex(c11 + uvec3(1u, 1u, 1u))];
|
||||||
|
|
||||||
|
// Divide by the number of light transmitting blocks to get the average.
|
||||||
|
vec2 light000 = i000.z == 0 ? vec2(0) : vec2(i000.xy) / float(i000.z);
|
||||||
|
vec2 light001 = i001.z == 0 ? vec2(0) : vec2(i001.xy) / float(i001.z);
|
||||||
|
vec2 light010 = i010.z == 0 ? vec2(0) : vec2(i010.xy) / float(i010.z);
|
||||||
|
vec2 light011 = i011.z == 0 ? vec2(0) : vec2(i011.xy) / float(i011.z);
|
||||||
|
vec2 light100 = i100.z == 0 ? vec2(0) : vec2(i100.xy) / float(i100.z);
|
||||||
|
vec2 light101 = i101.z == 0 ? vec2(0) : vec2(i101.xy) / float(i101.z);
|
||||||
|
vec2 light110 = i110.z == 0 ? vec2(0) : vec2(i110.xy) / float(i110.z);
|
||||||
|
vec2 light111 = i111.z == 0 ? vec2(0) : vec2(i111.xy) / float(i111.z);
|
||||||
|
|
||||||
vec2 light00 = mix(light000, light001, interpolant.z);
|
vec2 light00 = mix(light000, light001, interpolant.z);
|
||||||
vec2 light01 = mix(light010, light011, interpolant.z);
|
vec2 light01 = mix(light010, light011, interpolant.z);
|
||||||
@ -174,8 +229,7 @@ vec2 _flw_lightForDirection(in vec2[27] lights, in vec3 interpolant, in uvec3 c0
|
|||||||
vec2 light0 = mix(light00, light01, interpolant.y);
|
vec2 light0 = mix(light00, light01, interpolant.y);
|
||||||
vec2 light1 = mix(light10, light11, interpolant.y);
|
vec2 light1 = mix(light10, light11, interpolant.y);
|
||||||
|
|
||||||
// Divide by 60 (15 * 4) to normalize.
|
return mix(light0, light1, interpolant.x) / 15.;
|
||||||
return mix(light0, light1, interpolant.x) / 63.;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flw_light(vec3 worldPos, vec3 normal, out vec2 lightCoord) {
|
bool flw_light(vec3 worldPos, vec3 normal, out vec2 lightCoord) {
|
||||||
@ -194,24 +248,31 @@ bool flw_light(vec3 worldPos, vec3 normal, out vec2 lightCoord) {
|
|||||||
// The block's position in the section adjusted into 18x18x18 space
|
// The block's position in the section adjusted into 18x18x18 space
|
||||||
ivec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
ivec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
||||||
|
|
||||||
|
uint solid = _flw_fetchSolid3x3x3(sectionOffset, blockInSectionPos);
|
||||||
|
|
||||||
|
if (solid == _FLW_COMPLETELY_SOLID) {
|
||||||
|
lightCoord = vec2(0.);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch everything in a 3x3x3 area centered around the block.
|
// Fetch everything in a 3x3x3 area centered around the block.
|
||||||
vec2[27] lights = _flw_lightFetch3x3x3(sectionOffset, blockInSectionPos);
|
uvec3[27] lights = _flw_fetchLight3x3x3(sectionOffset, blockInSectionPos, solid);
|
||||||
|
|
||||||
vec3 interpolant = fract(worldPos);
|
vec3 interpolant = fract(worldPos);
|
||||||
|
|
||||||
vec2 lightX;
|
vec2 lightX;
|
||||||
if (normal.x > 0) {
|
if (normal.x > _FLW_EPSILON) {
|
||||||
lightX = _flw_lightForDirection(lights, interpolant, uvec3(1u, 0u, 0u), uvec3(1u, 0u, 1u), uvec3(1u, 1u, 0u), uvec3(1u, 1u, 1u));
|
lightX = _flw_lightForDirection(lights, interpolant, uvec3(1u, 0u, 0u), uvec3(1u, 0u, 1u), uvec3(1u, 1u, 0u), uvec3(1u, 1u, 1u));
|
||||||
} else if (normal.x < 0) {
|
} else if (normal.x < -_FLW_EPSILON) {
|
||||||
lightX = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 0u), uvec3(0u, 0u, 1u), uvec3(0u, 1u, 0u), uvec3(0u, 1u, 1u));
|
lightX = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 0u), uvec3(0u, 0u, 1u), uvec3(0u, 1u, 0u), uvec3(0u, 1u, 1u));
|
||||||
} else {
|
} else {
|
||||||
lightX = vec2(0.);
|
lightX = vec2(0.);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 lightZ;
|
vec2 lightZ;
|
||||||
if (normal.z > 0) {
|
if (normal.z > _FLW_EPSILON) {
|
||||||
lightZ = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 1u), uvec3(0u, 1u, 1u), uvec3(1u, 0u, 1u), uvec3(1u, 1u, 1u));
|
lightZ = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 1u), uvec3(0u, 1u, 1u), uvec3(1u, 0u, 1u), uvec3(1u, 1u, 1u));
|
||||||
} else if (normal.z < 0) {
|
} else if (normal.z < -_FLW_EPSILON) {
|
||||||
lightZ = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 0u), uvec3(0u, 1u, 0u), uvec3(1u, 0u, 0u), uvec3(1u, 1u, 0u));
|
lightZ = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 0u), uvec3(0u, 1u, 0u), uvec3(1u, 0u, 0u), uvec3(1u, 1u, 0u));
|
||||||
} else {
|
} else {
|
||||||
lightZ = vec2(0.);
|
lightZ = vec2(0.);
|
||||||
@ -219,9 +280,9 @@ bool flw_light(vec3 worldPos, vec3 normal, out vec2 lightCoord) {
|
|||||||
|
|
||||||
vec2 lightY;
|
vec2 lightY;
|
||||||
// Average the light in relevant directions at each corner.
|
// Average the light in relevant directions at each corner.
|
||||||
if (normal.y > 0.) {
|
if (normal.y > _FLW_EPSILON) {
|
||||||
lightY = _flw_lightForDirection(lights, interpolant, uvec3(0u, 1u, 0u), uvec3(0u, 1u, 1u), uvec3(1u, 1u, 0u), uvec3(1u, 1u, 1u));
|
lightY = _flw_lightForDirection(lights, interpolant, uvec3(0u, 1u, 0u), uvec3(0u, 1u, 1u), uvec3(1u, 1u, 0u), uvec3(1u, 1u, 1u));
|
||||||
} else if (normal.y < 0.) {
|
} else if (normal.y < -_FLW_EPSILON) {
|
||||||
lightY = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 0u), uvec3(0u, 0u, 1u), uvec3(1u, 0u, 0u), uvec3(1u, 0u, 1u));
|
lightY = _flw_lightForDirection(lights, interpolant, uvec3(0u, 0u, 0u), uvec3(0u, 0u, 1u), uvec3(1u, 0u, 0u), uvec3(1u, 0u, 1u));
|
||||||
} else {
|
} else {
|
||||||
lightY = vec2(0.);
|
lightY = vec2(0.);
|
||||||
|
@ -9,6 +9,10 @@ public final class MoreMath {
|
|||||||
*/
|
*/
|
||||||
public static final float SQRT_3_OVER_2 = (float) (Math.sqrt(3.0) / 2.0);
|
public static final float SQRT_3_OVER_2 = (float) (Math.sqrt(3.0) / 2.0);
|
||||||
|
|
||||||
|
public static int align32(int size) {
|
||||||
|
return (size + 31) & ~31;
|
||||||
|
}
|
||||||
|
|
||||||
public static int align16(int size) {
|
public static int align16(int size) {
|
||||||
return (size + 15) & ~15;
|
return (size + 15) & ~15;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user