Closed MCArth closed 1 year ago
Hmm, I've not seen either of these. Can you share the code you're using to create the mesh you're using, and the code where you register it as an object block?
I've been able the object at local 0,0,0 in stress:
With the following code:
import { Engine } from 'noa-engine'
// registration
import atlasURL from '../textures/terrain_atlas.png'
import tallgrass from '../textures/tallgrass.png'
import { Mesh, PBRMaterial, PlaneBuilder, Texture } from '@babylonjs/core'
var noa = new Engine({
debug: true,
showFPS: true,
// inverseY: true,
chunkSize: 48,
chunkAddDistance: [1, 1],
playerStart: [0, 10, 0],
playerAutoStep: true,
})
noa.registry.registerMaterial('grass', { textureURL: atlasURL, atlasIndex: 0 })
noa.registry.registerMaterial('g_dirt', { textureURL: atlasURL, atlasIndex: 1 })
noa.registry.registerMaterial('dirt', { textureURL: atlasURL, atlasIndex: 2 })
noa.registry.registerMaterial('stone', { textureURL: atlasURL, atlasIndex: 3 })
noa.registry.registerMaterial('stone2', { textureURL: atlasURL, atlasIndex: 4 })
noa.registry.registerMaterial('cloud', { textureURL: atlasURL, atlasIndex: 5 })
noa.registry.registerMaterial('seethrough', { textureURL: atlasURL, atlasIndex: 6, texHasAlpha: true })
var id = 1
var dirt = noa.registry.registerBlock(id++, { material: 'dirt' })
var grass = noa.registry.registerBlock(id++, { material: 'grass' })
var stone = noa.registry.registerBlock(id++, { material: 'stone' })
var stone2 = noa.registry.registerBlock(id++, { material: 'stone2' })
// var cloud = noa.registry.registerBlock(id++, { material: 'cloud', opaque: false })
// var seethrough = noa.registry.registerBlock(id++, { material: 'seethrough', opaque: false })
var centrecross = noa.registry.registerBlock(id++, {
blockMesh: getCentreCrossModel(noa, tallgrass),
opaque: true,
solid: true,
onCustomMeshCreate: null,
})
function getCentreCrossModel(noa, tex) {
const scene = noa.rendering.getScene()
const plane1 = PlaneBuilder.CreatePlane(
`BlkMdl1`,
{
size: 1,
sideOrientation: Mesh.DOUBLESIDE,
},
scene
)
plane1.isPickable = false
plane1.rotation.x = Math.PI
plane1.position.y = 0.5
plane1.bakeCurrentTransformIntoVertices()
plane1.setEnabled(false)
const plane2 = PlaneBuilder.CreatePlane(
`BlkMdl2`,
{size: 1, sideOrientation: Mesh.DOUBLESIDE},
scene
)
plane2.isPickable = false
plane2.rotation.y = Math.PI / 2
plane2.rotation.z = Math.PI
plane2.position.y = 0.5
plane2.bakeCurrentTransformIntoVertices()
plane2.setEnabled(false)
const mat = new PBRMaterial(`BlockModelMeshMat`, scene)
const texture = new Texture(tex, scene, null, null, 1)
mat.unlit = true
texture.hasAlpha = true
mat.albedoTexture = texture
mat.freeze()
plane1.material = mat
plane2.material = mat
const mergedMesh = Mesh.MergeMeshes([plane1, plane2], true, false, null, false, true)
mergedMesh.isPickable = false
plane1.dispose()
plane2.dispose()
return mergedMesh
}
// worldgen
var decideVoxel = (x, y, z, ht, clo, chi, pillar) => {
let id = 1+Math.floor(Math.random()*4)
// if (Math.random() < 0.00002) {
// id = 5
// }
if (y < ht) {
return id
}
if (y < ht + pillar) return id
if (y > clo && y < chi) return id
if (y < ht+1 && Math.random() < 0.0002) {
return 5
}
return 0
}
noa.world.on('worldDataNeeded', async (requestID, data, cx, cy, cz) => {
await waitMs(1000)
for (var i = 0; i < data.shape[0]; i++) {
var x = cx + i
for (var k = 0; k < data.shape[2]; k++) {
var z = cz + k
var ht = Math.sqrt(x * x + z * z) / 100
var a = noise(x, 150)
var b = noise(z + 50, 140)
var c = noise(x - z - 50, 120)
ht += 2 * a + b + c
var pillar = (Math.random() < 0.002) ? 5 : 0
var clo = 39 + 2 * (b - c)
var chi = 35 + 2 * (a - b)
for (var j = 0; j < data.shape[1]; j++) {
var y = cy + j
var id = decideVoxel(x, y, z, ht, clo, chi, pillar)
data.set(i, j, k, id)
}
}
}
// tell noa the chunk's terrain data is now set
noa.world.setChunkData(requestID, data)
})
async function waitMs(ms) {
return new Promise(((resolve, reject) => {
setTimeout(() => {
resolve()
}, ms)
}))
}
add the following texture:
to repro just fly backwards on first load. you might have to do it a few times to get it to repro
(i havent seen the "briefly flashing on screen" bit, but hopefully that's related and can be fixed simultaneously)
Hey, thanks very much for the complete repro steps. This was really thorny, it seems to have been a timing issue with Babylon internals, which depended on the timing of the call to mat.freeze()
(but only in the case of PBR materials).
I've pushed a fix that seems to resolve it - can you check? I was only really able to reproduce the issue sporadically, so it's hard to be sure about a fix.
Thanks for looking into it. It's always the race conditions that get you 😅
Seems to fix it for me as well
something to consider: it could be good to lock to a specific babylon version in both noa and the examples (or at least only allow patch upgrades with ~). An awful amount of things seem to break with babylon updates
Thanks for checking! Let's hope this is the last we see of this one...
Hi, I've brought in the changes and I'm encountering an object meshing bug. Occasionally an object will just appear at local position 0, 0, 0 (so it follows you around). When this happens, placing an object of that type results in no object thin instance being placed inside the placed block position (so I'm theorising the object at 0, 0, 0 is lots of the object stacked on top of each other). I've encountered this on both babylon 5.14.1 and 5.25.0.
I know there were changes as a result of changes to babylon internals, perhaps this is related.
I've also noticed now when I first open the world, object meshes briefly flash visible on the screen (also at 0, 0, 0 local I think). This isn't such a big deal but may also be related. Unsure when the thin instances are placed at the correct position, if there's a gap that could explain the brief flashing.