Skip to content

Show realistic light and shadows

View on GitHubSample viewer app

Show realistic lighting and shadows for a given time of day.

Image of show realistic light and shadows

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

  1. Create a Scene and display it in a composable SceneView.
  2. Create a ZonedDateTime to define the day and time of day.
  3. Set the sun time to the scene view using zoned date time and a time offset in milliseconds.
  4. Set the sun lighting of the scene view to a LightingMode of NoLight, Light, or LightAndShadows.

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

ShowRealisticLightAndShadowsViewModel.ktShowRealisticLightAndShadowsViewModel.ktMainActivity.ktShowRealisticLightAndShadowsScreen.kt
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* 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>
)

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.