Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qtquick3d-shadow-mapping.qdoc
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5
6\title Shadow Mapping
7\page quick3d-shadow-mapping
8
9\section1 Introduction
10
11\l{https://en.wikipedia.org/wiki/Shadow_mapping}{Shadow-mapping} is a common technique for providing real time shadows to a 3D scene.
12It works by rendering a depth map texture from the light source's point of view. Then, when shading a pixel of a 3D model its depth value is compared to the depth map and is shaded darker if it is in shadow or lighter if it is lit by the light.
13
14Shadows add to the perceptual realism of a scene and makes it easier to judge the relative positions of objects.
15
16\image{shadows-shadow-no-shadow.webp}
17
18Notice how in the left scene in the image it is impossible to tell how far from the plane the objects are but in the right scene the shadows makes this easy.
19
20Qt provides support for shadow mapping for all our three light types, DirectionalLight, PointLight and SpotLight. To activate shadows in your scene you need to first set the light to cast shadows by setting \l{Light::}{castsShadow} to \c{true}. You can then control which Model's will cast and receive shadows by setting the \l{Model::}{castsShadows} and \l{Model::}{receivesShadows} to \c{true} or \c{false}.
21
22\section1 Directional Lights
23
24The directional light emits light in one direction from an unidentifiable source located infinitely far away. This is similar to the way sunlight works in real life. A directional light has infinite range and does not diminish.
25
26\section2 Cascading Shadow Maps
27
28One problem with a DirectionalLight is that it renders the whole scene from the point of view of the light. This can lead to blocky looking shadows when the size of the shadowmap is not adequate. One option to get better rendering quality is to use Cascading Shadow Maps (CSM). Qt supports a version of CSM called Parallell Split Shadow Maps (PSSM). PSSM works by splitting the view frustum into several parts and rendering a shadowmap for each part.
29
30\image {quick3d-pssm.webp}
31
32This picture shows an abstract image of a view frustum with PSSM splits. It has two splits ending up in three cascades.
33
34This way you can get better shadowmap resolution closer to the camera where the visual quality is more noticeable and lower resolution further from the camera where the visual quality is less noticeable.
35
36\image {shadows-0csm-3csm.webp}
37
38The above picture shows a shadowmap without any splits (left) and a shadowmap with 3 splits (right).
39
40You can control the number of cascade splits by the \l{DirectionalLight::}{csmNumSplits} property and where the splits are by the \l{DirectionalLight::}{csmSplit1}, \l{DirectionalLight::}{csmSplit2} and \l{DirectionalLight::}{csmSplit3} properties. To get nice looking transitions between the splits you can specify a certain amount of blending between them with the \l{DirectionalLight::}{csmBlendRatio} property.
41
42\image{shadows-seam.webp}
43
44The above picture shows a zoomed in view of a cascade seam with no blending active.
45
46Keep in mind that for every split you add the application has to render another shadowmap which will affect performance negatively. The size of the blend area will affect performance so keep it as small as possible.
47
48\section1 Point Light
49
50The PointLight can be described as a sphere, emitting light with equal strength in all directions from the center of the light up to a given radius. This is similar to the way a light bulb emits light.
51
52\image {shadows-point-light.webp}
53
54The PointLight renders its shadowmap into a cubemap which means that is does six render passes. This can be quite computationally expensive.
55
56\section1 Spot Light
57
58The SpotLight emits light towards one direction in a cone shape, which is defined by the \l{SpotLight}{coneAngle} property. The light intensity diminishes when approaching the \l{SpotLight}{coneAngle}. The angle at which the light intensity starts to diminish is defined by \l{SpotLight}{innerConeAngle}. This is similar to how a flashlight or a spot-light emits light.
59
60\image {shadows-spot-light.webp}
61
62Just like the PointLight, the SpotLight also renders its shadowmap into a cubemap.
63
64\section1 Performance and scene tweaking
65
66While Qt tries to provide sensible default values for the properties related to shadowmapping there is usually some need to tweak them to fit the specific scene. Especially if you have a scene that is much smaller or bigger than what is expected. The following section will go into more detail of how you can tweak the values to make the shadow map look good while still maintaining as good performance as possible.
67
68\section2 Shadow bias
69
70\l{Light::shadowBias}{Shadow bias} is a way to remove so-called shadow-acne which are false shadows that typically appear in certain patterns. Shadow bias offsets the shadow map depth texture in a way that shadows appear further from the shadowing object and this often fixes the shadow-acne. The draw back is that if you have too much shadow bias then you can get an effect called peter panning where the shadow is too far away from the shadowing object. It is also possible to reduce shadow acne by increasing the shadowmap resolution.
71
72\image{shadows-bias.webp}
73
74The above image shows a scene with 0 shadow bias (left) vs 10 shadow bias (right). The left scene has some false shadows on the top of the cones and cylinders.
75
76\section2 Shadowmap resolution
77
78The resolution/quality of the shadowmap is controlled by the \l{Light::}{shadowMapQuality} property. A higher shadowmap quality decreases the blockiness of the shadows but is more expensive to render so set it as low as possible while still maintaining the needed visual quality.
79
80\image{shadows-low-high-resolution.webp}
81
82The above image shows a scene with a low shadowmap resolution vs a high shadowmap resolution.
83
84\section2 Soft shadows quality
85
86Soft shadows are a way to approximate the way shadows look in real life where they fade from being harder to softer at the edges. The soft shadow quality is controlled by the \l{Light}{softShadowQuality} property.
87It supports hard shadows with no softness as well as percentage-close filtering (PCF) soft shadows of varying quality. The hard shadows are the cheapest to render and PCF gets more and more expensive the higher quality it is. To control the radius of the soft shadow use the \l{Light::}{pcfFactor} property. The value of \l{Light::}{pcfFactor} does not impact the rendering speed but the higher it is the higher the soft shadow quality needs to be to look good.
88
89\image{shadows-hard-soft.webp}
90
91The above image shows a scene with a \l{Light}{softShadowQuality} \c{Light.Hard} shadow on the left and a scene with a \l{Light}{softShadowQuality} \c{Light.PCF32} and \l{Light::}{pcfRadius} \c{10} on the right.
92
93\section2 Shadowmap far distance
94
95The property \l{Light}{shadowMapFar} can be used to control the maximum distance of the shadow map. This property works slightly different for PointLight and SpotLight vs DirectionalLight.
96
97For PointLight/SpotLight it determines how big the bounding box of the rendered shadow should be, but for the DirectionalLight it defines how far from the scene's camera the shadow map should cover in the scene.
98
99\image{shadows-near-far.webp}
100
101The above image shows the same scene with the same directional light but two different values for \l{Light}{shadowMapFar}.
102
103\sa {Using Image-Based Lighting}, {Lightmaps and Global Illumination}
104
105*/
106