diff --git a/prismarine-viewer/examples/playground.ts b/prismarine-viewer/examples/playground.ts index 295cc47d5..bfc337d45 100644 --- a/prismarine-viewer/examples/playground.ts +++ b/prismarine-viewer/examples/playground.ts @@ -111,10 +111,19 @@ async function main () { const chunk1 = new Chunk() //@ts-ignore const chunk2 = new Chunk() - chunk1.setBlockStateId(targetPos, 34) - chunk2.setBlockStateId(targetPos.offset(1, 0, 0), 34) + const addNeighbor = (x, z, light = 15) => { + x += 2 + chunk1.setBlockStateId(targetPos.offset(x, 0, z), 1) + chunk1.setBlockLight(targetPos.offset(x, 1, z), light) + } + addNeighbor(0, 1) + addNeighbor(0, -1) + addNeighbor(1, 0) + addNeighbor(-1, 0) + chunk1.setBlockStateId(targetPos.offset(1, 1, 0), mcData.blocksByName['grass'].minStateId) + addNeighbor(0, 0, 0) const world = new World((chunkX, chunkZ) => { - // if (chunkX === 0 && chunkZ === 0) return chunk1 + if (chunkX === 0 && chunkZ === 0) return chunk1 // if (chunkX === 1 && chunkZ === 0) return chunk2 //@ts-ignore const chunk = new Chunk() @@ -124,6 +133,7 @@ async function main () { // await schem.paste(world, new Vec3(0, 60, 0)) const worldView = new WorldDataEmitter(world, viewDistance, targetPos) + globalThis.worldView = worldView // Create three.js context, add to page const renderer = new THREE.WebGLRenderer({ alpha: true, ...localStorage['renderer'] }) @@ -132,7 +142,8 @@ async function main () { document.body.appendChild(renderer.domElement) // Create viewer - const viewer = new Viewer(renderer, { numWorkers: 1, showChunkBorders: false }) + const viewer = new Viewer(renderer, {showChunkBorders: true, numWorkers: 1,}) + globalThis.viewer = viewer viewer.entities.setDebugMode('basic') viewer.setVersion(version) viewer.entities.onSkinUpdate = () => { @@ -142,8 +153,6 @@ async function main () { viewer.listen(worldView) // Load chunks await worldView.init(targetPos) - window['worldView'] = worldView - window['viewer'] = viewer params.blockIsomorphicRenderBundle = () => { const canvas = renderer.domElement diff --git a/prismarine-viewer/viewer/lib/mesher/models.ts b/prismarine-viewer/viewer/lib/mesher/models.ts index 833de1807..ed90f9d4d 100644 --- a/prismarine-viewer/viewer/lib/mesher/models.ts +++ b/prismarine-viewer/viewer/lib/mesher/models.ts @@ -349,8 +349,7 @@ function renderElement (world: World, cursor: Vec3, element, doAO: boolean, attr const aos: number[] = [] const neighborPos = position.plus(new Vec3(...dir)) - let baseLightLevel = world.getLight(neighborPos) - const baseLight = baseLightLevel / 15 + const baseLight = world.getLight(neighborPos) for (const pos of corners) { let vertex = [ (pos[0] ? maxx : minx), @@ -386,7 +385,7 @@ function renderElement (world: World, cursor: Vec3, element, doAO: boolean, attr const side2 = world.getBlock(cursor.offset(...side2Dir)) const corner = world.getBlock(cursor.offset(...cornerDir)) - let cornerLightResult = 15 + let cornerLightResult = 1 if (/* world.config.smoothLighting */false) { // todo fix const side1Light = world.getLight(cursor.plus(new Vec3(...side1Dir)), true) const side2Light = world.getLight(cursor.plus(new Vec3(...side2Dir)), true) @@ -403,7 +402,7 @@ function renderElement (world: World, cursor: Vec3, element, doAO: boolean, attr const ao = (side1Block && side2Block) ? 0 : (3 - (side1Block + side2Block + cornerBlock)) // todo light should go upper on lower blocks - light = (ao + 1) / 4 * (cornerLightResult / 15) + light = (ao + 1) / 4 * cornerLightResult aos.push(ao) } diff --git a/prismarine-viewer/viewer/lib/mesher/world.ts b/prismarine-viewer/viewer/lib/mesher/world.ts index 9a4f0ab3e..f36050bdd 100644 --- a/prismarine-viewer/viewer/lib/mesher/world.ts +++ b/prismarine-viewer/viewer/lib/mesher/world.ts @@ -44,19 +44,21 @@ export class World { // if (lightsCache.has(key)) return lightsCache.get(key) const column = this.getColumnByPos(pos) if (!column || !hasChunkSection(column, pos)) return 15 + let skyLightBlock = column.getSkyLight(posInChunk(pos)); + if (skyLightBlock === 0) skyLightBlock = column.getSkyLight(posInChunk(pos.offset(0, 1, 0))); let result = Math.min( 15, Math.max( column.getBlockLight(posInChunk(pos)), - Math.min(skyLight, column.getSkyLight(posInChunk(pos))) - ) + 2 + Math.min(skyLight, skyLightBlock) + ) ) // lightsCache.set(key, result) if (result === 2 && this.getBlock(pos)?.name.match(/_stairs|slab/)) { // todo this is obviously wrong result = this.getLight(pos.offset(0, 1, 0)) } if (isNeighbor && result === 2) result = 15 // TODO - return result + return Math.max(result / 15, 0.25) } addColumn (x, z, json) { diff --git a/prismarine-viewer/viewer/lib/sunlight.ts b/prismarine-viewer/viewer/lib/sunlight.ts new file mode 100644 index 000000000..c3a084a3b --- /dev/null +++ b/prismarine-viewer/viewer/lib/sunlight.ts @@ -0,0 +1,43 @@ +export const getSunlightLevel = (timeOfDay: number) => { + if (timeOfDay > 13.670 && timeOfDay < 22.330) return 4 + if (timeOfDay > 22.33 && timeOfDay < 22.491) return 5 + // or 13,509–13,669 + if (timeOfDay > 13.508 && timeOfDay < 13.669) return 5 + // 22,492–22,652 + if (timeOfDay > 22.491 && timeOfDay < 22.652) return 6 + // or 13,348–13,508 + if (timeOfDay > 13.347 && timeOfDay < 13.508) return 6 + // 22,653–22,812‌ + if (timeOfDay > 22.652 && timeOfDay < 22.812) return 7 + // or 13,188–13,347 + if (timeOfDay > 13.187 && timeOfDay < 13.347) return 7 + // 22,813‌-22,973 or 13,027–13,187 + if (timeOfDay > 22.812 && timeOfDay < 22.973 || timeOfDay > 13.027 && timeOfDay < 13.187) { + return 8 + } + // 22,974–23,134 or 12,867–13,026 + if (timeOfDay > 22.973 && timeOfDay < 23.134 || timeOfDay > 12.867 && timeOfDay < 13.026) { + return 9 + } + // 23,135–23,296 or 12,705–12,866 + if (timeOfDay > 23.134 && timeOfDay < 23.296 || timeOfDay > 12.705 && timeOfDay < 12.866) { + return 10 + } + // 23,297–23,459 or 12,542–12,704 + if (timeOfDay > 23.296 && timeOfDay < 23.459 || timeOfDay > 12.542 && timeOfDay < 12.704) { + return 11 + } + // 23,460–23,623‌ or 12,377–12,541 + if (timeOfDay > 23.459 && timeOfDay < 23.623 || timeOfDay > 12.377 && timeOfDay < 12.541) { + return 12 + } + // 23,624–23,790 or 12,210–12,376 + if (timeOfDay > 23.623 && timeOfDay < 23.790 || timeOfDay > 12.210 && timeOfDay < 12.376) { + return 13 + } + // 23,791–23,960 or 12,041–12,209 + if (timeOfDay > 23.790 || timeOfDay < 12.041) { + return 14 + } + return 15 +} diff --git a/prismarine-viewer/viewer/lib/viewer.ts b/prismarine-viewer/viewer/lib/viewer.ts index 9cb7eb3db..42c27222e 100644 --- a/prismarine-viewer/viewer/lib/viewer.ts +++ b/prismarine-viewer/viewer/lib/viewer.ts @@ -7,6 +7,7 @@ import EventEmitter from 'events' import { WorldRendererThree } from './worldrendererThree' import { generateSpiralMatrix } from 'flying-squid/dist/utils' import { WorldRendererCommon, WorldRendererConfig, defaultWorldRendererConfig } from './worldrendererCommon' +import { getSunlightLevel } from './sunlight' export class Viewer { scene: THREE.Scene @@ -180,22 +181,11 @@ export class Viewer { }) emitter.on('time', (timeOfDay) => { - let skyLight = 15 - if (timeOfDay < 0 || timeOfDay > 24000) { - throw new Error("Invalid time of day. It should be between 0 and 24000.") - } else if (timeOfDay <= 6000 || timeOfDay >= 18000) { - skyLight = 15 - } else if (timeOfDay > 6000 && timeOfDay < 12000) { - skyLight = 15 - ((timeOfDay - 6000) / 6000) * 15 - } else if (timeOfDay >= 12000 && timeOfDay < 18000) { - skyLight = ((timeOfDay - 12000) / 6000) * 15 - } - - skyLight = Math.floor(skyLight) // todo: remove this after optimization + const sunLightLevel = getSunlightLevel(timeOfDay) - if (this.world.mesherConfig.skyLight === skyLight) return - this.world.mesherConfig.skyLight = skyLight - ; (this.world as WorldRendererThree).rerenderAllChunks?.() + if (this.world.mesherConfig.skyLight === sunLightLevel) return + this.world.mesherConfig.skyLight = sunLightLevel; + (this.world as WorldRendererThree).rerenderAllChunks?.() }) emitter.emit('listening')