Adicionar uma camada WebGL personalizada a um mapa

O SDK da Web do Azure Maps dá suporte à criação de camadas personalizadas usando WebGL. WebGL é baseado em OpenGL ES e permite renderizar gráficos 2D e 3D em navegadores da web.

Usando WebGL, você pode criar gráficos interativos de alto desempenho que renderizam no navegador em tempo real que suportam cenários como simulações, visualização de dados, animações e modelagem 3D.

Os desenvolvedores podem acessar o contexto WebGL do mapa durante a renderização e usar camadas WebGL personalizadas para integrar com outras bibliotecas, como três.js e deck.gl para fornecer conteúdo enriquecido e interativo no mapa.

Adicionar uma camada WebGL

Antes de adicionar uma camada WebGL a um mapa, você precisa ter um objeto que implemente a WebGLRenderer interface. Primeiro, crie uma camada WebGL fornecendo um id e renderer objeto para o construtor e, em seguida, adicione a camada ao mapa para que ela seja renderizada.

O código de exemplo a seguir demonstra como adicionar uma camada WebGL a um mapa:

var myRenderer = {
    /**
     * Either "2d" or "3d". Defaults to "2d".
     * - "3d" to use the depth buffer and share it with other layers
     * - "2d" to add a layer with no depth. If you need to use the depth buffer for a "2d"
     *   layer you must use an offscreen framebuffer and the prerender method.
     */
    renderingMode: "2d",

    /**
     * Optional method called when the layer has been added to the Map.
     * This gives the layer a chance to initialize gl resources and register event listeners.
     * @param map The Map this custom layer was just added to.
     * @param gl The gl context for the map.
     */
    onAdd: function (map, gl) {},

    /**
     * Optional method called when the layer has been removed from the Map.
     * This gives the layer a chance to clean up gl resources and event listeners.
     * @param map The Map this custom layer was just added to.
     * @param gl The gl context for the map.
     */
    onRemove: function (map, gl) {},

    /**
     * Optional method called during a render frame to allow a layer to prepare resources
     * or render into a texture.
     *
     * The layer cannot make any assumptions about the current GL state and must bind a framebuffer before rendering.
     *
     * @param gl The map's gl context.
     * @param matrix The map's camera matrix.
     */
    prerender: function (gl, matrix) {},

    /**
     * Required. Called during a render frame allowing the layer to draw into the GL context.
     *
     * The layer can assume blending and depth state is set to allow the layer to
     * properly blend and clip other layers. The layer cannot make any other 
     * assumptions about the current GL state.
     *
     * If the layer needs to render to a texture, it should implement the prerender
     * method to do this and only use the render method for drawing directly into the
     * main framebuffer.
     *
     * The blend function is set to gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA).
     * This expects colors to be provided in premultiplied alpha form where the r, g and b
     * values are already multiplied by the a value. If you are unable to provide colors in
     * premultiplied form you may want to change the blend function to
     * gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA).
     *
     * @param gl The map's gl context.
     * @param matrix The map's camera matrix.
     */
    render: function (gl, matrix) {}
};
 
//Add the layer to the map.
map.layers.add(new atlas.layer.WebGLLayer("layerId", { renderer: myRenderer }));

Nota

A WebGLLayer classe suporta as minZoomopções , maxZoome visible camada.

//Add the layer to the map with layer options. 
map.layers.add(new atlas.layer.WebGLLayer("layerId", 
    { 
        renderer: myRenderer, 
        minZoom: 10, 
        maxZoom: 22, 
        visible: true
    }
));

Este exemplo renderiza um triângulo no mapa usando uma camada WebGL.

A screenshot showing a triangle rendered on a map, using a WebGL layer.

Para obter um exemplo totalmente funcional com código-fonte, consulte Camada WebGL 2D simples nos Exemplos do Azure Maps.

A matriz de câmera do mapa é usada para projetar o ponto esférico de Mercator para gl coordenadas. O ponto Mercator [0, 0] representa o canto superior esquerdo do mundo Mercator e [1, 1] representa o canto inferior direito. Quando renderingMode é , a coordenada z é "3d"conforme. Uma caixa com comprimentos x, y e z idênticos em unidades Mercator seria renderizada como um cubo.

A MercatorPoint classe tem fromPosition, fromPositionse toFloat32Array métodos estáticos que podem ser usados para converter uma posição geoespacial em um ponto de Mercator. Da mesma forma, os toPosition métodos e toPositions podem ser usados para projetar um ponto de Mercator para uma posição.

Renderizar um modelo 3D

Use uma camada WebGL para renderizar modelos 3D. O exemplo a seguir mostra como carregar um arquivo glTF e processá-lo no mapa usando três.js.

Você precisa adicionar os seguintes arquivos de script.

<script src="https://unpkg.com/three@latest/build/three.min.js"></script>
<script src="https://unpkg.com/three@latest/examples/js/loaders/GLTFLoader.js"></script>

Este exemplo renderiza um papagaio 3D animado no mapa.

A screenshot showing an animated 3D parrot on the map.

Para obter um exemplo totalmente funcional com código-fonte, consulte Três camadas WebGL personalizadas nos Exemplos do Azure Maps.

A onAdd função carrega um arquivo na memória e instancia três objetos .js, como Câmera, Cena, Luz e um .glb THREE.WebGLRendererarquivo .

A render função calcula a matriz de projeção da câmera e renderiza o modelo para a cena.

Gorjeta

  • Para ter uma animação contínua e suave, você pode acionar a repintura de um único quadro chamando map.triggerRepaint() a render função.
  • Para ativar a suavização de serrilhado, basta definir antialias como true uma das opções de estilo ao criar o mapa.

Renderize um modelo 3D usando babylon.js

Babylon.js é um dos principais motores gráficos baseados em WebGL do mundo. O exemplo a seguir mostra como carregar um arquivo GLTF e processá-lo no mapa usando babylon.js.

Você precisa adicionar os seguintes arquivos de script.

<script src="https://cdn.babylonjs.com/babylon.js"></script> 
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script> 

Este exemplo renderiza uma torre de satélite no mapa.

A onAdd função instancia um motor BABYLON e uma cena. Em seguida, ele carrega um .gltf arquivo usando BABYLON. SceneLoader.

A render função calcula a matriz de projeção da câmera e renderiza o modelo para a cena.

A screenshot showing an example of rendering a 3D model using babylon.js.

Para obter um exemplo totalmente funcional com código-fonte, consulte Camada WebGL personalizada do Babylon nos Exemplos do Azure Maps.

Renderizar uma camada de deck.gl

Uma camada WebGL pode ser usada para renderizar camadas da biblioteca deck.gl . O exemplo a seguir demonstra a visualização de dados do fluxo de migração de pessoas nos Estados Unidos de condado para condado dentro de um determinado intervalo de tempo.

Você precisa adicionar o seguinte arquivo de script.

<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script> 

Defina uma classe de camada que se estenda atlas.layer.WebGLLayer.

class DeckGLLayer extends atlas.layer.WebGLLayer { 

    constructor(options) { 
        super(options.id); 

        //Create an instance of deck.gl layer 
        this._mbLayer = new deck.MapboxLayer(options); 

        //Create a renderer 
        const deckGLRenderer = { 
            renderingMode: "3d", 
            onAdd: (map, gl) => { 
               this._mbLayer.onAdd?.(map["map"], gl); 
            }, 
            onRemove: (map, gl) => { 
                this._mbLayer.onRemove?.(map["map"], gl); 
            }, 
            prerender: (gl, matrix) => { 
                this._mbLayer.prerender?.(gl, matrix); 
            }, 
            render: (gl, matrix) => { 
                this._mbLayer.render(gl, matrix); 
            } 
        }; 
        this.setOptions({ renderer: deckGLRenderer }); 
    } 
} 

Este exemplo renderiza uma camada de arco google a biblioteca deck.gl .

A screenshot showing an arc-layer from the Deck G L library.

Para obter um exemplo totalmente funcional com código-fonte, consulte Camada WebGL personalizada do Deck GL nos Exemplos do Azure Maps.

Próximos passos

Saiba mais sobre as classes e métodos usados neste artigo: