UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

96 lines (91 loc) 3.49 kB
import * as THREE from 'three'; // shader for copying a 2D texture to a framebuffer const copyTextureShader = { vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` precision highp float; uniform sampler2D sourceTexture; varying vec2 vUv; void main() { gl_FragColor = texture2D(sourceTexture, vUv); } ` }; let material = null; let quad = null; const quadCam = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); /** * Initializes a THREE.WebGLArrayRenderTarget with immutable storage * and populates its layers. * Returns the populated render target so callers can own/dispose it. * * @param width - The width of each layer in the DataArrayTexture. * @param height - The height of each layer in the DataArrayTexture. * @param count - The total number of layers the DataArrayTexture should have. * @param tiles - An array of RasterTile objects, each containing textures. * @param max - The maximum allowed number of layers for the DataArrayTexture. * @param renderer - The renderer used to render the texture. * @returns The constructed render target, or null */ export function makeDataArrayRenderTarget(width, height, count, tiles, max, renderer) { if (count === 0) { return null; } // The render target's internal framebuffer will be used to attach layers. const renderTarget = new THREE.WebGLArrayRenderTarget(width, height, count, { depthBuffer: false // No depth buffer needed for simple 2D texture copy }); const arrayTexture = renderTarget.texture; // Set up the quad for rendering if (!quad) { const geometry = new THREE.PlaneGeometry(2, 2); material = new THREE.ShaderMaterial({ uniforms: { // This uniform will be updated with each source 2D texture sourceTexture: { value: null } }, vertexShader: copyTextureShader.vertexShader, fragmentShader: copyTextureShader.fragmentShader }); quad = new THREE.Mesh(geometry, material); } // loop through each tile and its textures // to render them into DataArrayTexture layers let currentLayerIndex = 0; const previousRenderTarget = renderer.getRenderTarget(); for (const tile of tiles) { for (let i = 0; i < tile.textures.length && currentLayerIndex < max; ++i, ++currentLayerIndex) { const texture = tile.textures[i]; if (!texture) { continue; } // Set the current source 2D texture on the quad's material material.uniforms.sourceTexture.value = texture; if (!currentLayerIndex) { // Set parameters from the first found texture arrayTexture.magFilter = texture.magFilter; arrayTexture.minFilter = texture.minFilter; arrayTexture.wrapS = texture.wrapS; arrayTexture.wrapT = texture.wrapT; arrayTexture.format = texture.format; arrayTexture.type = texture.type; arrayTexture.internalFormat = texture.internalFormat; arrayTexture.anisotropy = texture.anisotropy; arrayTexture.premultiplyAlpha = texture.premultiplyAlpha; } // render this source texture into the current layer renderer.setRenderTarget(renderTarget, currentLayerIndex); renderer.render(quad, quadCam); } } renderer.setRenderTarget(previousRenderTarget); return renderTarget; }