Search the Community
Showing results for tags 'tile-ground'.
-
Hi Almighty Babylon Community, I am new to Babylon (and JavaScript in general), and am working on rendering huge tiled maps. The tiled map consists of many square cells are each cell is a 2048 x 2048 pngs (served by HTTP from the server as static files). At each moment we only need to render ~ 12 cells covering an area centered at the main entity. As the main entity moves, it might need to render another set of cells, although the new set of cells shares most part with the old set. My current approach is to render the set of cells with a TiledGround. The TiledGround has MultiMaterial attached to it, and each material in the MultiMaterial has a texture with the corresponding png. Each time when the main entity moves to the point that we need to update the TiledGround, the original TiledGround is disposed and a new TiledGround is created. The problem is that, I can feel the lagging at the moment when the disposing/recreation happens. I am wondering: Since the new set of cells and the old set of cells share most of cells, is there a way to incrementally update the TiledGround so that the lagging can go away? I am setting `.isblocking = false` for all the textures hoping that this can help with the lagging (it is okay to display a black cell first and have texture filled in later when it is loaded). Is this the right way to achieve the goal? Would using multiple Grounds instead TiledGround help? I am worrying that this might not the direction to go. Thanks a lot. Below is the code I have for this task, where `syncState` is called every time when an update on the tile map happens. I would like to do this on the PG but I am not sure how I can have it interact with the cell images, sorry! Thanks a lot for your time and patience import * as BABYLON from "babylonjs"; import { onSnapshot } from "mobx-state-tree"; import STORE from "store"; /** Maintains the 3D entity in BABYLON for tile maps. **/ export default class TileMap { constructor(scene) { this.scene = scene; // Under the hood, the tile map is represented as a tiled ground, // with a multi material. this.tiledGround = null; this.multiMaterial = null; // Create the pure black material for tiles without an image. this.pureBlack = new BABYLON.StandardMaterial("PureBlack", this.scene); this.pureBlack.diffuseColor = new BABYLON.Color3.Black(); // Connects the global state so that this becomes a view of the // the tileMap state. onSnapshot(STORE.tileMap, state => { if (!state.pending) { this.syncState(STORE.tileMap); } }); } /** * Updates the geometric properties of the mesh to make it in sync with the * given state. */ syncState(state) { if (this.tiledGround) { this.tiledGround.dispose(); } // 1. Prepare the multi material for the updated tiled ground. this.multiMaterial = new BABYLON.MultiMaterial( "TileMapMaterial", this.scene); for (let v = 0; v < state.rows; ++v) { for (let u = 0; u < state.cols; ++u) { const i = (state.rows - v - 1) * state.cols + u; if (state.tile[i]) { const image = new BABYLON.StandardMaterial(state.tile[i], this.scene); image.emissiveTexture = new BABYLON.Texture(state.tile[i], this.scene); image.emissiveTexture.uscale = 1; // Invert the v (Y) axis because the tile map has inverted Y. image.emissiveTexture.vscale = -1; // Asnchronously load the image texture. image.emissiveTexture.isBlocking = false; this.multiMaterial.subMaterials.push(image); } else { this.multiMaterial.subMaterials.push(this.pureBlack); } } } // 2. Create the tiled ground. this.tiledGround = new BABYLON.Mesh.CreateTiledGround( "TileMap", state.origin.x, -(state.origin.y + state.height), state.origin.x + state.width, -state.origin.y, { h: state.rows, w: state.cols }, // Number of tiles along x and z (Y). { h: 2, w: 2 }, // Precisions for each tile. this.scene); // 3. Apply the multi material to the tiled ground. this.tiledGround.material = this.multiMaterial; const numTiles = state.rows * state.cols; const verticesCount = this.tiledGround.getTotalVertices(); const tileIndicesLength = this.tiledGround.getIndices().length / numTiles; // Distribute the multi material into sub meshes. this.tiledGround.subMeshes = []; for (let i = 0; i < numTiles; ++i) { this.tiledGround.subMeshes.push(new BABYLON.SubMesh( i, 0, verticesCount, tileIndicesLength * i, tileIndicesLength, this.tiledGround)); } } }
- 12 replies
-
- sub-mesh
- tile-ground
-
(and 1 more)
Tagged with: