| name | arcgis-scene-effects |
| description | Configure SceneView environment settings including shadows, lighting, backgrounds, underground navigation, and elevation modes. Use for realistic 3D visualizations. |
ArcGIS Scene Effects
Use this skill for configuring SceneView environment, shadows, backgrounds, underground navigation, and elevation settings.
Environment Settings
Basic Environment Configuration
const view = new SceneView({
container: "viewDiv",
map: scene,
environment: {
lighting: {
directShadowsEnabled: true,
date: new Date("Sun Mar 15 2019 16:00:00 GMT+0100")
},
atmosphereEnabled: true,
starsEnabled: true
}
});
Map Component Environment
<arcgis-scene item-id="YOUR_WEBSCENE_ID">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-scene>
<script type="module">
const viewElement = document.querySelector("arcgis-scene");
await viewElement.viewOnReady();
viewElement.environment = {
lighting: {
directShadowsEnabled: true,
date: new Date()
},
atmosphereEnabled: true,
starsEnabled: true
};
</script>
Shadows and Lighting
Enable Direct Shadows
view.environment = {
lighting: {
directShadowsEnabled: true,
date: new Date("Sun Mar 15 2019 16:00:00 GMT+0100")
}
};
// Update time of day dynamically
function updateTimeOfDay(dateString) {
view.environment.lighting.date = new Date(dateString);
}
Toggle Shadows on Symbols
// Clone renderer and toggle castShadows
const clone = layer.renderer.clone();
clone.symbol.symbolLayers.getItemAt(0).castShadows = true;
layer.renderer = clone;
Highlight Shadow Color
import HighlightOptions from "@arcgis/core/views/support/HighlightOptions.js";
const highlightOptions = new HighlightOptions({
name: "default",
color: "cyan",
shadowColor: "cyan"
});
view.highlights = [highlightOptions];
// Change shadow color dynamically
highlightOptions.shadowColor = "#ff0000";
Virtual Lighting
view.environment = {
lighting: {
type: "virtual" // Consistent lighting without sun position
}
};
Transparent Background
Configure Transparent Background
const view = new SceneView({
container: "viewDiv",
map: scene,
alphaCompositingEnabled: true, // Required for transparency
environment: {
background: {
type: "color",
color: [255, 252, 244, 0] // RGBA with 0 alpha = transparent
},
starsEnabled: false,
atmosphereEnabled: false
}
});
Toggle Background Transparency
// Make background transparent
const backgroundColor = view.environment.background.color.clone();
backgroundColor.a = 0; // 0 = transparent, 1 = opaque
view.environment.background.color = backgroundColor;
Underground Navigation
Enable Underground Navigation (Map Component)
<arcgis-scene item-id="YOUR_WEBSCENE_ID">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-scene>
<script type="module">
const viewElement = document.querySelector("arcgis-scene");
await viewElement.viewOnReady();
// Allow navigation below ground
viewElement.map.ground.navigationConstraint = {
type: "none"
};
// Set ground opacity to see through
viewElement.map.ground.opacity = 0.4;
// Optional: set surface color when no basemap
viewElement.map.ground.surfaceColor = "#fff";
</script>
Underground Navigation (Core API)
const view = new SceneView({
container: "viewDiv",
map: scene
});
view.when(() => {
// Allow camera below ground
view.map.ground.navigationConstraint = {
type: "none"
};
// Make ground semi-transparent
view.map.ground.opacity = 0.4;
});
// Navigate to underground viewpoint
view.goTo({
position: {
x: -122.4,
y: 37.8,
z: -500, // Negative z = underground
spatialReference: { wkid: 4326 }
},
tilt: 80
});
Local Scene Mode
Create Local Scene
<arcgis-scene basemap="topo-vector" viewing-mode="local">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-scene>
Local Scene with Clipping Area
const viewElement = document.querySelector("arcgis-scene");
await viewElement.viewOnReady();
// Define clipping extent
const clippingExtent = {
xmax: -10834217,
xmin: -10932882,
ymax: 4493918,
ymin: 4432667,
spatialReference: { wkid: 3857 }
};
// Set clipping area
viewElement.clippingArea = clippingExtent;
viewElement.extent = clippingExtent;
// Disable atmosphere for local scenes
viewElement.environment = {
atmosphereEnabled: false,
starsEnabled: false
};
Elevation Info
Elevation Modes
// 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
};
Elevation with Offset
layer.elevationInfo = {
mode: "relative-to-ground",
offset: 100, // Meters above ground
unit: "meters"
};
Elevation with Expression
layer.elevationInfo = {
mode: "relative-to-ground",
featureExpressionInfo: {
expression: "Geometry($feature).z * 10" // Exaggerate Z values
},
unit: "meters"
};
Dynamic Elevation Configuration
function updateElevationInfo(mode, offset, expression, unit) {
layer.elevationInfo = {
mode: mode,
offset: Number(offset),
featureExpressionInfo: {
expression: expression || "0"
},
unit: unit
};
}
Screenshot Capture
Take Screenshot
const viewElement = document.querySelector("arcgis-scene");
// Take full view screenshot
const screenshot = await viewElement.takeScreenshot({
format: "png"
});
// Display screenshot
const img = document.createElement("img");
img.src = screenshot.dataUrl;
document.body.appendChild(img);
Screenshot of Specific Area
const screenshot = await viewElement.takeScreenshot({
area: {
x: 100,
y: 100,
width: 500,
height: 400
},
format: "png"
});
Screenshot with Drag Selection
viewElement.addEventListener("arcgisViewDrag", (event) => {
event.detail.stopPropagation(); // Prevent navigation
if (event.detail.action === "end") {
const area = {
x: Math.min(event.detail.origin.x, event.detail.x),
y: Math.min(event.detail.origin.y, event.detail.y),
width: Math.abs(event.detail.x - event.detail.origin.x),
height: Math.abs(event.detail.y - event.detail.origin.y)
};
viewElement.takeScreenshot({ area, format: "png" })
.then(screenshot => {
// Use screenshot.dataUrl or screenshot.data
});
}
});
Download Screenshot
function downloadImage(filename, dataUrl) {
const element = document.createElement("a");
element.href = dataUrl;
element.download = filename;
element.click();
}
const screenshot = await view.takeScreenshot({ format: "png" });
downloadImage("scene-screenshot.png", screenshot.dataUrl);
Atmosphere and Stars
Configure Atmosphere
view.environment = {
atmosphereEnabled: true, // Show atmosphere haze
starsEnabled: true, // Show stars at night
lighting: {
date: new Date() // Current sun position
}
};
Disable for Clean Visualization
view.environment = {
atmosphereEnabled: false,
starsEnabled: false
};
View Constraints
Altitude Constraints
const view = new SceneView({
container: "viewDiv",
map: scene,
constraints: {
altitude: {
min: 20000000, // Minimum camera altitude
max: 25000000 // Maximum camera altitude
}
}
});
Focus Area
Create Focus Area
import FocusArea from "@arcgis/core/effects/FocusArea.js";
import Polygon from "@arcgis/core/geometry/Polygon.js";
import Collection from "@arcgis/core/core/Collection.js";
// Define focus area geometry
const focusGeometry = new Polygon({
spatialReference: { wkid: 102100 },
rings: [[
[1288603, 6130075],
[1288506, 6129722],
[1288260, 6129821],
[1288603, 6130075]
]]
});
// Create focus area effect
const focusArea = new FocusArea({
title: "Area of Interest",
id: "focus-1",
outline: { color: [255, 128, 128, 0.55] },
geometries: new Collection([focusGeometry])
});
// Add to view
viewElement.focusAreas.areas.add(focusArea);
viewElement.focusAreas.style = "bright"; // or "dark"
Focus Area Styles
// Bright style - highlights focus area
viewElement.focusAreas.style = "bright";
// Dark style - darkens surrounding area
viewElement.focusAreas.style = "dark";
Toggle Focus Area
// Disable focus area
focusArea.enabled = false;
// Enable focus area
focusArea.enabled = true;
Update Focus Area Geometry
import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js";
const sketchVM = new SketchViewModel({
view: view,
layer: graphicsLayer
});
sketchVM.on("update", (event) => {
// Update focus area with new geometry
focusArea.geometries = new Collection([event.graphics[0].geometry]);
});
Complete Example
<!DOCTYPE html>
<html>
<head>
<script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/calcite.esm.js"></script>
<script src="https://js.arcgis.com/4.34/"></script>
<script type="module" src="https://js.arcgis.com/4.34/map-components/"></script>
<style>
html, body { height: 100%; margin: 0; }
</style>
</head>
<body>
<arcgis-scene item-id="YOUR_WEBSCENE_ID">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-scene>
<script type="module">
const viewElement = document.querySelector("arcgis-scene");
await viewElement.viewOnReady();
// Configure environment
viewElement.environment = {
lighting: {
directShadowsEnabled: true,
date: new Date()
},
atmosphereEnabled: true,
starsEnabled: true
};
// Enable underground navigation
viewElement.map.ground.navigationConstraint = { type: "none" };
viewElement.map.ground.opacity = 0.6;
// Configure layer elevation
const layer = viewElement.map.layers.getItemAt(0);
layer.elevationInfo = {
mode: "relative-to-ground",
offset: 50,
unit: "meters"
};
</script>
</body>
</html>
TypeScript Usage
Scene environment configurations use autocasting. For TypeScript safety, use as const:
// Use 'as const' for environment settings
view.environment = {
lighting: {
date: new Date("2024-06-21T12:00:00"),
directShadowsEnabled: true
},
weather: {
type: "sunny",
cloudCover: 0.3
} as const,
background: {
type: "color",
color: [0, 0, 0, 1]
} as const
};
Tip: See arcgis-core-maps skill for detailed guidance on autocasting vs explicit classes.
Common Pitfalls
Alpha compositing: Must set
alphaCompositingEnabled: truefor transparent backgroundsLocal scenes: Require clipping area and typically disable atmosphere/stars
Underground navigation: Must set
ground.navigationConstraint.type = "none"Shadow performance:
directShadowsEnabledcan impact performanceElevation modes: "on-the-ground" ignores offset and expression settings
Screenshot CORS: External layers may block screenshot capture