Hello,
In order to understanding how is working a LoD Image viewer (like openseaDragon for exemple)I’m trying to reproduce this kind of mecanism but more three.js oriented.
So basicaly, i’d like to render texture in webgl instead of canvas (even if i use canvas mecanism to read and crop image).
My LodImage is composed of an array of LevelInfo (depending of zoom level) wich contains an array of lstTile (wich are image’crops ).
class LodImage {
constructor(scene, nodeParent, nameNode) {
//Image properties
this._url = '';
this._width = 0;
this._height = 0;
this._tileSize = 0;
this._lstLevelInfo = [];
//three.js properties
this._scene = scene;
this._graphSceneNodeParent = nodeParent;
this._nodeSceneName = nameNode;
this._graphSceneNode = null;
}
async buildPyramid(imageUrl, tileSize, nameNode) {
//compute all resize global images for each level
await buildPyramidModel(this, imageUrl, tileSize);
createGeometryLevelsTile(this);
}
}
class LevelsInfos {
constructor(levelIndex, width, height, RowTiles, ColumnTiles) {
this._levelIndex = levelIndex;
this._width = width;
this._height = height;
this._rowTiles = RowTiles;
this._columnTiles = ColumnTiles;
this._context2D = null;
this._lstTile = [];
//three.js properties
this._graphSceneNodeParent = null;
this._nodeSceneName = '';
this._graphSceneNode = null;
this._geometry = null;
this._material = [];
this._mesh = null;
}
}
My first question is:
Is it better to use 1 THREE.PlaneGeometry by level with tile/face inside or multiple THREE.PlaneGeometry by level with THREE.PlaneGeometry/tile?
The questionbehind this one is, Do three.js render all faces of THREE.PlaneGeometry or just visible face in the viewport?
Solution 1: using 1 THREE.PlaneGeometry by level with tile/face
async function TestcreateGeometryLevelsTile(LODImage) {
//get informations array (compute previously in getInfoFromURL function called in buildPyramid method)
var lstlevels = LODImage._lstLevelInfo;
var tilesize = LODImage._tileSize;
var posx = 0, posy = 0, posz = 0;
//main node
LODImage._graphSceneNode = new THREE.Object3D();
LODImage._graphSceneNode.name = LODImage._nodeSceneName;
LODImage._graphSceneNodeParent.add(LODImage._graphSceneNode);
LODImage._graphSceneNode.position.set(posx, posy, posz);
//for each level
var col = 0;
for (var i = 0; i < lstlevels.length-1; ++i) {
var currentlevel = lstlevels[i];
//get the size previously computed
var currentWidth = currentlevel._width;
var currentHeight = currentlevel._height;
var currentRowSize = currentlevel._rowTiles;
var currentColumnSize = currentlevel._columnTiles;
// create a plane geometry for the image with a width of 10
// and a height that preserves the image's aspect ratio
currentlevel.setGeometry(new THREE.PlaneGeometry(currentWidth, currentHeight, currentRowSize, currentColumnSize));
//create a array of materials from the lstTile context
var lstTile = currentlevel._lstTile;
var lenght = currentlevel.getGeometry().faces.length / 2;
var indexTile = 0;
var col2 = 0;
for (var y = 0; y < lenght; ++y) {
var j = 2 * y;
var currentTile = lstTile[indexTile];
buildTexturedPlaneGeometry(currentlevel, i, currentTile, j, y);
indexTile++;
col2 += 20;
}
// Combine the geometry and material into a mesh
var nameMaterial = "material_" + i + "_" + lenght + "_faces";
var multiMaterial = new THREE.MeshFaceMaterial(currentlevel.getMaterialArray());
multiMaterial.name = nameMaterial;
currentlevel.setMesh(new THREE.Mesh( currentlevel.getGeometry(), multiMaterial));
buildNode(LODImage._graphSceneNode,
currentlevel._graphSceneNode,
LODImage._nodeSceneName, i,
currentlevel.getMesh(), posx, posy, posz);
posx += 50;
col += 40;
}
}
function buildTexturedPlaneGeometry(currentlevel, indexLevel, currentTile, indexvertex, indexTile) {
var texture = new THREE.Texture(currentTile._context2D.canvas);
var material = new THREE.MeshBasicMaterial({ map: texture });
currentlevel.addMaterial(material);
currentlevel.getGeometry().faces[indexvertex].materialIndex = indexTile;
currentlevel.getGeometry().faces[indexvertex + 1].materialIndex = indexTile;
}
ps: by the way, i still have a warning in this solution with THREE.MeshFaceMaterial, i read that this object is replace by THREE.MeshMultiMaterial but when i’m try it my quad is black!
ps2: with this solution i have only one level rendered…the second on is black… any idea?
Thx