Compare commits
1 commit
next
...
light-bloc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edae93f29f |
3 changed files with 96 additions and 36 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue