Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Vitaly
e46b16fa0d fix: better skylight calculation 2024-05-03 19:20:31 +03:00
5 changed files with 71 additions and 28 deletions

View file

@ -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

View file

@ -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)
}

View file

@ -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) {

View file

@ -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,50913,669
if (timeOfDay > 13.508 && timeOfDay < 13.669) return 5
// 22,49222,652
if (timeOfDay > 22.491 && timeOfDay < 22.652) return 6
// or 13,34813,508
if (timeOfDay > 13.347 && timeOfDay < 13.508) return 6
// 22,65322,812
if (timeOfDay > 22.652 && timeOfDay < 22.812) return 7
// or 13,18813,347
if (timeOfDay > 13.187 && timeOfDay < 13.347) return 7
// 22,813-22,973 or 13,02713,187
if (timeOfDay > 22.812 && timeOfDay < 22.973 || timeOfDay > 13.027 && timeOfDay < 13.187) {
return 8
}
// 22,97423,134 or 12,86713,026
if (timeOfDay > 22.973 && timeOfDay < 23.134 || timeOfDay > 12.867 && timeOfDay < 13.026) {
return 9
}
// 23,13523,296 or 12,70512,866
if (timeOfDay > 23.134 && timeOfDay < 23.296 || timeOfDay > 12.705 && timeOfDay < 12.866) {
return 10
}
// 23,29723,459 or 12,54212,704
if (timeOfDay > 23.296 && timeOfDay < 23.459 || timeOfDay > 12.542 && timeOfDay < 12.704) {
return 11
}
// 23,46023,623 or 12,37712,541
if (timeOfDay > 23.459 && timeOfDay < 23.623 || timeOfDay > 12.377 && timeOfDay < 12.541) {
return 12
}
// 23,62423,790 or 12,21012,376
if (timeOfDay > 23.623 && timeOfDay < 23.790 || timeOfDay > 12.210 && timeOfDay < 12.376) {
return 13
}
// 23,79123,960 or 12,04112,209
if (timeOfDay > 23.790 || timeOfDay < 12.041) {
return 14
}
return 15
}

View file

@ -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
}
const sunLightLevel = getSunlightLevel(timeOfDay)
skyLight = Math.floor(skyLight) // todo: remove this after optimization
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')