섀도 매핑
소개
섀도 매핑은 3D 씬에 실시간 그림자를 구현하는 데 널리 사용되는 기법입니다. 이 기법은 광원의 시점에서 뎁스 맵 텍스처를 렌더링하는 방식으로 작동합니다. 그런 다음, 3D 모델의 픽셀에 셰이딩을 적용할 때 해당 픽셀의 깊이 값을 뎁스 맵과 비교하여, 그림자 영역에 있으면 더 어둡게, 빛이 비치는 영역에 있으면 더 밝게 셰이딩합니다.
그림자는 씬의 시각적 사실감을 높여주고, 오브젝트들의 상대적 위치를 파악하기 쉽게 해줍니다.

이미지의 왼쪽 장면에서는 물체가 평면으로부터 얼마나 떨어져 있는지 알 수 없는 반면, 오른쪽 장면에서는 그림자 덕분에 이를 쉽게 알 수 있다는 점에 주목하십시오.
DirectionalLight PointLight SpotLight castsShadow true castsShadows receivesShadows true falseXML-Qt
방향성 조명
방향성 조명은 무한히 멀리 떨어진, 식별할 수 없는 광원에서 한 방향으로 빛을 발산합니다. 이는 실제 생활에서 햇빛이 작용하는 방식과 유사합니다. 방향성 조명은 범위가 무한하며 강도가 약해지지 않습니다.
계단식 섀도우 맵
단일 그림자 맵( DirectionalLight )의 문제점 중 하나는 전체 장면을 빛의 관점에서 렌더링한다는 점입니다. 이로 인해 그림자 맵의 크기가 충분하지 않을 경우, 그림자가 거칠게 보일 수 있습니다. 더 나은 렌더링 품질을 얻기 위한 한 가지 방법은 계단식 그림자 맵(Cascaded Shadow Maps, CSM)을 사용하는 것입니다. Qt는 병렬 분할 섀도우 맵(PSSM)이라고 하는 CSM의 한 버전을 지원합니다. PSSM은 뷰 프러스텀을 여러 부분으로 분할하고 각 부분에 대해 섀도우 맵을 렌더링하는 방식으로 작동합니다.

이 그림은 PSSM 분할이 적용된 뷰 프러스텀의 추상적인 이미지를 보여줍니다. 두 개의 분할이 세 개의 캐스케이드로 이어집니다.
이렇게 하면 시각적 품질이 더 두드러지는 카메라 근처에서는 더 높은 섀도우맵 해상도를, 시각적 품질이 덜 눈에 띄는 카메라에서 멀리 떨어진 곳에서는 더 낮은 해상도를 적용할 수 있습니다.

위 그림은 분할이 전혀 없는 섀도우맵(왼쪽)과 3개의 분할이 적용된 섀도우맵(오른쪽)을 보여줍니다.
csmNumSplits 속성을 통해 캐스케이드 분할 횟수를 제어할 수 있으며, csmSplit1, csmSplit2 및 csmSplit3 속성을 통해 분할 위치를 지정할 수 있습니다. 분할 지점 간의 자연스러운 전환을 위해 csmBlendRatio 속성을 사용하여 분할 지점 간의 블렌딩 정도를 지정할 수 있습니다.

위 그림은 블렌딩이 활성화되지 않은 캐스케이드 이음매의 확대된 모습입니다.
분할을 하나 추가할 때마다 애플리케이션이 별도의 섀도우맵을 렌더링해야 하므로, 이는 성능에 부정적인 영향을 미친다는 점을 유의하십시오. 블렌딩 영역의 크기도 성능에 영향을 미치므로 가능한 한 작게 설정하십시오.
점광원
점광원( PointLight )은 빛의 중심에서 주어진 반경까지 모든 방향으로 동일한 강도의 빛을 방출하는 구로 설명할 수 있습니다. 이는 전구가 빛을 내는 방식과 유사합니다.

PointLight 는 섀도우맵을 큐브맵으로 렌더링하므로, 총 6회의 렌더링 패스가 수행됩니다. 이는 상당한 연산 부하를 유발할 수 있습니다.
스팟 라이트
SpotLight 는 ‘ coneAngle ’ 속성으로 정의된 원뿔 모양의 한 방향으로 빛을 발산합니다. 빛의 강도는 ‘ coneAngle ’에 가까워질수록 약해집니다. 빛의 강도가 약해지기 시작하는 각도는 ‘ innerConeAngle ’으로 정의됩니다. 이는 손전등이나 스포트라이트가 빛을 발산하는 방식과 유사합니다.

PointLight 와 달리, SpotLight 는 섀도우 맵을 단일 깊이 맵으로 렌더링합니다.
성능 및 씬 조정
Qt는 섀도우 매핑과 관련된 속성에 대해 합리적인 기본값을 제공하려고 노력하지만, 일반적으로 특정 장면에 맞게 조정할 필요가 있습니다. 특히 예상보다 훨씬 작거나 큰 장면의 경우 더욱 그렇습니다. 다음 섹션에서는 가능한 한 좋은 성능을 유지하면서도 섀도우 맵이 자연스럽게 보이도록 값을 조정하는 방법에 대해 더 자세히 다룰 것입니다.
섀도우 바이어스
Shadow bias 이는 소위 ‘섀도우 아크네(shadow-acne)’라고 불리는, 특정 패턴으로 나타나는 잘못된 그림자를 제거하는 방법입니다. 섀도우 바이어스는 그림자가 그림자를 드리우는 물체로부터 더 멀리 떨어진 곳에 나타나도록 섀도우 맵 깊이 텍스처를 오프셋하며, 이를 통해 섀도우 아크네를 해결하는 경우가 많습니다. 단점은 섀도우 바이어스를 너무 많이 적용하면 그림자가 그림자를 드리우는 물체에서 지나치게 멀어지는 ‘피터 패닝(Peter Panning)’ 현상이 발생할 수 있다는 점입니다. 또한 섀도우 맵 해상도를 높여 섀도우 아크네를 줄일 수도 있습니다.

위 이미지는 섀도우 바이어스가 0인 장면(왼쪽)과 10인 장면(오른쪽)을 비교한 것입니다. 왼쪽 장면에서는 원뿔과 원통의 상단에 일부 잘못된 그림자가 보입니다.
섀도우맵 해상도
섀도우맵의 해상도/품질은 ` shadowMapQuality ` 속성으로 제어됩니다. 섀도우맵 품질이 높을수록 그림자의 블록 현상이 줄어들지만, 렌더링 비용이 더 많이 들기 때문에 필요한 시각적 품질을 유지하면서 가능한 한 낮게 설정하는 것이 좋습니다.

위 이미지는 섀도우맵 해상도가 낮은 장면과 높은 장면의 비교를 보여줍니다.
부드러운 그림자 품질
소프트 섀도우는 실제 세계에서처럼 그림자가 가장자리로 갈수록 선명한 부분에서 부드러운 부분으로 점차 희미해지는 모습을 재현하는 방법입니다. 소프트 섀도우 품질은 ` softShadowQuality ` 속성으로 제어됩니다. 이 속성은 부드러움이 전혀 없는 하드 섀도우뿐만 아니라, 다양한 품질의 PCF(Percentage-Close Filtering) 소프트 섀도우도 지원합니다. 하드 섀도우는 렌더링 비용이 가장 저렴하며, PCF는 품질이 높아질수록 렌더링 비용이 점점 더 많이 듭니다. 소프트 섀도우의 반경을 조절하려면 ` pcfFactor ` 속성을 사용합니다. ` pcfFactor ` 값은 렌더링 속도에 영향을 미치지 않지만, 이 값이 높을수록 자연스럽게 보이려면 소프트 섀도우 품질도 더 높아야 합니다.

위 이미지는 왼쪽에 softShadowQuality 의 Light.Hard 그림자가 적용된 장면과, 오른쪽에 softShadowQuality 의 Light.PCF32 및 pcfFactor 의 10 가 적용된 장면을 보여줍니다.
섀도우 맵의 원거리
shadowMapFar 속성을 사용하여 섀도우 맵의 최대 거리를 제어할 수 있습니다. 이 속성은 PointLight 및 SpotLight 과 DirectionalLight 에서 작동 방식이 약간 다릅니다.
PointLight/SpotLight 의 경우, 이 속성은 렌더링된 그림자의 바운딩 박스 크기를 결정하지만, DirectionalLight 의 경우 이 속성은 섀도 맵이 씬 내에서 씬의 카메라로부터 얼마나 먼 거리까지 커버해야 하는지를 정의합니다.

위 이미지는 동일한 방향광을 사용하는 동일한 장면이지만, shadowMapFar 의 값이 서로 다른 두 가지 경우를 보여줍니다.
섀도우맵 비트 심도
특정 상황에서는 씬이 매우 커서 섀도우 맵이 깊이 축에서 넓은 영역을 덮게 되는 경우가 있습니다. 예를 들어, 카메라 시야에서 멀리 떨어져 있으면서도 여전히 그림자를 드리우고 있어 섀도우 맵 경계 내에 포함되어야 하는 오브젝트가 많은 경우입니다. 이 경우, shadowBias 값을 높여도 씬에 밴딩 아티팩트가 발생할 수 있습니다. 이를 해결하는 한 가지 방법은 섀도우 맵에 32비트 심도(depth)를 사용하는 것입니다. ‘ use32BitShadowmap ’ 속성을 ‘ true ’로 설정하면 해당 조명에 대해 이 기능이 활성화됩니다.

위 이미지는 동일한 방향광을 사용하는 동일한 장면이지만, 하나는 32비트 섀도우맵을 사용하고 다른 하나는 16비트 섀도우맵을 사용하는 모습을 보여줍니다.
‘이미지 기반 라이팅(Image-Based Lighting) 사용’, ‘라이트맵(Lightmaps) 및 전역 조명(Global Illumination) ’, ‘카스케이드 섀도우 맵(Qt Quick 3D ) 예제’도 참조하십시오 .
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.