forked from mirror/ObjToSchematic
Fixed lighting for transparent blocks, added emissive blocks
This commit is contained in:
parent
546df638cb
commit
eb4ab21f4e
@ -1,7 +1,7 @@
|
||||
{
|
||||
"AMBIENT_OCCLUSION_OVERRIDE_CORNER": true,
|
||||
"LOG_TO_FILE": true,
|
||||
"USE_WORKER_THREAD": false,
|
||||
"USE_WORKER_THREAD": true,
|
||||
"MULTISAMPLE_COUNT": 16,
|
||||
"OLD_SPACE_SIZE_MB": 8192,
|
||||
"ALPHA_BIAS": 1.0,
|
||||
|
15
res/emissive_blocks.json
Normal file
15
res/emissive_blocks.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"emissive_blocks": [
|
||||
"minecraft:respawn_anchor",
|
||||
"minecraft:magma_block",
|
||||
"minecraft:sculk_catalyst",
|
||||
"minecraft:crying_obsidian",
|
||||
"minecraft:shroomlight",
|
||||
"minecraft:sea_lantern",
|
||||
"minecraft:jack_o_lantern",
|
||||
"minecraft:glowstone",
|
||||
"minecraft:pearlescent_froglight",
|
||||
"minecraft:verdant_froglight",
|
||||
"minecraft:ochre_froglight"
|
||||
]
|
||||
}
|
@ -1,85 +1,86 @@
|
||||
{
|
||||
"version": 1,
|
||||
"blocks": [
|
||||
"minecraft:black_concrete",
|
||||
"minecraft:black_concrete_powder",
|
||||
"minecraft:black_glazed_terracotta",
|
||||
"minecraft:black_terracotta",
|
||||
"minecraft:black_wool",
|
||||
"minecraft:blue_concrete",
|
||||
"minecraft:blue_concrete_powder",
|
||||
"minecraft:blue_glazed_terracotta",
|
||||
"minecraft:blue_terracotta",
|
||||
"minecraft:blue_wool",
|
||||
"minecraft:brown_concrete",
|
||||
"minecraft:brown_concrete_powder",
|
||||
"minecraft:brown_glazed_terracotta",
|
||||
"minecraft:brown_terracotta",
|
||||
"minecraft:brown_wool",
|
||||
"minecraft:cyan_concrete",
|
||||
"minecraft:cyan_concrete_powder",
|
||||
"minecraft:cyan_glazed_terracotta",
|
||||
"minecraft:cyan_terracotta",
|
||||
"minecraft:cyan_wool",
|
||||
"minecraft:gray_concrete",
|
||||
"minecraft:gray_concrete_powder",
|
||||
"minecraft:gray_glazed_terracotta",
|
||||
"minecraft:gray_terracotta",
|
||||
"minecraft:gray_wool",
|
||||
"minecraft:green_concrete",
|
||||
"minecraft:green_concrete_powder",
|
||||
"minecraft:green_glazed_terracotta",
|
||||
"minecraft:green_terracotta",
|
||||
"minecraft:green_wool",
|
||||
"minecraft:light_blue_concrete",
|
||||
"minecraft:light_blue_concrete_powder",
|
||||
"minecraft:light_blue_glazed_terracotta",
|
||||
"minecraft:light_blue_terracotta",
|
||||
"minecraft:light_blue_wool",
|
||||
"minecraft:light_gray_concrete",
|
||||
"minecraft:light_gray_concrete_powder",
|
||||
"minecraft:light_gray_glazed_terracotta",
|
||||
"minecraft:light_gray_terracotta",
|
||||
"minecraft:light_gray_wool",
|
||||
"minecraft:lime_concrete",
|
||||
"minecraft:lime_concrete_powder",
|
||||
"minecraft:lime_glazed_terracotta",
|
||||
"minecraft:lime_terracotta",
|
||||
"minecraft:lime_wool",
|
||||
"minecraft:magenta_concrete",
|
||||
"minecraft:magenta_concrete_powder",
|
||||
"minecraft:magenta_glazed_terracotta",
|
||||
"minecraft:magenta_terracotta",
|
||||
"minecraft:magenta_wool",
|
||||
"minecraft:orange_concrete",
|
||||
"minecraft:orange_concrete_powder",
|
||||
"minecraft:orange_glazed_terracotta",
|
||||
"minecraft:orange_terracotta",
|
||||
"minecraft:orange_wool",
|
||||
"minecraft:pink_concrete",
|
||||
"minecraft:pink_concrete_powder",
|
||||
"minecraft:pink_glazed_terracotta",
|
||||
"minecraft:pink_terracotta",
|
||||
"minecraft:pink_wool",
|
||||
"minecraft:purple_concrete",
|
||||
"minecraft:purple_concrete_powder",
|
||||
"minecraft:purple_glazed_terracotta",
|
||||
"minecraft:purple_terracotta",
|
||||
"minecraft:purple_wool",
|
||||
"minecraft:red_concrete",
|
||||
"minecraft:red_concrete_powder",
|
||||
"minecraft:red_glazed_terracotta",
|
||||
"minecraft:red_terracotta",
|
||||
"minecraft:red_wool",
|
||||
"minecraft:white_concrete",
|
||||
"minecraft:white_concrete_powder",
|
||||
"minecraft:white_glazed_terracotta",
|
||||
"minecraft:white_terracotta",
|
||||
"minecraft:white_wool",
|
||||
"minecraft:yellow_concrete",
|
||||
"minecraft:yellow_concrete_powder",
|
||||
"minecraft:yellow_glazed_terracotta",
|
||||
"minecraft:yellow_terracotta",
|
||||
"minecraft:yellow_wool"
|
||||
"black_concrete",
|
||||
"black_concrete_powder",
|
||||
"black_glazed_terracotta",
|
||||
"black_terracotta",
|
||||
"black_wool",
|
||||
"blue_concrete",
|
||||
"blue_concrete_powder",
|
||||
"blue_glazed_terracotta",
|
||||
"blue_terracotta",
|
||||
"blue_wool",
|
||||
"brown_concrete",
|
||||
"brown_concrete_powder",
|
||||
"brown_glazed_terracotta",
|
||||
"brown_terracotta",
|
||||
"brown_wool",
|
||||
"cyan_concrete",
|
||||
"cyan_concrete_powder",
|
||||
"cyan_glazed_terracotta",
|
||||
"cyan_terracotta",
|
||||
"cyan_wool",
|
||||
"gray_concrete",
|
||||
"gray_concrete_powder",
|
||||
"gray_glazed_terracotta",
|
||||
"gray_terracotta",
|
||||
"gray_wool",
|
||||
"green_concrete",
|
||||
"green_concrete_powder",
|
||||
"green_glazed_terracotta",
|
||||
"green_terracotta",
|
||||
"green_wool",
|
||||
"light_blue_concrete",
|
||||
"light_blue_concrete_powder",
|
||||
"light_blue_glazed_terracotta",
|
||||
"light_blue_terracotta",
|
||||
"light_blue_wool",
|
||||
"light_gray_concrete",
|
||||
"light_gray_concrete_powder",
|
||||
"light_gray_glazed_terracotta",
|
||||
"light_gray_terracotta",
|
||||
"light_gray_wool",
|
||||
"lime_concrete",
|
||||
"lime_concrete_powder",
|
||||
"lime_glazed_terracotta",
|
||||
"lime_terracotta",
|
||||
"lime_wool",
|
||||
"magenta_concrete",
|
||||
"magenta_concrete_powder",
|
||||
"magenta_glazed_terracotta",
|
||||
"magenta_terracotta",
|
||||
"magenta_wool",
|
||||
"orange_concrete",
|
||||
"orange_concrete_powder",
|
||||
"orange_glazed_terracotta",
|
||||
"orange_terracotta",
|
||||
"orange_wool",
|
||||
"pink_concrete",
|
||||
"pink_concrete_powder",
|
||||
"pink_glazed_terracotta",
|
||||
"pink_terracotta",
|
||||
"pink_wool",
|
||||
"purple_concrete",
|
||||
"purple_concrete_powder",
|
||||
"purple_glazed_terracotta",
|
||||
"purple_terracotta",
|
||||
"purple_wool",
|
||||
"red_concrete",
|
||||
"red_concrete_powder",
|
||||
"red_glazed_terracotta",
|
||||
"red_terracotta",
|
||||
"red_wool",
|
||||
"white_concrete",
|
||||
"white_concrete_powder",
|
||||
"white_glazed_terracotta",
|
||||
"white_terracotta",
|
||||
"white_wool",
|
||||
"yellow_concrete",
|
||||
"yellow_concrete_powder",
|
||||
"yellow_glazed_terracotta",
|
||||
"yellow_terracotta",
|
||||
"yellow_wool",
|
||||
"glowstone",
|
||||
"sea_lantern"
|
||||
]
|
||||
}
|
34
res/transparent_blocks.json
Normal file
34
res/transparent_blocks.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"transparent_blocks": [
|
||||
"minecraft:frosted_ice",
|
||||
"minecraft:glass",
|
||||
"minecraft:white_stained_glass",
|
||||
"minecraft:orange_stained_glass",
|
||||
"minecraft:magenta_stained_glass",
|
||||
"minecraft:light_blue_stained_glass",
|
||||
"minecraft:yellow_stained_glass",
|
||||
"minecraft:lime_stained_glass",
|
||||
"minecraft:pink_stained_glass",
|
||||
"minecraft:gray_stained_glass",
|
||||
"minecraft:light_gray_stained_glass",
|
||||
"minecraft:cyan_stained_glass",
|
||||
"minecraft:purple_stained_glass",
|
||||
"minecraft:blue_stained_glass",
|
||||
"minecraft:brown_stained_glass",
|
||||
"minecraft:green_stained_glass",
|
||||
"minecraft:red_stained_glass",
|
||||
"minecraft:black_stained_glass",
|
||||
"minecraft:ice",
|
||||
"minecraft:oak_leaves",
|
||||
"minecraft:spruce_leaves",
|
||||
"minecraft:birch_leaves",
|
||||
"minecraft:jungle_leaves",
|
||||
"minecraft:acacia_leaves",
|
||||
"minecraft:dark_oak_leaves",
|
||||
"minecraft:mangrove_leaves",
|
||||
"minecraft:azalea_leaves",
|
||||
"minecraft:flowering_azalea_leaves",
|
||||
"minecraft:slime_block",
|
||||
"minecraft:honey_block"
|
||||
]
|
||||
}
|
@ -8,7 +8,7 @@ import { ChunkedBufferGenerator, TBlockMeshBufferDescription } from './buffer';
|
||||
import { Palette } from './palette';
|
||||
import { ProgressManager } from './progress';
|
||||
import { StatusHandler } from './status';
|
||||
import { ColourSpace } from './util';
|
||||
import { ColourSpace, TOptional } from './util';
|
||||
import { AppError, ASSERT } from './util/error_util';
|
||||
import { LOGF } from './util/log_util';
|
||||
import { AppPaths, PathUtil } from './util/path_util';
|
||||
@ -36,9 +36,11 @@ export class BlockMesh {
|
||||
private _blocks: Block[];
|
||||
private _voxelMesh: VoxelMesh;
|
||||
private _fallableBlocks: string[];
|
||||
private _transparentBlocks: string[];
|
||||
private _emissiveBlocks: string[];
|
||||
private _atlas: Atlas;
|
||||
private _lightingNew: Array<number>;
|
||||
private _posToLightingBufferIndex: (vec: Vector3) => number;
|
||||
private _lightingNew: Buffer;
|
||||
private _posToLightingBufferIndex: (vec: Vector3) => { index: number, left: boolean };
|
||||
private _posIsValid: (vec: Vector3) => boolean;
|
||||
|
||||
public static createFromVoxelMesh(voxelMesh: VoxelMesh, blockMeshParams: AssignParams.Input) {
|
||||
@ -54,13 +56,19 @@ export class BlockMesh {
|
||||
this._voxelMesh = voxelMesh;
|
||||
this._atlas = Atlas.getVanillaAtlas()!;
|
||||
//this._lighting = new Map<string, number>();
|
||||
this._lightingNew = new Array<number>();
|
||||
this._lightingNew = Buffer.alloc(0);
|
||||
//this._recreateBuffer = true;
|
||||
this._posToLightingBufferIndex = () => { return 0; };
|
||||
this._posToLightingBufferIndex = () => { return { index: 0, left: false }; };
|
||||
this._posIsValid = () => { return false; };
|
||||
|
||||
const fallableBlocksString = fs.readFileSync(PathUtil.join(AppPaths.Get.resources, 'fallable_blocks.json'), 'utf-8');
|
||||
this._fallableBlocks = JSON.parse(fallableBlocksString).fallable_blocks;
|
||||
|
||||
const transparentlocksString = fs.readFileSync(PathUtil.join(AppPaths.Get.resources, 'transparent_blocks.json'), 'utf-8');
|
||||
this._transparentBlocks = JSON.parse(transparentlocksString).transparent_blocks;
|
||||
|
||||
const emissivelocksString = fs.readFileSync(PathUtil.join(AppPaths.Get.resources, 'emissive_blocks.json'), 'utf-8');
|
||||
this._emissiveBlocks = JSON.parse(emissivelocksString).emissive_blocks;
|
||||
}
|
||||
|
||||
private _assignBlocks(blockMeshParams: AssignParams.Input) {
|
||||
@ -153,23 +161,41 @@ export class BlockMesh {
|
||||
];
|
||||
}
|
||||
|
||||
private _internalGetLight(vec: Vector3) {
|
||||
private _internalGetLight(vec: Vector3): TOptional<number> {
|
||||
if (this._posIsValid(vec)) {
|
||||
return this._lightingNew[this._posToLightingBufferIndex(vec)];
|
||||
const index = this._posToLightingBufferIndex(vec);
|
||||
const value = this._lightingNew[index.index];
|
||||
return (index.left ? (value >> 4) : value) & 0xF;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _internalSetLight(vec: Vector3, value: number) {
|
||||
const index = this._posToLightingBufferIndex(vec);
|
||||
if (index.left) {
|
||||
this._lightingNew[index.index] = (this._lightingNew[index.index] & 0xF) + (value << 4);
|
||||
} else {
|
||||
this._lightingNew[index.index] = (this._lightingNew[index.index] & (0xF << 4)) + value;
|
||||
}
|
||||
return 15;
|
||||
}
|
||||
|
||||
private _calculateLighting() {
|
||||
const blocksBounds = this._voxelMesh.getBounds();
|
||||
const sizeVector = blocksBounds.getDimensions().add(1).add(2);
|
||||
this._lightingNew = new Array<number>(sizeVector.x * sizeVector.y * sizeVector.z).fill(0);
|
||||
|
||||
// Number of blocks to store lighting values for.
|
||||
const numBlocks = sizeVector.x * sizeVector.y * sizeVector.z;
|
||||
// Each block takes up 4-bits
|
||||
const numBytes = Math.ceil(numBlocks * 0.5);
|
||||
this._lightingNew = Buffer.alloc(numBytes);
|
||||
|
||||
this._posToLightingBufferIndex = (vec: Vector3) => {
|
||||
const indexVector = Vector3.sub(vec, Vector3.sub(blocksBounds.min, 1));
|
||||
const index = (sizeVector.z * sizeVector.x * indexVector.y) + (sizeVector.x * indexVector.z) + indexVector.x;
|
||||
//ASSERT(index >= 0 && index < this._lightingNew.length);
|
||||
return index;
|
||||
return {
|
||||
index: Math.floor(index * 0.5),
|
||||
left: index % 2 === 0,
|
||||
};
|
||||
};
|
||||
|
||||
this._posIsValid = (vec: Vector3) => {
|
||||
@ -194,40 +220,48 @@ export class BlockMesh {
|
||||
}
|
||||
|
||||
while (actions.length > 0) {
|
||||
const action = actions.pop();
|
||||
ASSERT(action !== undefined);
|
||||
const action = actions.pop()!;
|
||||
const newLightValue = action.value;
|
||||
|
||||
if (!this._posIsValid(action.pos)) {
|
||||
continue;
|
||||
}
|
||||
const bufferIndex = this._posToLightingBufferIndex(action.pos);
|
||||
const currentLightValue = this._lightingNew[bufferIndex] ?? 0;
|
||||
|
||||
/*
|
||||
const currentLightValue = this._lighting.get(action.pos.stringify());
|
||||
// We're trying to update the lighting value of an out-of-bounds block, skip.
|
||||
if (currentLightValue === undefined) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
const currentLightValue = this._internalGetLight(action.pos) ?? 0;
|
||||
|
||||
// Update lighting values only if the new value is lighter than the current brightness.
|
||||
if (newLightValue > currentLightValue && !this._voxelMesh.isVoxelAt(action.pos)) {
|
||||
//this._lighting.set(action.pos.stringify(), newLightValue);
|
||||
this._lightingNew[bufferIndex] = newLightValue;
|
||||
//this._lightingNew
|
||||
const blockHere = this.getBlockAt(action.pos);
|
||||
if (blockHere !== undefined && this._emissiveBlocks.includes(blockHere.blockInfo.name)) {
|
||||
if (this._internalGetLight(action.pos)! < 14) {
|
||||
this._internalSetLight(action.pos, 14);
|
||||
actions.push({ pos: new Vector3(0, 1, 0).add(action.pos), value: 14 });
|
||||
actions.push({ pos: new Vector3(1, 0, 0).add(action.pos), value: 14 });
|
||||
actions.push({ pos: new Vector3(0, 0, 1).add(action.pos), value: 14 });
|
||||
actions.push({ pos: new Vector3(-1, 0, 0).add(action.pos), value: 14 });
|
||||
actions.push({ pos: new Vector3(0, 0, -1).add(action.pos), value: 14 });
|
||||
actions.push({ pos: new Vector3(0, -1, 0).add(action.pos), value: 14 });
|
||||
}
|
||||
} else if (newLightValue > currentLightValue) {
|
||||
if (blockHere === undefined || this._transparentBlocks.includes(blockHere.blockInfo.name)) {
|
||||
this._internalSetLight(action.pos, newLightValue);
|
||||
|
||||
actions.push({ pos: new Vector3(0, 1, 0).add(action.pos), value: newLightValue - 1 }); // up
|
||||
actions.push({ pos: new Vector3(1, 0, 0).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(0, 0, 1).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(-1, 0, 0).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(0, 0, -1).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(0, -1, 0).add(action.pos), value: newLightValue === 15 ? 15 : newLightValue - 1 }); // down
|
||||
actions.push({ pos: new Vector3(0, 1, 0).add(action.pos), value: newLightValue - 1 }); // up
|
||||
actions.push({ pos: new Vector3(1, 0, 0).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(0, 0, 1).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(-1, 0, 0).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(0, 0, -1).add(action.pos), value: newLightValue - 1 });
|
||||
actions.push({ pos: new Vector3(0, -1, 0).add(action.pos), value: newLightValue === 15 ? 15 : newLightValue - 1 }); // down
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getBlockAt(pos: Vector3): TOptional<Block> {
|
||||
const index = this._voxelMesh.getVoxelIndex(pos);
|
||||
if (index !== undefined) {
|
||||
return this._blocks[index];
|
||||
}
|
||||
}
|
||||
|
||||
public getBlocks(): Block[] {
|
||||
return this._blocks;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ export class ChunkedBufferGenerator {
|
||||
|
||||
for (let f = 0; f < AppConstants.FACES_PER_VOXEL; ++f) {
|
||||
const faceName = faceOrder[f];
|
||||
const faceLighting = lightingRamp.get(blockLighting[f]) ?? 1.0;
|
||||
const faceLighting = lightingRamp.get(blockLighting[f] ?? 15) ?? 1.0;
|
||||
|
||||
const texcoord = blocks[blockIndex].blockInfo.faces[faceName].texcoord;
|
||||
for (let v = 0; v < AppConstants.VERTICES_PER_FACE; ++v) {
|
||||
|
@ -84,6 +84,10 @@ export class VoxelMesh {
|
||||
return this._bounds;
|
||||
}
|
||||
|
||||
public getVoxelIndex(pos: Vector3) {
|
||||
return this._voxelsHash.get(pos.stringify());
|
||||
}
|
||||
|
||||
public getVoxelCount() {
|
||||
return this._voxels.length;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user