Compare commits

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

1 commit

Author SHA1 Message Date
Vitaly Turovsky
edae93f29f fix: improve block light calculation (but still wrong) 2024-05-11 21:21:09 +03:00
3 changed files with 96 additions and 36 deletions

View file

@ -300,6 +300,15 @@ function renderElement (world: World, cursor: Vec3, element, doAO: boolean, attr
const maxy = element.to[1]
const maxz = element.to[2]
const isConnectedWithTheBlock = (
(face === 'up' && maxy === 16) ||
(face === 'down' && miny === 0) ||
(face === 'north' && minz === 0) ||
(face === 'south' && maxz === 16) ||
(face === 'west' && minx === 0) ||
(face === 'east' && maxx === 16)
)
const u = eFace.texture.u
const v = eFace.texture.v
const su = eFace.texture.su
@ -349,7 +358,7 @@ function renderElement (world: World, cursor: Vec3, element, doAO: boolean, attr
const aos: number[] = []
const neighborPos = position.plus(new Vec3(...dir))
const baseLight = world.getLight(neighborPos) / 15
const baseLight = world.getLight(isConnectedWithTheBlock ? neighborPos : position) / 15
for (const pos of corners) {
let vertex = [
(pos[0] ? maxx : minx),

View file

@ -1,43 +1,44 @@
import { test, expect } from 'vitest'
import { setup } from './mesherTester'
import { BlockNames } from '../../../../../src/mcDataTypes'
const version = '1.18.1'
const addPositions = [
// [[0, 0, 0], 'diamond_block'],
[[1, 0, 0], 'stone'],
[[-1, 0, 0], 'stone'],
[[0, 1, 0], 'stone'],
[[0, -1, 0], 'stone'],
[[0, 0, 1], 'stone'],
[[0, 0, -1], 'stone'],
// [[0, 0, 0], 'diamond_block'],
[[1, 0, 0], 'stone'],
[[-1, 0, 0], 'stone'],
[[0, 1, 0], 'stone'],
[[0, -1, 0], 'stone'],
[[0, 0, 1], 'stone'],
[[0, 0, -1], 'stone'],
] as const
test('Known blocks are not rendered', () => {
const { mesherWorld, getGeometry, pos, mcData } = setup(version, addPositions as any)
const { mesherWorld, getGeometry, pos, mcData } = setup(version, addPositions as any)
let time = 0
let times = 0
const invalidBlocks = {}/* as {[number, number]} */
for (const block of mcData.blocksArray) {
if (block.maxStateId! - block.minStateId! > 100) continue
for (let i = block.minStateId!; i <= block.maxStateId!; i++) {
if (block.transparent) continue
mesherWorld.setBlockStateId(pos, i)
const start = performance.now()
const { centerFaces, totalTiles, centerTileNeighbors } = getGeometry()
time += performance.now() - start
times++
if (centerFaces === 0 && centerTileNeighbors !== 0) {
if (invalidBlocks[block.name]) continue
invalidBlocks[block.name] = [i - block.minStateId!, centerTileNeighbors]
// console.log('INVALID', block.name, centerTileNeighbors, i - block.minStateId)
}
}
let time = 0
let times = 0
const invalidBlocks = {}/* as {[number, number]} */
for (const block of mcData.blocksArray) {
if (block.maxStateId! - block.minStateId! > 100) continue
for (let i = block.minStateId!; i <= block.maxStateId!; i++) {
if (block.transparent) continue
mesherWorld.setBlockStateId(pos, i)
const start = performance.now()
const { centerFaces, totalTiles, centerTileNeighbors } = getGeometry()
time += performance.now() - start
times++
if (centerFaces === 0 && centerTileNeighbors !== 0) {
if (invalidBlocks[block.name]) continue
invalidBlocks[block.name] = [i - block.minStateId!, centerTileNeighbors]
// console.log('INVALID', block.name, centerTileNeighbors, i - block.minStateId)
}
}
console.log('Average time', time / times)
// Fully expected
expect(invalidBlocks).toMatchInlineSnapshot(`
}
console.log('Average time', time / times)
// Fully expected
expect(invalidBlocks).toMatchInlineSnapshot(`
{
"creeper_head": [
0,
@ -94,3 +95,51 @@ test('Known blocks are not rendered', () => {
}
`)
})
test('Light calculated correctly', () => {
const result = {} as Record<string, any>
for (const block of ['oak_fence', 'oak_slab', 'soul_sand'] as BlockNames[]) {
const positions = [
[[0, 0, 0], block]
]
const { getLights, setLight, reload } = setup('1.20.2', positions as any)
setLight(0, 0, 0, 5)
setLight(0, -1, 0, 10)
setLight(0, 1, 0, 10)
setLight(1, 0, 0, 10)
setLight(-1, 0, 0, 10)
setLight(0, 0, 1, 10)
setLight(0, 0, -1, 10)
reload()
result[block] = getLights()
}
expect(result).toMatchInlineSnapshot(`
{
"oak_fence": {
"down": 10,
"east": 5,
"north": 5,
"south": 5,
"up": 10,
"west": 5,
},
"oak_slab": {
"down": 10,
"east": 10,
"north": 10,
"south": 10,
"up": 5,
"west": 10,
},
"soul_sand": {
"down": 10,
"east": 10,
"north": 10,
"south": 10,
"up": 10,
"west": 10,
},
}
`)
})

View file

@ -44,17 +44,18 @@ export class World {
// if (lightsCache.has(key)) return lightsCache.get(key)
const column = this.getColumnByPos(pos)
if (!column || !hasChunkSection(column, pos)) return 15
const posChunk = posInChunk(pos)
let result = Math.min(
15,
Math.max(
column.getBlockLight(posInChunk(pos)),
Math.min(skyLight, column.getSkyLight(posInChunk(pos)))
column.getBlockLight(posChunk),
Math.min(skyLight, column.getSkyLight(posChunk))
) + 2
)
// 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 (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
}
@ -128,7 +129,8 @@ export class World {
}
// todo export in chunk instead
const hasChunkSection = (column, pos) => {
export const hasChunkSection = (column, pos) => {
pos = posInChunk(pos)
if (column._getSection) return column._getSection(pos)
if (column.skyLightSections) {
return column.skyLightSections[getLightSectionIndex(pos, column.minY)] || column.blockLightSections[getLightSectionIndex(pos, column.minY)]