We have the web service that provides a very large texture split in tiles, so the idea is that the terrain will be loading and rendering the tiles as it happens on Geojs library when rendering a tiled world map.
I did a lot of search on this but didn’t get with any valid solution,
I was checking out the Geojs library but it just has the tile generation for 2D maps.
As of right now, that would require some coding. But you could create an image texture locally via a canvas that you could keep updating with the tiles each time you are getting them. That should work just fine.
About this topic, after a lot of tests what I can tell you:
Using web canvas, you can get all the tiles, write them into canvas, then get the final image made by the canvas.
I’ve tried to do a partial rendering using this approach:
For each N tiles loaded from the server, write them into the canvas and then get the partial image made by canvas.
But that didn’t go well, it took a lot of time to render because the rendering image from canvas is a heavy operation, so in the end, it takes more time then just wait for all tiles.
I’ve tried to use web workers to be able to use the partial rendering, but then I got other issues
Canvas can’t be accessed by the web worker because it can’t manipulate DOM elements
I searched for solutions for this using third libraries but none seems to be a good fit.
I’ve changed the code to put as many operations on web workers to test the performance, but in the end, it didn’t change the performance too much.
I used OffscreenCanvas that allows using canvas with web workers, but only for Chrome and Firefox (user needs to change a setting for that)
I load the image using fetch instead of the Image DOM object
Even with the web worker solution, the partial rendering was not possible to achieve.
So basically if you want to do partial rendering, the only solution that comes in my mind is to implement it as customization on the VTK library.
An example of how to write the tiles into the canvas and then get the merged image:
var canvas = document.createElement('canvas');
var canvasContext = this.canvas.getContext("2d");
// set the canvas.width and canvas.height with the size of the image
//draw a tile passing the image
//x and y are the position of the file, for example (2, 1)
canvasContext.drawImage(img, x * tileWidth, y * tileHeight);
//call toBlob to let the canvas to render your final image
//with the blob obj you can create a object url and use this url to load it with a Image DOM element on HTML (loadImageFromUrl just do that)
canvas.toBlob(blob => ImageUtil.loadImageFromUrl(URL.createObjectURL(blob), true)
.then(img => this.oncomplete(img)));
ImageUtil code:
export default class ImageUtil {
static loadImageFromUrl(url, revokeUrl = false) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
if (revokeUrl) {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
}
resolve(img);
};
img.src = url;
});
}
}