aframe-tangram-terrain-component
v4.0.0
Published
A Tangram terrain component for A-Frame.
Downloads
35
Maintainers
Readme
aframe-tangram-terrain-component
A Tangram terrain component for A-Frame with batteries included.
Supports A-Frame 1.0.
API
tangram-terrain
component
This component obtains a terrain normalmap from the Amazon public dataset S3 servers and applies a overlay texture according the Tangram style specification. The normlmap can be used both as a displacement map for the geometry and also a a normal map for the material. By using the GPU picking technique for the normal map, the height calculation or hit testing is done on the shader. In addition the component also offers Level-of-Detail (LOD) of the geometry by using fast buffer geometry draw ranges on the vertex shader.
All properties are updateable!
Schema
| Property | Description | Default Value | | -------- | ----------- | ------------- | | apiKey | Sets the global API key of the overlay map. May be empty if the style needs no API. | "" | | style | The style definition document for the ovleray style. Must point to a custom style or to a basemap style. May need an API key set. | "" | | center | Center of the map, in the form of [longitude, latitude] | [0, 0] | | zoom | The zoom level of the map. | 13 | | heightmapFactor | Multiplication factor of the geometry's segmentsWidth and segmentsHeight for the heightmap. Higher factor will fetch more detailed heightmaps however will also increase bandwith and texture memory | 2 | | pxToWorldRatio | The multiplication factor between meters in A-Frame and the pixels of the map. ie; when set to 100, will display 100 pixels per 1 meter in world space. (see a note on fidelity) | 100 | | lodCount | Number of level of details for geometry. Set to 1 of no LOD is needed. | 1 | | lod | Level-Of-Detail in the range between 1 and lodCount. May be set during runtime. | 1 | | vertexNormals | Decides if a normalmap shall be applied to the material. Needed for lighting. Due to normal terrain tiles no additional data needs to transfered. | true |
Events
| Name | Data | Description | | -------- | ----------- | ------------- | | tangram-terrain-loaded | None| Fired when the terrain that means the elevation data and the overlay map has finished loading or the corresponding Level-Of-Detail has been loaded. Only by then the public API will be usable. For reasons I can't handle the Tangram library does unfortunately not report when an updated center has been fully loaded. Just on the first initial load. |
API
| Name | Data | Description |
| -------- | ----------- | ------------- |
| project | lon, lat| Returns the pixel x and y and z (depth) coordinates of the given longitude and latitude. |
| unproject | x, y| Gives the longitude and latitude of the world coordinates at the given pixel points. |
| unprojectHeight | x, y| Gives the depth value (GPU picked from the heightmap) from the pixel coordinates. Value is scaled according to the displacementScale
scale and added the displacementBias
value. |
| unprojectHeightInMeters | x, y| Gives the height value in meters. No physical exact values are possible though. Range between 0 and 8900 (Mount Everest) or -7000 and 8900 meters when includeOceans
is set to true |
| renderDepthBuffer | | Renders the heightmap depth buffer. Needs to be only called manually if the heigtmap is panned programmtically |
Notes
You can also download the map data to your machine and use the component below to display and work with the terrain. This comes in handy if you want to provide the assets rathern than pulling it from a tile server directly.
To download the normalmap from the current terrain press <ctrl> + <alt> + t
on the keyboard. To download the styled map press <ctrl> + <alt> + <shift> + t
on the keyboard. The bounds of the terrain area will be printed to the console which is need for the static terrain as an argument. See the following component for using those assets.
tangram-static-terrain
component
This component does not pull data from a tile server but uses image assets, that may be produced manually by downloading them from the tangram-terrain component.
Those two maps must be provided as assets to the map and normalmap attributes and the original pxtoWroldRatio value as well as the bounds string from the console.log
in order to be able to project data on the static terrain.
The geometry's width and height and segments detail settings and materials detail may of course differ from the reference terrain.
All properties are updateable!
Schema
| Property | Description | Default Value |
| -------- | ----------- | ------------- |
| map | Reference to the visible texture. | "" |
| normalmap | Reference to the normalmap texture. | "" |
| bounds | String of four elements obtained from the console log after taking the normalmap screenshot. | "0, 0, 0, 0" |
| lodCount | See tangram-terrain
component | 1 |
| lod | See tangram-terrain
component | 1 |
| vertexNormals | See tangram-terrain
component | true |
API
| Name | Data | Description |
| -------- | ----------- | ------------- |
| project | lon, lat| Returns the pixel x and y and z (depth) coordinates of the given longitude and latitude. Return null
if the given coordinates are outside the bounds. |
| unproject | x, y| Gives the longitude and latitude of the world coordinates at the given pixel points. Returns null
if the given coordinates are outside the bounds. |
| unprojectHeight | x, y| Gives the depth value (GPU picked from the heightmap) from the pixel coordinates. Value is scaled according to the displacementScale
scale and added the displacementBias
value. |
| unprojectHeightInMeters | x, y| Gives the height value in meters. No physical exact values are possible though. Range between 0 and 8900 (Mount Everest) or -7000 and 8900 meters when includeOceans
is set to true |
Styling
The Tangram map is styled within a (set) of YAML files. See the Tangram documentation for details.
A note on fidelity
The higher pxToWorldRatio
, the more map area will be displayed per world
unit. That canvas has to be translated into a plane in world space. This is
combined with the width and height in world space (from geometry.width and
geometry.height on the entity) to set up the plane for rendering in 3D.
The map is rendered as a texture on a 3D plane. However in WebGL textures must be a power of two. Therefore internally the pxToWorldRatio is floored to be a power of two.
Dependencies
The Mapzen styling documents are in the YAML format, so you need a possiblity to require those files.
If you are using Webpack install
npm install yml-loader --save-dev
and configure the webpack configuration file
If you are using browserify install the
nmp install yamlify --save-dev
and give pass the transform (-t) parameter to browserify.
Installation
Browser
Install and use by directly including the browser files:
<head>
<title>My A-Frame Scene</title>
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-tangram-terrain-component/dist/aframe-tangram-terrain-component.min.js"></script>
</head>
<body>
<a-scene>
<a-assets>
<a-asset-item id="yamlElevation" src="https://raw.githubusercontent.com/tangrams/terrain-demos/master/styles/terrarium-elevation.yaml" />
</a-assets>
<a-tangram-terrain
map-style="#yamlElevation"
zoom="10"
center="15.8056, 7.7671"
px-world-ratio="12"
wireframe="false"
height-scale="40"
width="25" depth="25">
</a-tangram-terrain>
</a-scene>
</body>
npm
Install via npm:
npm install aframe-tangram-terrain-component
Then require and use.
require('aframe');
require('aframe-tangram-terrain-component');
Required step for Webpack
To get the import working you need to tell Webpack not to parse the Tangram library otherwise you will run into this error. So you need to add this in your webpack.config.js.
module: {
noParse: [/tangram\/dist\/tangram/],
}
See also here for more information.
Known issues
- The maximum texture size (configured by the pxToWorldRatio and size parameters of the overlay map is restricted on mobile devies.
- The Tangram library only allows [one instance on a page] (https://github.com/tangrams/tangram/issues/350) that means a tiling algorithm cannot instance terrain entities in parallel! Hopefully this restriction of the Tangram library may fall in the future.
Implementation details
To save bandwith and increase speed the elevation data is backed into the normal map of the tiling webservice, which is all done in a shader by the Tangram library. Three.JS does not support normals with displacement alpha channels so I use the
onBeforeCompile
hook on theMeshStandardMaterial
to handle this texture format.The commond functions are all within the
tangram-terrain
system.This is done by rendering a depth buffer to an external THREE.JS scene, so that the height from the normal map alpha channel is read by the GPU.