Closed Patbox closed 4 years ago
Hi, did you set texHasAlpha when registering the block material?
Basically, texture transparency comes down to the settings on the Babylon material applied to the mesh - noa makes one for you by default, but you can also make your own and pass it in.
Note: the [opaque](https://github.com/andyhall/noa/blob/master/src/lib/registry.js#L99)
flag for blocks (not block materials) is separate - that determines whether the block itself occludes block faces adjacent to it. E.g. a minecraft "tree leaves" block would need to be non-opaque, since you can see adjacent blocks through it, even though the texture doesn't have alpha.
Yes, I've set texHasAlpha to true. The code for setting up blocks looks like this: https://github.com/Patbox/voxelsrv/blob/master/src/registry.js#L27
createBlock(_id++, color + '_stained_glass', 0, ['block/' + color + '_stained_glass' ] , {opaque: false}, {drop: color + '_stained_glass', hardness: 1, tool: 'pickaxe', material: 'glass'})
Okay, it's a few years since I touched these bits of code but I think I see what's going on now.
Noa's texHasAlpha
flag maps to Babylon's hasAlpha
property on textures, which only enables the texture to have fully on/off pixels (like minecraft tree leaf textures). To get partial transparency one has to also define an opacityTexture
.
To see why the engine doesn't support this, you can try it out by doing it on a custom block texture:
var tmat = noa.rendering.makeStandardMaterial('')
tmat.diffuseTexture = new Texture('textures/window.png', scene)
tmat.opacityTexture = tmat.diffuseTexture
noa.registry.registerMaterial('window', null, null, false, tmat)
blockIDs.windowID = noa.registry.registerBlock(_id++, {
material: 'window',
opaque: false,
})
As you can see the composite order gets messed up, (I assume) because noa merges terrain into big per-chunk meshes, and then Babylon treats that whole chunk as a single thing with respect to drawing transparent textures in the right order.
So, long story short, I think the right way to do what you're looking for is to treat each block with partial transparency as a custom block and make your own mesh for it, with whatever settings you need (opacity, backfaceCulling, etc). And generally assume that all terrain (i.e. blocks that don't have custom meshes) textures cannot be partially transparent.
I should add that I'm basically a beginner at this stuff, so do let me know if you see a better approach.
By the way: your project looks really nice! Would you like it added to the list of projects at the top of noa's readme?
Okay so I will do it with custom blocks.
And thanks! Sure, you can add it.
The final result of using custom meshes. Here's code I use:
var mat = noa.rendering.makeStandardMaterial(name)
var tex = new BABYLON.Texture('textures/' + texture[0] + '.png', scene, true, true,
BABYLON.Texture.NEAREST_SAMPLINGMODE)
mat.diffuseTexture = tex
mat.opacityTexture = mat.diffuseTexture
mat.backFaceCulling = true
var mesh = BABYLON.MeshBuilder.CreateBox(name, {size: 1}, noa.rendering.getScene())
mesh.material = mat
mesh.bakeTransformIntoVertices( ( new BABYLON.Matrix.Scaling(1, 1, 1) ).setTranslation ( new BABYLON.Vector3(0, 0.5, 0) ) )
mesh.material.needDepthPrePass = true
var finOpts = options
finOpts.blockMesh = mesh
noa.registry.registerBlock(id, finOpts)
LGTM 👍
I'm afraid it will get pretty hairy if you want to do things like remove unneeded block faces between two such custom blocks, or between a stained glass block and adjacent solid blocks. But I don't think there's any good solution for that, besides managing it all manually.
PS: congratulations on having a web-based minecraft client that's better than Mojang's 😄
Guessing this is okay to close, reopen if you have questions.
Hello. I've tried to add blocks with textures with partial transparency and it looks like it doesn't render it properly. Blocks have 'opaque' set to false.