Show realistic lighting and shadows for a given time of day.
Use case
You can use realistic lighting to evaluate the shadow impact of buildings and utility infrastructure on the surrounding community. This could be useful for civil engineers and urban planners, or for events management assessing the impact of building shadows during an outdoor event.
How to use the sample
Select one of the three lighting options to show that lighting effect on the SceneView
. Select a time of day from the slider (based on a 24hr clock), and a date from the date picker, to show the lighting for that time of day in the SceneView
.
How it works
- Create a
Scene
and display it in a composableSceneView
. - Create a
ZonedDateTime
to define the day and time of day. - Set the sun time to the scene view using zoned date time and a time offset in milliseconds.
- Set the sun lighting of the scene view to a
LightingMode
ofNoLight
,Light
, orLightAndShadows
.
Relevant API
- Scene
- SceneView
- SceneView.SunLighting
Additional information
This sample uses the GeoView-Compose Toolkit module to be able to implement a composable SceneView.
Tags
3D, lighting, realism, realistic, rendering, sceneview-compose, shadows, sun, time, toolkit
Sample Code
/* Copyright 2025 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.esri.arcgismaps.sample.showrealisticlightandshadows.components
import android.app.Application
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.lifecycle.AndroidViewModel
import com.arcgismaps.geometry.Point
import com.arcgismaps.geometry.SpatialReference
import com.arcgismaps.mapping.ArcGISScene
import com.arcgismaps.mapping.ArcGISTiledElevationSource
import com.arcgismaps.mapping.BasemapStyle
import com.arcgismaps.mapping.Surface
import com.arcgismaps.mapping.Viewpoint
import com.arcgismaps.mapping.layers.ArcGISSceneLayer
import com.arcgismaps.mapping.view.AtmosphereEffect
import com.arcgismaps.mapping.view.Camera
import com.arcgismaps.mapping.view.LightingMode
import com.arcgismaps.mapping.view.SpaceEffect
import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel
class ShowRealisticLightAndShadowsViewModel(application: Application) : AndroidViewModel(application) {
val arcGISScene = ArcGISScene(BasemapStyle.ArcGISTopographic).apply {
// Add a base surface with elevation source
baseSurface = Surface().apply {
// Create an elevation source from Terrain3D REST service
elevationSources.add(
ArcGISTiledElevationSource(
"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
)
)
}
// Create a scene layer from buildings REST service
operationalLayers.add(
ArcGISSceneLayer(
"https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/DevA_BuildingShells/SceneServer"
)
)
// Create a point to center on
val point = Point(
x = -122.69033,
y = 45.54605,
z = 500.0,
spatialReference = SpatialReference.wgs84()
)
initialViewpoint = Viewpoint(
center = point,
scale = 17000.0,
camera = Camera(
locationPoint = point,
heading = 162.58544,
pitch = 72.0,
roll = 0.0
)
)
}
// Create a LightingOptionsState with default values that will be used by the scene view
val lightingOptionsState = LightingOptionsState(
mutableStateOf(LightingMode.LightAndShadows),
mutableStateOf(Color(red = 220, green = 220, blue = 220, alpha = 255)),
mutableStateOf(AtmosphereEffect.HorizonOnly),
mutableStateOf(SpaceEffect.Stars)
)
// Create a message dialog view model for handling error messages
val messageDialogVM = MessageDialogViewModel()
}
/**
* Represents various lighting options used by the composable scene view.
*/
data class LightingOptionsState(
val sunLighting: MutableState<LightingMode>,
val ambientLightColor: MutableState<Color>,
val atmosphereEffect: MutableState<AtmosphereEffect>,
val spaceEffect: MutableState<SpaceEffect>
)