ArcGIS 3D Layers
Use this skill for 3D-specific layer types in SceneView: scene layers, integrated meshes, point clouds, voxels, dimensions, and glTF model imports.
Import Patterns
ESM (npm)
import SceneLayer from "@arcgis/core/layers/SceneLayer.js";
import IntegratedMeshLayer from "@arcgis/core/layers/IntegratedMeshLayer.js";
import IntegratedMesh3DTilesLayer from "@arcgis/core/layers/IntegratedMesh3DTilesLayer.js";
import PointCloudLayer from "@arcgis/core/layers/PointCloudLayer.js";
import VoxelLayer from "@arcgis/core/layers/VoxelLayer.js";
import DimensionLayer from "@arcgis/core/layers/DimensionLayer.js";
import BuildingSceneLayer from "@arcgis/core/layers/BuildingSceneLayer.js";
CDN (dynamic import)
const SceneLayer = await $arcgis.import("@arcgis/core/layers/SceneLayer.js");
const PointCloudLayer = await $arcgis.import("@arcgis/core/layers/PointCloudLayer.js");
const VoxelLayer = await $arcgis.import("@arcgis/core/layers/VoxelLayer.js");
All 3D-specific layers (SceneLayer, IntegratedMeshLayer, PointCloudLayer, VoxelLayer) require SceneView — they do not work in MapView.
SceneLayer
SceneLayer displays 3D building models, objects, and mesh data from scene services.
Basic SceneLayer
const sceneLayer = new SceneLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
popupTemplate: {
title: "{NAME}",
content: "{*}"
}
});
map.add(sceneLayer);
SceneLayer with Renderer
const sceneLayer = new SceneLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
renderer: {
type: "simple",
symbol: {
type: "mesh-3d",
symbolLayers: [{
type: "fill",
material: { color: [244, 247, 134] },
edges: {
type: "solid",
color: [50, 50, 50, 0.5],
size: 1
}
}]
}
}
});
SceneLayer Edge Rendering
// Solid edges
const solidEdges = {
type: "solid",
color: [50, 50, 50, 0.5],
size: 1
};
// Sketch edges
const sketchEdges = {
type: "sketch",
color: [50, 50, 50, 0.8],
size: 1.5,
extensionLength: 2
};
sceneLayer.renderer = {
type: "simple",
symbol: {
type: "mesh-3d",
symbolLayers: [{
type: "fill",
material: { color: "white" },
edges: sketchEdges
}]
}
};
Querying SceneLayer
const layerView = await view.whenLayerView(sceneLayer);
// Client-side query
const query = layerView.createQuery();
query.geometry = view.extent;
query.where = "HEIGHT > 100";
const results = await layerView.queryFeatures(query);
// Server-side query
const serverQuery = sceneLayer.createQuery();
serverQuery.where = "CATEGORY = 'Commercial'";
serverQuery.outFields = ["*"];
const serverResults = await sceneLayer.queryFeatures(serverQuery);
Editable SceneLayer
// Apply edits to scene layer (if editing enabled)
await sceneLayer.applyEdits({
addFeatures: [newGraphic],
updateFeatures: [updatedGraphic],
deleteFeatures: [{ objectId: 123 }]
});
IntegratedMeshLayer
IntegratedMeshLayer displays photogrammetric mesh data (3D reality capture).
const meshLayer = new IntegratedMeshLayer({
url: "https://tiles.arcgis.com/tiles/.../IntegratedMeshServer"
});
map.add(meshLayer);
IntegratedMesh3DTilesLayer
For 3D Tiles 1.1 data sources:
const mesh3DTiles = new IntegratedMesh3DTilesLayer({
url: "https://example.com/tileset.json"
});
map.add(mesh3DTiles);
Mesh Modifications
// Clip or replace mesh areas
const modification = {
geometry: polygon,
type: "clip" // or "replace", "mask"
};
PointCloudLayer (LiDAR Data)
Basic PointCloudLayer
const pcLayer = new PointCloudLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer"
});
map.add(pcLayer);
PointCloud Renderers
// RGB (True Color) Renderer
pcLayer.renderer = {
type: "point-cloud-rgb",
field: "RGB"
};
// Classification Renderer
pcLayer.renderer = {
type: "point-cloud-unique-value",
field: "CLASS_CODE",
colorUniqueValueInfos: [
{ values: ["2"], label: "Ground", color: [139, 90, 43] },
{ values: ["6"], label: "Building", color: [194, 194, 194] },
{ values: ["5"], label: "High Vegetation", color: [34, 139, 34] }
]
};
// Elevation Stretch Renderer
pcLayer.renderer = {
type: "point-cloud-stretch",
field: "ELEVATION",
stops: [
{ value: 0, color: [0, 0, 255] },
{ value: 50, color: [255, 255, 0] },
{ value: 100, color: [255, 0, 0] }
]
};
PointCloud Density and Size
pcLayer.pointsPerInch = 40; // Density control
PointCloud Filters
// Include only specific classifications
pcLayer.filters = [{
field: "CLASS_CODE",
mode: "include",
values: [2, 6] // Ground and Building
}];
// Remove filters
pcLayer.filters = [];
Smart Mapping for PointCloud
import * as colorRendererCreator from "@arcgis/core/smartMapping/renderers/color.js";
import * as typeRendererCreator from "@arcgis/core/smartMapping/renderers/type.js";
// True color renderer
const rgbResponse = await colorRendererCreator.createPCTrueColorRenderer({
layer: pcLayer
});
pcLayer.renderer = rgbResponse.renderer;
// Classification renderer
const classResponse = await typeRendererCreator.createPCClassRenderer({
layer: pcLayer,
field: "CLASS_CODE"
});
pcLayer.renderer = classResponse.renderer;
VoxelLayer (Volumetric 3D Data)
VoxelLayer displays 3D volumetric data (atmospheric, oceanographic, geological).
Basic VoxelLayer
const voxelLayer = new VoxelLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
currentVariableId: 0
});
map.add(voxelLayer);
VoxelLayer with Map Component
<arcgis-scene viewing-mode="local">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-scene>
<script type="module">
import VoxelLayer from "@arcgis/core/layers/VoxelLayer.js";
import Map from "@arcgis/core/Map.js";
const vxlLayer = new VoxelLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer"
});
const viewElement = document.querySelector("arcgis-scene");
viewElement.map = new Map({
layers: [vxlLayer],
ground: { navigationConstraint: { type: "none" } }
});
</script>
VoxelLayer Configuration
const voxelLayer = new VoxelLayer({
url: "...",
currentVariableId: 0,
enableDynamicSections: true,
volumeDisplayQuality: "high" // "low", "medium", "high"
});
await voxelLayer.load();
console.log("Variables:", voxelLayer.variables);
console.log("Styles:", voxelLayer.styles);
Voxel Key Properties
| Property | Type | Description |
|----------|------|-------------|
| currentVariableId | number | Active variable to display |
| currentStyleId | number | Active style/rendering |
| enableDynamicSections | boolean | Allow interactive slicing |
| volumeDisplayQuality | string | "low", "medium", "high" |
| variables | VoxelVariable[] | Available data variables |
| styles | VoxelTransferFunctionStyle[] | Rendering styles |
Voxel Slicing (Dynamic Sections)
voxelLayer.enableDynamicSections = true;
// Configure slice plane
const slicePlane = {
point: { x: 0, y: 0, z: -500 },
normal: { x: 0, y: 0, z: 1 }
};
Voxel Isosurfaces
// Create isosurface at specific value
const isosurface = {
value: 25,
enabled: true,
color: [255, 0, 0, 0.7]
};
Voxel Color Stops
// Customize color stops for variable rendering
// Accessed through voxelLayer.styles
DimensionLayer (3D Measurements)
Basic DimensionLayer
import DimensionLayer from "@arcgis/core/layers/DimensionLayer.js";
import DimensionAnalysis from "@arcgis/core/analysis/DimensionAnalysis.js";
import LengthDimension from "@arcgis/core/analysis/LengthDimension.js";
const dimensionAnalysis = new DimensionAnalysis({
style: {
type: "simple",
textBackgroundColor: [0, 0, 0, 0.6],
textColor: "white",
fontSize: 12
}
});
const dimensionLayer = new DimensionLayer({
title: "Dimensions",
source: dimensionAnalysis
});
map.add(dimensionLayer);
Add Length Dimensions
const dimension = new LengthDimension({
startPoint: {
x: -122.4, y: 37.8, z: 0,
spatialReference: { wkid: 4326 }
},
endPoint: {
x: -122.5, y: 37.8, z: 0,
spatialReference: { wkid: 4326 }
},
orientation: 0,
offset: 10
});
dimensionLayer.source.dimensions.push(dimension);
Interactive Dimension Placement
const layerView = await view.whenLayerView(dimensionLayer);
const abortController = new AbortController();
async function startPlacement() {
try {
while (!abortController.signal.aborted) {
await layerView.place({ signal: abortController.signal });
}
} catch (error) {
if (!promiseUtils.isAbortError(error)) throw error;
}
}
startPlacement();
// Stop placement
abortController.abort();
BuildingSceneLayer
const buildingLayer = new BuildingSceneLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer"
});
await buildingLayer.load();
// Access sublayers (disciplines and categories)
buildingLayer.allSublayers.forEach(sublayer => {
console.log(sublayer.title, sublayer.type);
});
Importing 3D Models (glTF)
glTF Symbol
const graphic = new Graphic({
geometry: {
type: "point",
longitude: -122.4,
latitude: 37.8,
z: 0
},
symbol: {
type: "point-3d",
symbolLayers: [{
type: "object",
resource: {
href: "https://example.com/model.glb"
},
width: 10,
height: 10,
depth: 10,
heading: 45,
tilt: 0,
roll: 0
}]
}
});
graphicsLayer.add(graphic);
Interactive Model Placement
import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js";
const graphicsLayer = new GraphicsLayer({
elevationInfo: { mode: "on-the-ground" }
});
const sketchVM = new SketchViewModel({
layer: graphicsLayer,
view: view,
pointSymbol: {
type: "point-3d",
symbolLayers: [{
type: "object",
resource: { href: "https://example.com/model.glb" }
}]
}
});
sketchVM.create("point");
sketchVM.on("create", (event) => {
if (event.state === "complete") {
sketchVM.update(event.graphic);
}
});
Elevation Info
// Feature placement relative to ground/scene
layer.elevationInfo = {
mode: "on-the-ground" // Features draped on ground
// mode: "relative-to-ground" // Features offset from ground
// mode: "relative-to-scene" // Features offset from scene
// mode: "absolute-height" // Features at absolute Z values
};
// With offset
layer.elevationInfo = {
mode: "relative-to-ground",
offset: 100,
unit: "meters"
};
// With expression
layer.elevationInfo = {
mode: "relative-to-ground",
featureExpressionInfo: {
expression: "Geometry($feature).z * 10"
},
unit: "meters"
};
3D Analysis Components
| Component | Purpose |
|-----------|---------|
| arcgis-building-explorer | Explore building scene layers by discipline and floor |
| arcgis-elevation-profile | Generate elevation profiles along a path |
| arcgis-line-of-sight | Analyze line-of-sight visibility |
| arcgis-shadow-cast | Simulate shadow casting at different times |
| arcgis-slice | Slice through 3D content to reveal interior |
| arcgis-directional-pad | Navigate 3D scenes with directional controls |
Viewing Modes
// Global mode (default) - spherical Earth
view.viewingMode = "global";
// Local mode - flat, for local areas
view.viewingMode = "local";
<!-- Local mode for indoor/underground/voxel -->
<arcgis-scene viewing-mode="local">
</arcgis-scene>
Common Pitfalls
-
SceneView only: SceneLayer, IntegratedMeshLayer, PointCloudLayer, and VoxelLayer only work in SceneView, not MapView.
-
VoxelLayer requires local viewing mode: Use
viewing-mode="local"for best results with voxel data. -
PointCloud renderer fields: Common fields are
RGB,CLASS_CODE,ELEVATION,INTENSITY. -
glTF model scale: Models may need explicit
width/height/depthto fit the scene properly. -
Ground navigation constraint: Set
navigationConstraint: { type: "none" }to allow underground viewing. -
Load before accessing metadata: Always
await layer.load()before accessingvariables,styles,allSublayers, or similar properties.
Reference Samples
layers-scenelayer— Basic SceneLayerlayers-scenelayer-edges— Edge rendering styleslayers-pointcloud— PointCloudLayer with rendererslayers-pointcloud-filters— Filtering point cloud datalayers-voxel— VoxelLayer basicslayers-voxel-isosurface— Isosurface visualizationlayers-voxel-dynamic-sections— Voxel slicinglayers-integratedmeshlayer— IntegratedMeshLayerlayers-dimension— DimensionLayer measurementsimport-gltf— Importing glTF 3D models
Related Skills
arcgis-scene-environment— Lighting, weather, atmosphere, shadowsarcgis-custom-rendering— RenderNode for custom 3D WebGL renderingarcgis-visualization— Renderers and symbologyarcgis-layers— Common layer patterns and configuration