arcgis-3d-layers

SKILL.md

ArcGIS 3D Layers

Use this skill for 3D layer types including voxel layers, point clouds, glTF imports, and 3D analysis components.

VoxelLayer (Volumetric 3D Data)

VoxelLayer displays 3D volumetric data like atmospheric, oceanographic, or geological data.

Basic VoxelLayer

import VoxelLayer from "@arcgis/core/layers/VoxelLayer.js";

const voxelLayer = new VoxelLayer({
  url: "https://tiles.arcgis.com/tiles/.../SceneServer",
  visible: true,
  popupEnabled: true
});

map.add(voxelLayer);

VoxelLayer with Map Component

<arcgis-scene viewing-mode="local">
  <arcgis-zoom slot="top-left"></arcgis-zoom>
  <arcgis-legend slot="bottom-right"></arcgis-legend>
</arcgis-scene>

<script type="module">
  import VoxelLayer from "@arcgis/core/layers/VoxelLayer.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: "...",
  // Variable to display
  currentVariableId: 0,
  // Slicing
  enableDynamicSections: true,
  // Rendering mode
  renderMode: "volume" // or "surfaces"
});

// Access voxel-specific properties after load
await voxelLayer.load();
console.log("Variables:", voxelLayer.variables);
console.log("Volumes:", voxelLayer.volumes);

Voxel Slicing

// Add dynamic section (slice)
voxelLayer.enableDynamicSections = true;

// Configure slice plane
const slicePlane = {
  point: { x: 0, y: 0, z: -500 },
  normal: { x: 0, y: 0, z: 1 }
};

Voxel Isosurface

// Create isosurface at specific value
const isosurface = {
  value: 25,
  enabled: true,
  color: [255, 0, 0, 0.7]
};

PointCloudLayer (LiDAR Data)

Basic PointCloudLayer

import PointCloudLayer from "@arcgis/core/layers/PointCloudLayer.js";

const pcLayer = new PointCloudLayer({
  url: "https://tiles.arcgis.com/tiles/.../SceneServer"
});

map.add(pcLayer);

PointCloud Renderers

// RGB (True Color) Renderer
const rgbRenderer = {
  type: "point-cloud-rgb",
  field: "RGB"
};

// Class (Classification) Renderer
const classRenderer = {
  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 Renderer (Stretch)
const elevationRenderer = {
  type: "point-cloud-stretch",
  field: "ELEVATION",
  fieldTransformType: "none",
  colorModulation: null,
  stops: [
    { value: 0, color: [0, 0, 255] },
    { value: 50, color: [255, 255, 0] },
    { value: 100, color: [255, 0, 0] }
  ]
};

pcLayer.renderer = rgbRenderer;

Smart Mapping for PointCloud

import colorRendererCreator from "@arcgis/core/smartMapping/renderers/color.js";
import 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"
});

// Continuous color renderer
const elevResponse = await colorRendererCreator.createPCContinuousRenderer({
  layer: pcLayer,
  field: "ELEVATION"
});

PointCloud Filters

pcLayer.filters = [{
  field: "CLASS_CODE",
  mode: "include",
  values: [2, 6] // Ground and Building only
}];

// Remove filters
pcLayer.filters = [];

For scene environment settings (atmosphere, lighting, weather, shadows), see arcgis-scene-environment.

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"
      },
      // Optional: scale and rotate
      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"
      }
    }]
  }
});

// Start placing model
sketchVM.create("point");

sketchVM.on("create", (event) => {
  if (event.state === "complete") {
    // Model placed, allow editing
    sketchVM.update(event.graphic);
  }
});

IntegratedMeshLayer

import IntegratedMeshLayer from "@arcgis/core/layers/IntegratedMeshLayer.js";

const meshLayer = new IntegratedMeshLayer({
  url: "https://tiles.arcgis.com/tiles/.../IntegratedMeshServer"
});

map.add(meshLayer);

DimensionLayer (Length Dimensioning)

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";

// Create dimension analysis with style
const dimensionAnalysis = new DimensionAnalysis({
  style: {
    type: "simple",
    textBackgroundColor: [0, 0, 0, 0.6],
    textColor: "white",
    fontSize: 12
  }
});

// Create dimension layer
const dimensionLayer = new DimensionLayer({
  title: "Dimensions",
  source: dimensionAnalysis
});

map.add(dimensionLayer);

Add Length Dimensions

// Add a dimension between two points
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,  // Rotation in degrees
  offset: 10       // Distance from line
});

dimensionLayer.source.dimensions.push(dimension);

Interactive Dimension Placement

const layerView = await view.whenLayerView(dimensionLayer);

// Start interactive placement
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();

OpenStreetMapLayer (3D Buildings)

import OpenStreetMapLayer from "@arcgis/core/layers/OpenStreetMapLayer.js";

// OSM tiles in 3D SceneView
const osmLayer = new OpenStreetMapLayer();

const map = new Map({
  ground: "world-elevation",
  layers: [osmLayer]
});

const view = new SceneView({
  map: map,
  container: "viewDiv"
});

Scene Environment

Ground Configuration

// World elevation
map.ground = "world-elevation";

// Custom elevation layer
import ElevationLayer from "@arcgis/core/layers/ElevationLayer.js";

map.ground = {
  layers: [
    new ElevationLayer({
      url: "https://elevation.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
    })
  ]
};

// Underground navigation
map.ground.navigationConstraint = { type: "none" }; // Allow underground
map.ground.opacity = 0.5; // Semi-transparent ground

Scene Quality

view.qualityProfile = "high"; // "low", "medium", "high"

// Custom quality settings
view.environment.atmosphereEnabled = true;
view.environment.starsEnabled = true;
view.environment.lighting.ambientOcclusionEnabled = true;

Background

// Solid color background
view.environment.background = {
  type: "color",
  color: [0, 0, 0, 1]
};

// Transparent background (for screenshots)
view.environment.background = {
  type: "color",
  color: [0, 0, 0, 0]
};

Scene Performance

Performance Monitoring

import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";

// Monitor performance
reactiveUtils.watch(
  () => view.performanceInfo,
  (info) => {
    console.log("Quality:", info.quality);
  }
);

// Reduce quality for performance
view.qualityProfile = "low";

Viewing Modes

// Global mode (default) - spherical Earth
view.viewingMode = "global";

// Local mode - flat, for local areas
view.viewingMode = "local";
<!-- Local mode for indoor/underground -->
<arcgis-scene viewing-mode="local">
</arcgis-scene>

TypeScript Usage

3D symbols and configurations use autocasting with type properties. For TypeScript safety, use as const:

// Use 'as const' for type safety
const graphic = new Graphic({
  geometry: point,
  symbol: {
    type: "point-3d",
    symbolLayers: [{
      type: "object",
      resource: { href: "https://example.com/model.glb" },
      width: 10,
      height: 10
    }]
  } as const
});

// Weather configuration
view.environment.weather = {
  type: "rainy",
  cloudCover: 0.8,
  precipitation: 0.5
} as const;

Tip: See arcgis-core-maps skill for detailed guidance on autocasting vs explicit classes.

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

Reference Samples

  • layers-voxel - Working with VoxelLayer in 3D
  • weather - Weather effects in SceneView
  • daylight - Daylight widget for sun position
  • import-gltf - Importing glTF 3D models
  • layers-dimension - DimensionLayer for 3D measurements

Common Pitfalls

  1. VoxelLayer requires local viewing mode: Use viewing-mode="local" for best results

  2. PointCloud renderer fields: Common fields are RGB, CLASS_CODE, ELEVATION, INTENSITY

  3. Weather only in SceneView: Weather effects don't work in MapView

  4. glTF model scale: Models may need scaling to fit the scene properly

  5. Ground navigation constraint: Set navigationConstraint: { type: "none" } to allow underground viewing

Weekly Installs
3
GitHub Stars
5
First Seen
Feb 28, 2026
Installed on
opencode3
gemini-cli3
codebuddy3
github-copilot3
codex3
kimi-cli3