Before-After 이미지 비교 플러그인. 

 

 

주의 : 잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요.


[ PBR 이란 무엇인가 ] 10. Image Based Lighting

Global Illumination & Indirect Lighting ] 에서는 GI 를 위해 indirect light 가 고려되어야 한다고 했습니다. 

광원이 있는 경우라면 그것을 통해 indirect light 를 계산할 수 있죠. 하지만 현실적으로 모든 light 를 배치하는 것은 힘듭니다. 그렇기 때문에 이를 근사계산하기 위해 그래픽스 연구자들은 indirect light 를 image 로부터 얻어 오는 방법에 대해서 고민했고, 요새 자주 사용되는 Image Based Lighting( IBL ) 이라는 개념을 생각해 냈습니다.

이 문서에서는 이 기법이 어떻게 발전해 왔는지, 구체적으로 어떤 개념인지에 대해 다루도록 하겠습니다. UE4 에서 IBL 이 사용되는 방식에 대해서는 시리즈의 다음 문서에서 다루도록 하겠습니다.

아티스트 분들은, 글 내용 중에 이상한 개념들이 나오는데, 너무 어렵게 생각하지 마시고 그냥 그런게 있다고 생각하고 넘어가시기 바랍니다. 언급을 안 하기도 그렇고 하기도 그렇고 그래서 대충 개념만 썼는데, 어려울 수 있습니다. 그냥 기본 설명과 그림을 위주로 보시기 바랍니다. 어려운 개념들은 몰라도 크게 상관은 없는 것들입니다.

Cubemap

그래픽스 카드들은 큐브맵이라는 것을 지원합니다. 큐브맵은 어떤 시점을 중심으로 둘러싼 환경들을 미리 렌더링해서 저장할 수 있는 텍스쳐입니다. 보통 특정 위치에서 여러 방향으로 사진을 찍은 다음에 그것을 보정해서 합치는거죠. 이러한 큐브맵이 실시간 그래픽스에서 가장 먼저 사용된 곳이 SkyBox 와 SkySphere 였습니다.

그림1. 스카이 큐브맵. 출처 : Rendering a skybox using a cube map with opengel and glsl.

그림2. 그림1 의 렌더링 결과. 출처 : 그림1 과 같음.

보통 원경에다가 사용했기 때문에 거리에 의한 왜곡의 영향도 덜 받았으며 가시 품질도 나름 괜찮았죠.

Environment Mapping

그런데 텍스쳐를 이용해 금속의 반사 소스로 활용하려는 움직임이 있었습니다. 1976 년에 Blinn 과 Newell 이 "Texture and reflection in computer generated images" 라는 논문에서 이 개념에 대해 발표한 바가 있고 80 년와 90 년대 초반에 여러 사람에 의해 사용되고 발전해 왔습니다( 자세한 내용에 대해 알고 싶으시다면 [1] 의 문서를 확인하세요 ).

이러한 방식을 Environment Mapping( 환경 매핑 ) 혹은 Reflection Mapping( 반사 매핑 ) 이라 부릅니다. 특히 그래픽스 하드웨어가 지원하는 큐브맵을 이용하면 이를 쉽게 표현할 수 있습니다.

그림3. Environment Mapping 예제. 출처 : Environment Mapping, Han-Wei Shen.

큐브맵의 좌표는 그림4 처럼 큐브( 정육면체 )의 중심을 원점으로 하는 좌표계로 표현됩니다.

그림4. 큐브맵 좌표계. 출처 : CS 354 Texture Mapping.

그렇기 때문에 그림5 에서 볼 수 있듯이, 표면의 normal 과 viewer 를 향한 vector 를 알게 되면 반사벡터를 쉽게 알 수 있습니다.

그림5. 환경 매핑 좌표 구하기. V 는 View 에서 서피스까지의 벡터, N 은 노멀, Vr 은 반사 벡터. 출처 : Mapping Techniques.

그림5 에서 큐브가 아니라 구가 나와서 헷갈리는 분도 계실 수 있지만, 구는 그림6 처럼 큐브에 매핑될 수 있습니다. 벡터는 길이는 달라도 방향이 동일하면 정규화( normalize )했을 때 같은 벡터가 됩니다. 그것을 큐브맵의 좌표로 사용합니다.

그림6. sphere 와 cube 에서 벡터.

이때까지는 EnvironmentMapping 이라는 것이 금속의 반사를 표현하기 위한 소스의 역할만 하고 있었습니다.

Image Based Lighting

그렇지만 하드웨어 성능이 더 발전하면서 Environment Mapping 을 한 단계 더 발전시켜 광원으로 만드려는 시도가 있었으며, 이것이 바로 Image-Based Lighting( IBL, 이미지 기반 조명 ) 개념입니다. 이것에 대해 주도적으로 연구한 사람은 Paul Debevec 이라는 분인 것 같더군요[2]( [2] 에 가면, 2003 년까지의 HDR 및 IBL 관련 자료들에 대한 링크가 많습니다. 관심있는 분들은 확인해 보시기 바랍니다 ).

IBL 과 Environment Mapping 의 가장 큰 차이는 이미지 소스가 광원으로서 사용되느냐 그렇지 않느냐에 있습니다.

IBL Diffuse

표면에 들어 온 빛은 그림7 처럼 반사( reflected ), 투과( transmitted ), 흡수( absorbed )됩니다. 

 

그림7. 빛의 반사, 투과, 흡수. 출처 : Waves, KaiserScience.

그 중에서 반사 성분은 그림8 처럼 크게 diffuse reflection( 난반사 ) 과 specular reflection( 정반사 ) 로 나뉘죠. 다들 이 개념에 대해서는 익숙할 것입니다. 그런 현상이 왜 발생하는지는 시리즈의 뒷부분에서 다루도록 하겠습니다.

그림8. Diffuse reflection & Specuar reflection. 출처 : Diffuse reflection, Wikipedia.

어쨌든 기존 environment mapping 에서는 큐브맵을 specular 성분으로만 사용했습니다. 앞서 말했듯이 금속을 표현하기 위한 용도였죠. 하지만 이를 제대로 된 광원으로서 사용하기 위해서는 diffuse 성분도 고려되어야 하며, GI 까지 생각하면 그림9 처럼 주변광들까지 고려가 되어야 합니다. 주변광까지 고려해서 큐브맵으로부터 서피스에 들어 온 빛들은 서피스 입장에서 보면 조도( illuminance, irradiance )라 할 수 있겠죠. 그래서 이러한 정보를 담고 있는 것을 irradiance map 이라고 부릅니다.

그림9. IBL 에서 irradiance. 출처 : [3].

이 irradiance map 은 해당 지점에서 오는 난반사 성분을 받아야 하기 때문에 원래 이미지보다는 뭉개진 느낌이 나겠죠.  그림10 의 오른쪽에 보이는 큐브맵이 irradiance map 입니다.

그림10. Irradiance map 샘플. 출처 : [3].

그런데 여기에서 한 가지 문제가 발생합니다. 큐브맵 텍스쳐를 샘플링( 텍스쳐에서 텍셀( texel )값을 가지고 오고 필터링( filtering )하는 작업 )하는 것은 그렇게 비용이 싼 작업이 아닙니다. 게다가 그림9 에서처럼 매우 많은 영역을 샘플링해야 합니다. 그림9 에서는 예를 들기 위해서 화살표 몇개만 그려주고 2D 로 보여줬지만 3D 에서 엄청난 텍셀을 샘플링해야 합니다. 물론 하나만 할 수도 있겠지만, 그럼 주변광( indirect lighting )을 받는다는 GI 원칙에서 어긋나겠죠. [3] 에 따르면 한 면이 128 X 128 해상도인 큐브맵에서 diffuse 를 구하기 위해서는 50,000 만큼의 샘플링이 필요하다고 하네요.

그래서 연구자들은 이를 좀 단순하게 계산하는 방법을 찾았습니다. 그것이 바로 Spherical Harmonics( SH, 구면 조화 )입니다. 이름부터 무시무시합니다. 어디선가 한번씩은 들어 보셨을 거라 생각합니다. 이 주제에 대해서는 저도 완전히 파악하고 있지 않기 때문에 나중에 시간이 나면 자세히 다루도록 하겠습니다.

SH 는 구면에서 뭔가 튀어나오거나 들어 간 물체의 형태를 그림11 처럼 수학적으로 표현하는 것입니다. 그런데 계수( l )가 얼마나 크냐에 따라서 좀더 디테일한 모양이 나오는 것이죠. 이 함수에다가 각도같은 걸 넣으면 원하는 형태를 얻을 수 있습니다. 솔직히 이해하기 힘드니 "그냥 그렇구나" 하시면 됩니다.

그림11. Spherical Harmonics 예제. 출처 : Opinions on Spherical harmonics.

그런데 이걸 어디다 쓰느냐구요?

예를 들어 그림10 의 irradiance map 을 구에다가 매핑한 다음에 밝기에 따라 튀어 나오게 하면 그림12 같은 느낌이 되겠죠(그냥 개념적으로 쉬운 설명을 위한 용도로 만들었으므로 정확한 것은 아닙니다 ).

그림12. 그림10 의 irradiance 를 구에 매핑했을 때의 느낌.

그럼 이 모양에 SH 를 적용해서 단순한 함수로 만듭니다. 그림11 에서 봤듯이 어떤 계수를 사용하느냐에 따라 좀 더 많은 모양이 나오고 결과가 정확해지겠죠. 대체적으로 "l = 3" 정도면 그럴싸한 모양이 나온다고 합니다.

어쨌든 이런 식으로 각 텍셀을 SH 함수로 만들면 빛이 나가는 경향과 세기가 결정됩니다. 아티스트 분들은 그냥 "최적화 함수구나" 라고 이해하시면 됩니다. 우리가 사용하는 irradiance map 은 단순히 diffuse 를 저장한 것이 아니라 SH 를 저장한 것이라는 것만 알고 계시면 됩니다.

이러한 IBL diffuse 를 적용하면 그림13 과 같은 결과가 나옵니다.

그림13. IBL Indirect Diffuse. 출처 : [3].

IBL Specular

Specular 성분은 Environment Mapping 에서 다뤘던 것과 큰 차이는 없습니다. 하지만 PBR 에서는 roughness( 거칠기 ) 라는 개념을 도입했고, 같은 금속이라도 얼마나 연마되었느냐에 따라서 그림14 에서 볼 수 있듯이 매끈함의 정도가 틀립니다( roughness 에 대해서는 시리즈의 뒤쪽에서 설명하겠습니다 ).

그림14. Roughness 에 따른 매끈함의 변화.

일반적으로 거칠기에 의해 blurring 이 먹는 것을 표현하기 위해 그림15 처럼 mipmap 을 만들어 처리합니다. LOD 레벨이 높아질수록 Roughness 가 높은 것으로 취급합니다.

그림15. 반사맵 밉맵. 출처 : [3].

Roughness 0.1 일 경우에 specular 만 출력한 예가 그림16 에 나와 있습니다.

그림16. Roughness 01 에서 IBL Indirect specular 의 예. 출처 : [3].

정리

IBL 은 이미지를 광원으로 취급해서 indirect light 성분을 획득하는 방식입니다. 실시간 GI 를 구현하기 힘든 상황에서 대안으로 사용합니다. 사실, 실시간 GI 를 사용한다고 해도 모든 광원을 배치하는 것은 불가능하기 때문에, 같이 사용하는 경향이 있습니다.

실제 엔진에서는 importance sampling 이라든가 하는 복잡한 방식을 사용합니다. 왜냐하면 diffuse 처럼 specular 로 일정 영역을 샘플링해야 제대로 된 결과가 나오기 때문입니다. 이 기법은 반사, Area light, Ray-tracing, 적분( integral ) 등의 주제와 관련이 있으므로 여기에서 설명하기에는 좀 주제가 무겁습니다. 그러므로 나중에 따로 주제를 잡아서 이야기하도록 하겠습니다( 만약 자세한 내용을 알고자 한다면, "IBL Importance Sampling" 이나 "IBL Filtered Importance Sampling" 등의 키워드로 검색해 보십시오.

UE4 의 경우에는 Split Sum Approximation 과 Prefiltered Environment Map 이라는 기법을 사용해 IBL specular 를 구현한다는 것만 언급하고 넘어가겠습니다. 자세한 내용은 [ Real Shading in Unreal Engine 4 ] 의 [ Image based lighting ] 항목을 참조하세요 ).

참고자료

[1] The Story of Reflection Mapping.

[2] HDRI and Image-Based Lighting, SIGGRAPH 2003.

[3] Physcally Based Rendering - Part Three.

주의 : 잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요.


[ PBR 이란 무엇인가 ] 9. Global Illumination & Indirect Lighting

빛의 경로

지금까지는 빛이 서피스에 반사되어 들어 오는 경우만을 이야기했습니다. 하지만 빛이 눈에 들어 오는 경로는 그림1 처럼 매우 복잡합니다. 산란( scattering ), 투과( Transmission ), 반사( Reflection ), 흡수( Absorbtion )가 모두 고려되어야 매우 자연스러운 결과가 나옵니다.

그림1. 다양한 경로로 눈에 들어 오는 빛.

Local Illumination

컴퓨팅 파워의 한계 때문에 실시간 그래픽스에서 그림1 에 나오는 모든 요소들을 처리할 수는 없습니다. 그래서 PBR 이전에는 빛이 직접적으로 닿는 부분만 고려해 렌더링을 했습니다. 그렇게 되면 빛이 직접적으로 닿지 않는 부분은 어두워지겠죠. 그렇지만 우리는 실세계에서는 완벽하게 어두운 부분은 존재할 수 없음을 알고 있습니다. 왜냐하면 한 서피스에 도달하는 빛은 여러 서피스로부터 반사된 후에 올 수 있다는 것을 알고 있기 때문입니다. 그래서 주변광( ambient light ) 라는 개념을 만들어서 어두운 부분을 대충 밝혀 줍니다.

Ambient 를 얼마만큼 밝혀줘야 하느냐? 그것은 아티스트의 감에 달려 있었습니다. 그래서 global ambient 와 material ambient 가 나뉘어 있었습니다. 오브젝트가 놓여 있는 환경이 다르다보니 어쩔 수 없는 선택이었죠.

이런 방식을 local illumination( 지역 조명 ) 이라고 부르며, 그 결과는 그림2 와 같습니다.

그림2. Local Illumination. 출처 : [1]

Global Illumination

사람들은 Local Illumination 이 부자연스럽다는 것을 알고 있습니다. 서피스에 들어 온 빛은 다시 다른 서피스를 위한 광원으로 사용될 수 있습니다. 물론 투과되는 빛도 다른 서피스를 위한 광원으로 사용될 수 있습니다. 이렇게 서피스에서 반사되거나 굴절되는 모든 빛을 새로운 광원으로 삼는 것을 Global illumination 이라 부릅니다.

그림3. Global Illumination. 출처 : [1]

그림3 을 보시면 그림2 와 비교했을 때 굴절과 반사가 제대로 제대로 적용되고 있음을 확인할 수 있습니다. 우리가 실세계에서 익숙하게 볼 수 있는 복잡한 결과가 나오게 되는겁니다.

이제 여기에서 여러분에게 GI 의 핵심 성분들에 대해서 이야기하도록 하겠습니다.

그림4. 눈에 들어 온 GI 성분들. 출처 : [2]

    • Direct light 는 광원에서 표면으로 직접 들어 온 빛을 의미합니다.

    • Indirect light 는 표면에 들어 온 빛이 반사되어 새로운 광원처럼 사용되는 경우를 의미합니다.

만약 direct light 성분만 계산을 하게 되면 그림5 와 같은 결과가 나옵니다.

그림5. Direct light Only. 출처 : [3].

바닥에 비춰진 빛이 반사되어( bounced ) 광원( indirect light )으로 작용하면, 그림6 과 같은 결과가 나옵니다.

그림6. Direct light + 1-bounced indirect light. 출처 : [3].

그렇다면 광원에서 나와서 한 번 반사된( 1-bounced ) 빛이 한 번 더 반사되면( 2-bounced ) 어떻게 될까요? 다시 다른 오브젝트나 바닥으로 반사되는 빛들도 존재하겠죠? 그러면 그림7 처럼 됩니다.

그림7. Direct light + 2-bounced indirect light. 출처 : [3].

이러한 bounce 가 많으면 많을수록 더 자연스러운 결과가 나오게 됩니다.

하지만 실시간 그래픽스에서 이런 계산을 하는 것은 너무 힘듭니다. 그래서 이를 근사계산하기 위해서 LPV( Light Propagation Volume ), SVOGI( Sparse Voxel Octree Global Illumination ) 등의 실시간 GI 알고리즘들과 Image Based Lighting( IBL ) 과 같은 개념들이 나오게 되었습니다.

Indirect Lighting Bounce 설정

UE4 에서는 LPV 를 적용하지 않는 이상 Static 과 Stationary 에 대해서만 GI 를 적용해 줍니다. UE4 에서는 이를 "Lightmass Global Illumination" 이라고 표현합니다.

툴바에 있는 "Settings" 풀다운 버튼에는 "World Settings" 메뉴가 있습니다.

그림8. WorldSettings 메뉴.

거기에 보면 "Lightmass" 카테고리가 있죠. 그 중에 "Num Indirect Lighting Bounces" 항목이 있습니다. 위에서 언급했듯이, 광원에서 나온 빛이 반사되서 나오는 횟수를 의미합니다. 이것이 0 이라면 direct light 성분만을 고려하겠다는 겁니다.

그림9. Direct light only.

이제 bounce 를 2 와 4 로 주고 결과를 확인해 보도록 하겠습니다.

그림10. Direct Light + Indirect Light. Bounce 2 일 때와 4 일 때의 결과.

Bounce 가 2 일 때와 4 일 때 미약하지만 영향을 주는 범위가 넓어지는 것을 알 수 있습니다. 하지만 2 일 때와 4 일 때의 차이는 범위가 조금 넓어졌다는 것 말고는 큰 차이가 없습니다. 반사를 하면 할수록 빛이 감쇠되기 때문에 너무 높은 값을 잡아 봐야 별로 소용이 없습니다. 그러므로 2 정도의 값이 적절합니다. 이는 Lightmass 빌드 속도에도 영향을 주므로 신중하게 결정할 필요가 있습니다.

Indirect Lighting Intensity 설정

하지만 기대했던 것처럼 Indirect light 의 영향력이 크지 않아 실망하시는 분들이 계실겁니다. 이 때 사용할 수 있는 것이 "Indirect Lighting Intensity" 속성입니다. UE4 의 광원들에는 "Light" 카테고리에 "Indirect lighting Intensity" 라는 항목이 있습니다.

앞의 "Lightmass" 카테고리의  설정은 전역 설정이지만 "Light" 카테고리 설정은 개별 설정입니다. 이 값을 2 로 해 놓고 결과를 확인해 보도록 하겠습니다.

그림11. Direct Light + Indirect Light. Bounce 2 일 때와 Intensity 값을 2 배로 늘려서 결과 비교.

Intensity 를 올리면 굳이 bounce 를 올리지 않더라도 더 멀리까지 영향을 주는 것처럼 보일 수 있습니다. 물론 가까운 곳에서 indirect lighting 의 영향이 세지기는 하겠죠.

Direct Light 와 Indirect Light 의 관계

그런데 실무를 하다가 보면 이상한 의문이 드는 분들이 계실 겁니다. "Light intensity 를 내렸더니 direct lighting 성분이 내려 가고 indirect lighting 성분이 올라 가요!!!", "Lighting build 를 했더니 갑자기 결과가 너무 달라져요!!!"

그림11 까지의 스샷들은 5000 루멘을 기준으로 찍은 것입니다. 그림11 의 두 번째 환경에서 light intensity 만 100 으로 고쳐보겠습니다.

그림12. 5000 루멘에서 100 루멘으로 내렸을 때

이상한 결과가 나왔지만 매우 당연한 것입니다. Indirect lighting 이라는 것은 Lightmass 빌드를 돌려야만 계산되는 것입니다. 그래서 intensity 를 바꾸게 되면 direct lighting 성분에는 즉각 반영이 되지만, indirect lighting 성분은 이전에 계산했던 값 그대로 남아 있게 됩니다. 그러면 direct light 성분이 낮아졌으므로 indirect light 성분은 ( auto exposure 에 의해 ) 상대적으로 밝아지는 것이죠. 그러므로 stationary light 의 Intensity 값을 변경하면 반드시 Lightmass 빌드를 해 주셔야 합니다. 물론 Static 도 그래야 합니다.

이러한 사실을 이용하면 재밌는 비주얼 디버깅을 해 볼 수 있습니다. Intensity 값을 0 으로 해 버리면 direct light 성분이 평가되지 않으므로 indirect light 성분만 볼 수가 있습니다. 실제 영향을 준 범위가 어디까지인지 알 수가 있겠죠.

그림13. Intensity 를 0 으로 만들어 Indirect 성분만 확인.

Indirect light 성분을 조정하는 것은 direct light 성분에 전혀 영향을 주지 않습니다. 단지 상대적인 관계가 달라 보이는 것입니다.

Lighting Quality 와 메쉬

Lightmass 를 preview 로 빌드하면 indirect lighting 결과가 상당히 이상하게 나올 수 있습니다.

그림14. Lighting Quality 설정.

그림15 는 indirect light 가 테이블을 뚫고 나오는 것을 보여 줍니다.

그림15. Preview 에서 잘못 나오는 indirect lighting 결과.

제가 lightmass 구현을 안 봐서 잘 모르겠지만, 아마도 volume 에다가 illuminance 나 luminance 를 저장하는 것이 아닌가 싶습니다. 그리고 preview 에서 product 로 품질이 올라갈 수록 그 volume 의 크기가 조밀해지는 것이 아닌가 싶습니다. Ray 샘플 개수나 photon 개수 및 밀도 등 여러 요소들이 달라지기 때문입니다. 그렇기 때문에 샘플링되지 않은 부분들은 보간이 됩니다.

그래서 테이블의 두께를 3 배 정도로 해 봤습니다. 그랬더니 그림16 에서 볼 수 있듯이 preview 에서도 차폐가 거의 제대로 되는 것을 확인할 수 있었습니다.

그림16. 테이블의 두께를 3 배로 늘렸을 때의 결과.

사실 그림16 도 완벽한 결과는 아닙니다. Production 으로 빌드했을 때는 완벽하게 차폐가 됩니다.

여기에서 이야기하고자 하는 것은 메쉬의 두께가 얇으면 preview 에서 잘못된 결과를 산출할 수 있기 때문에 이를 고려하면서 작업을 하셔야 한다는 것입니다. 사실 너무 얇으면 production 에서도 문제가 발생합니다.

그러므로 가급적이면 너무 얇은 메쉬들은 안 만드는 것이 좋습니다. 만약 어쩔 수 없이 그런 메쉬들을 만들어야 한다면, bounce 를 1 로 설정하고 production 이나 high 품질에서 라이팅 결과를 확인하시는 것이 바람직할 것이라 생각합니다.

PostProcessVolume

전체 indirect lighting 성분을 전반적으로 올리고 싶은 경우가 있습니다. 그런 경우에는 PostProcessVolume 을 설치하시면 됩니다. "Rendering Features" 카테고리에 보면 "Global Illumination" 이라는 하위 카테고리가 있습니다.

"IndirectLightingColor" 는 전체 indirect light 성분의 색상에 곱해지며, "Indirect Lighting Intensity" 는 전체 indirect light 성분의 세기에 곱해집니다. 이런 설정은 전역적이므로 함부로 건드리지는 않는 것이 좋습니다. 라이트 설정을 다 해 놨는데 공식이 바뀌어서 전반적으로 intensity 가 달라졌다든가 하는 경우나 게임 그래픽스 컨셉상 이상한 조명을 만들고 싶다든가 하는 경우에만 사용해야겠죠.

그림17. PostProcessVolume 을 사용한 indirect 성분 조정.

여러분은 그림17 에서 보이듯이 이런 설정은 direct lighting 성분에 전혀 영향을 주지 않는다는 점을 이해해야만 합니다. Direct lighting 성분은 여전히 흰색으로 보이고 있음을 기억하세요.

참고자료

[1] Global illumination, Wikipeida.

[2] PRACTICAL REAL-TIME VOXEL-BASED GLOBAL ILLUMINATION FOR CURRENT GPUS, Alexey Panteleev, NVIDIA.

[3] Real-time Global Illumination Using Voxel Cone Tracing, Fredrik Prantare.

주의 : 잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요.


[ PBR 이란 무엇인가 ] 8. Attenuation Radius 설정

거리 감쇠

3. 빛의 감쇠 ] 에서는 빛의 감쇠가 1 / dist2 으로 이루어진다고 했습니다. 하지만 실질적으로 컴퓨터 프로그램에서는 그런 식을 사용할 수 없습니다. 왜일까요?

dist = 0 인 상황이라면 결과가 1 / 0 이 됩니다. 그러면 컴퓨터는 이를 inf( 무한대, infinity ) 라고 평가하게 됩니다. 그래서 보통은 기본 감쇠 공식은 거리가 0 이 될 수 없다고 가정하고 계산을 하게 됩니다. 게다가 가장 가까울 때의 빛이 원래 빛의 밝기보다 밝아서는 안 되는 원칙( 에너지 보존 법칙 )도 지켜줘야겠죠.

그래서 UE4 에서는 거리 감쇠를 위해 식1 을 사용합니다.

식1. UE4 에서의 거리 감쇠 공식.

DistanceBias 라는 것이 갑자기 튀어 나와서 놀라셨겠지만, 이것은 쉐이더에서 그냥 1 로 정해져 있습니다.

식만 봐서는 잘 모르겠죠? 이를 그래프로 보면 그림1 과 같습니다.

 

그림1. 1 / dist2 과 1 / ( dist2 + 12 ) 의 비교. 거리( x 값 )가 0 이 되면 파란 그래프는 최대값이 1 이 됩니다.

하지만 여전히 이 감쇠 그래프는 문제점을 가지고 있습니다. x 값이 엄청나게 커져도 0 이 되질 않습니다. 즉 빛은 그 세기가 다를뿐 무한대의 거리까지 퍼져나간다는 의미입니다.

감쇠 반경 마스크

대부분의 엔진들에서 광원들은 "Attenuation Radius" 라는 속성을 가지고 있습니다. 이는 광원이 영향을 미치는 거리를 강제로 줄여버리는 역할을 합니다.

그림2. UE4 의 Attenuation Radius 속성. Source Radius 는 area light 의 속성입니다. 

왜 이런 일을 할까요? 사실 이유는 별게 아닙니다. 컴퓨팅 파워가 부족하기 때문입니다.

그림3 을 보시면 어느 정도 거리가 멀어지면 빛의 거의 영향을 미치지 못하는 것을 볼 수 있습니다.

그림3. 눈으로 보면 일정 거리 이상에 빛이 닿지 않는 것처럼 보입니다. 하지만 사실은 그림1 에서 확인할 수 있듯이 매우 약한 빛이 닿고 있는 것이죠.

씬 내에는 수 백개 많으면 수 천개의 광원이 존재할 수 있는데, 이를 모두 계산하기에는 비용이 너무 비쌉니다. 그래서 특정 광원이 미치는 범위를 조절하게 됩니다. 그것이 바로 감쇠 반경( Attenuation Radius )인 것이죠. 이를 UE4 에서는 내부적으로 "Light Radius Mask" 라고 부릅니다.

이는 식2 와 같이 계산됩니다.

식2. LightRadiusMask 공식.

식이 어렵죠? 이해하시려고 노력하실 필요는 없습니다. 저도 잘 이해가 안 갑니다. 여기에서 saturate() 라는 함수는 0 보다 작은 값은 0 으로, 1 보다 큰 값은 1 로 잘라주는 함수입니다.

어쨌든 그래프로 느낌만 이해하면 됩니다. 예를 들어 Radius 가 1 인 경우와 2 인 경우를 살펴 봅시다. 그럼 그래프는 그림4 와 같은 모양을 가집니다.

그림4. LightRadiusMask 그래프. Radius 가 1 이면 Dist 가 1 이 넘어갈 때 밝기가 0 이 되고, Radius 가 2 이면 Distance 가 2 가 넘어갈 때 밝기가 0 이 됩니다.

거리 감쇠와 감쇠 반경의 결합

이제 위에서 언급한 두 개의 식( 식1식2 )을 곱한 것이 최종 감쇠 공식입니다.

식3. 최종 감쇠 공식.

식을 봐봐야 머리만 아프니 그래프를 살펴 보죠. 이것의 형태는 그림5 와 같습니다. 그래프의 차이를 좀 더 명확하게 보기 위해서 빛의 밝기를 10 이라고 가정했습니다.

그림5. 빛의 밝기가 10 일 때 최종 감쇠 그래프.

여러분은 그림5 를 보면서 Radius 가 크면 클수록 Attenuation Radius 를 적용하지 않은 원래의 감쇠 공식과 비슷해진다는 것을 알 수 있을 겁니다. 그러므로 과도하게 적은 Radius 를 잡으면 감쇠가 이상한 형태로 나오는 결과를 산출하게 됩니다.

잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요


[ PBR 이란 무엇인가 ] 7. Light intensity 설정

개요

지금까지는 광도측정( photometry ) 관점에서 빛을 살펴 봤습니다. 사실 보면서 이게 "실무랑은 무슨 관계가 있나" 라는 의문을 가지시는 분들이 꽤 있었을 겁니다. 그러므로 딱히 이론적인 부분에 관심이 있는 분이 아니라면 지루하실 수도 있었을 겁니다. 이번 장부터는 앞에서 언급한 이론들을 UE4 를 사용해 실제로 적용해 보도록 하겠습니다.

[ 광원의 밝기( 광속 ) ] 에서는 광원의 밝기는 전방향으로 향하는 빛의 총량이라고 했습니다. 그리고 [ 조도( illuminance )측정 ] 에서 조도라는 것은 서피스에 들어 온 빛의 양을 의미한다고 했습니다. 그런데 PBR 로 오면서 조명의 개념이 약간 확장되었습니다. Area light 라는 개념이 생긴 것이죠. 말 그대로 범위를 가진 광원에서 나오는 빛을 의미합니다. 반대로 punctual light 는 point light, spot light 등 볼륨을 가지지 않는 기존 방식의 조명들을 의미합니다. 사실 우리가 매일 접하게 되는 실세계 조명들은 그림1 처럼 거의 다 area light 라 봐야겠죠. 

그림1. 실세계 조명들. 출처 : [1].

"Punctual" 이라는 것은 "시간을 엄수하는", "( 시간에 맞게 ) 정확한" 등의 뜻을 가지고 있습니다. 이것을 왜 area 의 반대 개념으로 사용하고 있는지는 저도 잘 모르겠습니다. Max, Maya, Frostbite 같은 프로그램/엔진들에서는 punctual light 를 photometric light 에 포함시켜 이야기하기도 합니다. 그림 2 에서 보이듯이 광원이 복잡한 IES( Illumination Engineering Society, 조명 공학회 ) profile 을 가지지 않는다면, 그냥 point light 나 spot light 가 되겠죠. 그런 것을 그냥 Simple/Isotropic profile 이라 부르는 것 같습니다. 

어쨌든 punctual light 를 사용하게 되면, ( GI 를 고려하지 않는다고 가정할 때 ) 한 광원에서 나오는 빛은 한 서피스에 한 번만 도달합니다.

그림2. Punctual light. 출처 : [1].

Puncutal light 와는 다르게 area light 는 그림3 에서 볼 수 있듯이 한 서피스에 대해 여러 번 빛을 방출하게 됩니다.

그림3. Area light. 출처 : [1].

여러 분은 그림2 의 punctual light 와 그림3 의 area light 를 보면서, "각각의 광원마다 빛의 세기( 밝기 )를 설정하는 방식이 달라야 한다" 고 느끼셨나요?

네 당연히 달라야 합니다. 왜냐하면 puncutal light 는 광도( luminous intensity, cd ) 관점으로 설정해야 하며, area light 는 광속( luminous flux, lumen ) 관점으로 설정해야 하기 때문입니다. Puncutal light 의 경우 특정 방향으로 가는 빛만이 서피스에 도달하므로, 전체 빛의 양을 의미하는 광속을 설정해서는 안 되겠죠. 광도와 광속의 차이가 이해가 안 가시면, [ 광원의 밝기( 광속 ) ]을 보고 오세요.

아티스트가 여러 단위를 써 가면서 이런 부분을 제어하는 것은 좀 스트레스를 받는 일이겠죠. 하지만 punctual light 의 경우에는 빛을 세기를 광도 단위로 설정하는 것이 좀 더 직관적일 수는 있습니다. 그냥 "얼마만큼의 빛이 특정 방향으로 전달되어야 해"라고 생각하는 것이 편하니까요. 그래서 프로스트바이트의 경우에는 단위를 직접 설정( 광속, 광도, 조도 )할 수 있도록 하고 있더군요[1]. CryEngine 3.6 같은 경우에는 조도 단위로 설정하도록 하고 있구요.

하지만 빛의 세기를 일괄적으로 광속 단위로 설정하더라도 이를 광도나 조도 단위로 변환하는 것은 엔진 내부에서 수행될 수 있습니다. 그러므로 이에 대해서 크게 걱정할 필요는 없습니다.

점광원의 광속을 기준으로 광도를 계산하는 경우를 생각해 봅시다. 구의 겉면적이 4π 이므로, 구의 단위 입체각을 통해서 나가는 빛의 양은 식1 과 같습니다.

식1. 점광원의 광도 계산.

그러면 점광원을 위해 설정한 설정한 광속( luminous flux )을 I 라 할 때( 원래는 φ( phi [fai] -- 'f' 발음 잘 안되니 '파이' 와 구분하기 위해 '화이' 라고 읽거나 그리스 발음인 '피' 라고 읽기도 합니다 )로 표기해야 하는데 여기에서는 그냥 I 로 표기하겠습니다 ), 조도( illuminance ) E 는 식2 와 같습니다.

식2. 점광원의 조도 계산.

식2 에서 곱하기 앞쪽은 이해하기 어렵지 않습니다. 방금 이야기한 부분이니까요. 그런데 뒤의 식이 갑자기 붙어 있으니 머리가 살짝 아파지실 겁니다. r 은 광원에서 서피스까지의 거리이고, θ 는 광원과 서피스 노멀( normal )과의 각도입니다.  [ 조도( illuminance )측정 ] 에서 조도에 영향을 주는 부분은 거리 및 기울기라고 이야기했던 걸 기억하시나요?

광원과 서피스의 거리가 멀어지면 빛의 양이 1/r2 으로 줄어들고, 기울기가 달라지면 빛의 양이 cos(θ) 만큼 줄어듭니다. 이럼 감쇠항들을 식에다가 넣으면 식2 의 형태가 되는거죠.

공식이 나오니 좀 당황스럽겠지만, 차분하게 생각해 보세요. 앞의 시리즈에서 언급했던 것을 공식으로 나타낸 것 뿐입니다

주의 : 아래 그림에서 한 점이라고 표현했는데, 단위 입체각을 의미합니다. 그림을 수정해야 하는데 귀찮아서 그냥 둡니다.

그림4. Illuminance 공식의 구성. 주의 : 그림에서 한 점이라고 표현했는데, 단위 입체각을 의미합니다. 그림을 수정해야 하는데 귀찮아서 그냥 둡니다.

그런데 실제 UE4 에서의 설정은 어떨까요?

이노무 언리얼!!!

지금부터는 UE4 를 까는 이야기를 할 겁니다. 가끔 UE4 구현을 보면 "이게 뭔 삽질인가" 라는 느낌이 들 때가 있습니다. 뭔가 구현은 해 놨는데 엉망으로 해 놨다는 느낌입니다. Frostbite 보다 그래픽스 품질이 떨어지는 것은 어쩔 수 없는 것 같습니다. 제대로 검증도 안 하고 구현하는듯...

어쨌든 본론으로 들어가, UE4 의 경우에는 광속 단위로 빛의 밝기를 설정하고 있습니다. 뭐 여기까지는 OK 입니다. Punctual light 의 경우에는 이를 엔진 내부에서 광도로 변환해 주면 되기 때문입니다.

하지만! 버뜨! 아놔! UE4 는 4π 로 광속을 나누는 것을 빼 먹었습니다. 게다가 미친 삽질까지 하나 더 합니다. 4.9 버전에서 "Correction for lumen units" 라는 작업을 한 것 같습니다. Inverse square falloff( 거리 제곱분의 1 로 감쇠 )를 사용하는 경우에, 빛의 밝기에 16 을 곱합니다.

16 이라는 속임수 값은 point light 가 거리의 제곱분의 1 로 감쇠될 때 기본 노출( exposure )에서 합리적인 밝기로 보일 수 있도록 하기 위해 추가한 X 같은 거야. Point light 감쇠를 위해 1/(4pi) 는 계산 안 해.

- Brian Karis, Epic Game, Inc.

- 출처 : UDN.

정말 할 말이 없습니다. Physically based 인데 완전 지 맘대로 값을 설정하고 있습니다. 에너지 보존 법칙을 위배한 데다가, 임의의 값을 곱하기까지 합니다. 이것 때문에 혼란스러워하는 사람들이 있는데, 그냥 씹어버립니다.

우리는 당신이 검토하고 있는 부분에 대해서 그리 많은 노력을 들이지 않았어. ( 중략 ) 요걸 좀 명확하게 정리하는 시간을 가지고 싶은데, 내 할 일 목록에 있는 다른 것들을 처리하느라 바뻐.

- Brian Karis, Epic Games, Inc.

- 출처 : UDN.

벌써 4.17 이 다가 오고 있는데, 검토는 안 하나 봅니다.

이 때문에 촛 불의 밝기 12.57( 혹은 15 ) 을 설정해도 촛불같지가 않습니다. 물론 UE4 는 100 이 1m 이므로, 1257 을 설정해 주긴 해야겠죠. 그렇다고 해도 촛불같지 않습니다.

그리고 감쇠 거리 설정을 어떻게 해야 할지 감을 잡기가 힘들 겁니다.

그럼 어떻게?

이런 상황에 대응하는 세 가지 자세가 있습니다.

    1. 현실을 인정하고, 감으로 값을 때려 넣는다.
    2. 현실을 인정하고, 적절한 값을 넣는다.
    3. 현실을 부정하고, 제대로 고친다.

뭐 1 번이야 알아서 하고 계실테고, 2 번과 3 번에 대해서 이야기하도록 하겠습니다.

현실 인정 -> 적절한 값 넣기

먼저 2 번 자세입니다. 앞에서 UE4 가 4π 로 나누는 것을 누락시키고 16 을 곱했다고 했습니다. 그러므로 값을 넣을 때 한 번 더 계산을 해 주는거죠.

내가 어떤 차트에서 I 루멘이라는 값을 가지고 왔다고 칩시다. 그러면 입력할 때 거리 팩터를 곱해주면 100 * I 루멘이 됩니다. 이걸 엔진 내부에서 다시 16 을 곱해서 최종적으로 1600 * I 루멘이 되죠. 그러면 식3 과 같이 현재값과 기대값 사이의 변환을 할 수 있습니다.

식3. 현재값과 기대값의 변환. 현재 넣는 값에 0.004973 을 곱해주면 됩니다. 물론 감쇠거리 계산도 적절히 해야겠죠.

현실 부정 -> 제대로 고치기

3 번 자세입니다. 그냥 제대로 고치는 겁니다. 물론 엔진 프로그래머가 고쳐줘야겠죠. [2] 번과 동일하게 고치면 별 문제가 없을 것이라 봅니다.

그림5 : 다양한 광속( luminous flux, luminous power ). 출처 : [2]. 태양의 경우에는 거리감쇠가 없으므로 바로 조도( lux )로 표시. UE4 에서는 거리 팩터( 100 = 1m )를 적용해 각각 1500, 120000, 260000 으로 넣어 줘야 합니다. 물론 그냥 루멘값을 넣으면 내부적으로 100 을 곱해주는 것도 방법이겠죠( 그림6 참조 ).

그러면 여러 차트에 있는 값들을 그냥 가져다 쓸 수도 있고, 감쇠 거리도 계산하기 편해집니다. 예를 들어 10 미터까지 도달하는 라이트를 설정하고 싶다면 제곱하면 됩니다. 즉 10 X 10 = 100 루멘을 설정하는 거죠. 반대로 루멘을 통해 감쇠거리를 계산하고 싶다면 root 를 씌우면 됩니다( 제곱근을 구하면 됩니다 ). 앞의 예로 보면 100 루멘짜리 라이트는 10 미터를 가는 것이죠.

그림6. UE4 엔진 코드를 수정하고, 두 개의 촛불을 넣음( 천장에 있는 등불도 촛불 밝기 ). 각각 15 루멘( 촛불 하나의 밝기 ) 설정. 15 루멘 입력하면 100 / ( 4 * pi ) 를 자동으로 적용해서 칸델라로 변환합니다. Eye-Adaptation 이 완전히 적용된 상태입니다.

그림7. 비교 자료. 실제 촛불 하나의 느낌. 출처 : DevianArt.

정리

현재 UE4 엔진은 조도계산 시에  4π 로 나누는 것을 누락시키고 16 을 곱했습니다. 그래서 외부 차트의 값을 가져다 쓰기도 애매하고 감쇠거리를 설정하기도 애매합니다. 뭘 기준으로 계산을 해야 할지 부정확하기 때문입니다.

게다가 directional light, punctual light, area light 의 라이트 세기 설정 방식이 전부 다릅니다. 그냥 이쪽 프로그래밍한 사람 맘대로입니다. 정말 한 대 쥐어 박고 싶군요.

개인적으로 PBR 을 도입하는 데 있어서 중요한 부분이 "단순성과 일관성" 에 있다고 봅니다. 아티스트가 값을 결정하는 데 있어서 의구심을 가질만한 요소가 적어야 한다고 봅니다. 그리고 아티스트가 외부 자료들을 보고 쉽게 자신만의 설정값 데이터베이스를 구축할 수 있어야 하겠죠.

그러므로 엔진을 고치든지 제대로 된 값을 계산해서 넣든지 해야 할 것이라 생각합니다. 아니면... 감쇠거리로부터 루멘을 계산해 주는 유틸리티를 추가하는 것도 방법이겠죠. 일반적으로 아티스트들에게는 일정 거리까지 도달하는 빛을 만드는 것이 목적일테니 말이죠.

참고 자료

[1] Moving FROSTBITE to PBR, Sebastien Lagarde & Charles de Rousiers.

[2] Moving Frostbite to Physically Based Rendering 3.0, Sebastien Lagarde & Charles de Rousiers.

잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요.


[ PBR 이란 무엇인가 ] 6. 휘도( luminance ) 측정

휘도

오늘은 드디어 빛이 여행하는 최종단계를 다룹니다. 광원에서 방출되어 표면에 도달한 빛은 표면의 재질( 속성 )에 따라 여러 방향으로 반사됩니다. 그리고 나서 그 빛 중의 일부는 우리의 눈에 도달하게 됩니다.

그림1. 조도와 휘도의 관계.

여러 분이 인터넷에서 광속( luminance flux ), 조도( illuminance ), 휘도( luminance ) 등에 대해서 검색을 하게 되면, 휘도에 대해서 검색했을 때 가장 많은 자료들이 나오는 것을 확인할 수 있습니다. 인간은 눈에 들어 온 빛만을 인지할 수 있기 때문에 당연한 것이겠죠. 그만큼 중요하며 대부분의 쉐이딩( shading ) 이론들이 이 휘도와 관련이 있습니다.

휘도는 다음과 같이 정의됩니다.

휘도는 특정 방향으로 이동하는 단위 면적당 광도( luminous intensity )를 측정한 것입니다. 그것은 특정 영역에서 방출되거나 반사되어 주어진 입체각 안에 들어 온 빛의 양을 의미합니다. 휘도의 국제 단위는 제곱미터 당 칸델라( candela per square meter( cd/m2 ) )입니다.

뭐 어렵게 써 놨지만 그냥 그림2 처럼 눈에 들어 온 빛의 양을 측정하는 것입니다. 개념 설명을 위주로 할 것이기 때문에 여기에서 공식은 자제하겠습니다. 사실 이 휘도라는 것은 매우 복잡하기 때문에 모델도 다양하고 여기에서 바로 다루기에는 어려운 부분이 있습니다. 앞으로의 재미로 남겨 두기로 하죠.

그림2. 특정 면적을 가진 표면에 대한 조도와 휘도.

거대 표면( macro-surfce )과 핀홀( pin-hole ) 카메라

지금까지 우리는 조도와 휘도를 이야기할 때 매우 큰 면적을 가진 표면과 큰 면적을 가진 눈을 중심으로 이야기했습니다. 하지만 그러한 관점에서 설명하면 이해하기가 어렵고 실제로 계산이 복잡해집니다. 그러므로 이쯤부터는 미세 표면과 핀홀 카메라를 중심으로 이야기를 하도록 하겠습니다.

만약 우리가 관심을 가지는 표면의 크기가 우리가 겨우 인지할 수 있을만한 점에 가깝다고 가정해 봅시다. 점에 가깝다는 것이 중요합니다. 완전히 점은 아닙니다. 이것을 거대 표면( macro surface )이라고 부르는데요, 여기에 이의가 있는 분들이 있을 수 있습니다. "Macro" 는 "거대한" 이라는 뜻인데, 점에 가깝다고 해 놓고서는 거대하다고 이야기하니 짜증나실테지만, 이는 "Micro" 와 대비되는 상대적인 개념입니다. 우리가 점처럼 보고 있는 면적보다도 더 눈에 잘 안 보이는 매우 작은 면적을 가진 표면을 미세 표면( micro surface 혹은 micro facet ) 이라 부르고 있기 때문에, 상대적으로 큰 것을 거대 표면이라 부른 것 뿐입니다.

PBR 이 도입되기 이전에는 거대 표면을 대상으로 라이팅을 계산했죠. 이에 대해서는 나중에 다루도록 하겠습니다. 어쨌든 앞으로 "점에 가까운 표면"을 그냥 "표면" 이라고 부르고 더 작은 표면을 "미세 표면" 이라고 부르도록 하겠습니다.

거대표면과 미세표면. 우리 눈에는 거대 표면마저 점처럼 보입니다. 출처 : [2].

그런 관점에서 보면 특정 표면에 들어 빛들의 각도차이가 거의 없으니 그냥 선처럼 보이겠죠. 그러면 조도와 휘도의 관계는 그림3 처럼 표현될 수 있습니다.

그림3. 점에 가까운 면적을 가진 표면에 대한 조도와 휘도.

여기서 말하고자 하는 것은 무엇일까요? 휘도가 관심을 가지는 것은 오직 눈에 들어 온 빛의 양이라는 점입니다. 그림2 의 관점에서 바라보든 그림3 의 관점에서 바라보든 차이는 없습니다. 그림2 같은 경우에는 그림3 보다 더 많은 점들을 대상으로 하고 있는 것일 뿐이죠. 사실 그래픽스 영역에서는 그림3 의 관점을 가지고 조도와 휘도 관계를 계산하는 것이 좀 더 편하긴 합니다.

하지만 아직도 복잡합니다. 눈이 면적을 가지고 있다고 가정하고 있기 때문에 들어 오는 빛을 계산하기도 힘들죠. 그래서 대부분의 실시간 그래픽스에서는 바늘구멍 카메라 모델을 사용합니다. 그림4 처럼 눈에 면적이 있는 것으로 보는 것이 아니라 그냥 점으로된 구멍이 있는 것처럼 생각하는 것입니다. 

그림4. 핀홀 카메라 모델. 출처 : Pinhole camera(DIY/homemade).

그러므로 모든 빛은 한점에 수렴한다고 가정하죠. 이 경우, 눈으로 들어 온 빛들의 각도 차이가 거의 없으므로 선에 가깝게 표현되겠죠. 그러면 조도와 휘도는 그림5 의 관점에서 설명됩니다.

그림5. 점에 가까운 면적을 가진 표면과 점에 가까운 면적을 가진 눈에 대한 조도와 휘도.

우리가 보통 실시간 그래픽스 이론에서 보고 있는 눈, 표면, 빛의 관계는 그림5 의 표현에 가깝습니다.

왜 조도와 휘도를 구분하나요

어떤 표면에 들어 온 빛은 사람의 눈에 모두 들어 오지 않습니다. 왜냐 모든 표면은 빛을 흡수( Absorbtion ), 반사( Reflection ), 투과( Transmission )시키기 때문이죠. 게다가 이 반사 성분은 확산반사( diffuse reflection ) 성분과 정반사( specular reflection, 거울면 반사 ) 성분으로 나뉩니다.

출처 : Waves, KaiserScience.

이 중에서 사람의 눈에 들어 올 수 있는 성분은 반사와 투과입니다. 그리고 우리가 앞으로 다루게될 모든 렌더링 이론들은 대부분 이 두가지 성분과 관련이 있습니다. Albedo( 표면 반사율 ), BRDF( Bidriectional Reflectance Distribution Function, 양방향 반사도 분산 함수 ), BTDF( Bidirectional Transmittance Distribution Function, 양방향 투과도 분산 함수 ) 등은 그림6 처럼 표면에 들어 온 빛이 얼마나 반사되고 투과되는지를 함수로서 표현한 것들입니다.

그림6. BRDF 와 BTDF. 출처 : [3].

그리에서 여기에서 산란( Scattering )이라는 용어가 나오는 것이 약간 불편한 분들이 있을 것 같아서 부가설명을 하자면, 산란이라는 것은 쉽게 이야기하면 전자기파가 모종의 이유로 자신의 방향으로 가지 못하고 다른 방향으로 가는 현상을 의미합니다. 반사와 투과 등의 모든 개념을 파동 관점에서 설명한 것이죠. 자세한 것은 시리즈의 뒷 부분에서 자세히 설명하도록 하겠습니다.

정리

표면에 들어 온 빛( 조도 )은 전부 눈( 휘도 )으로 들어 오지 않습니다. 그 이유는 표면이 빛을 흡수, 반사, 투과시키기 때문입니다. 사람이 눈으로 볼 수 있는 빛은 반사되거나 투과된 빛들입니다. 얼마만큼의 빛이 반사되고 투과되었는지를 결정하는 함수들이 Albedo, BRDF, BTDF 입니다. 대부분의 렌더링 이론들은 이와 관련이 있습니다.

지금까지는 빛과 그것의 양을 계산하는 것과 관련한 기본 개념 및 용어들을 설명하느라 시간을 보냈습니다. 마치 활용할 데가 없는 수학 공식을 배우듯이 지루하셨을거라 생각을 하지만, 이러한 용어들은 앞으로 자주 반복해서 나올 것이기 때문에 글을 읽느라 보낸 시간이 아깝지는 않을 것이라 기대해 봅니다. 

다음 시간부터는 본격적으로 PBR 에 대한 이야기를 풀어 나가보려고 합니다. 가급적이면 실제 예제들을 중심으로 렌더링 결과를 비교한다든가 하는 식으로 진행하려고 생각하고 있습니다.

참고 자료

[1] Luminance, Wikipedia.

[2] Microfacet Modles for Refraction through Roufh Surfaces, Bruce Walter, Stephen R. Marschner, Hongsong Li, Kenneth E. Terroance.

[3] Bidirectional scattering distribution function, Wikipedia.

주의 : 잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요.


[ PBR 이란 무엇인가 ] 5. 조도( illuminance ) 측정

조도

오늘은 조도에 대해 이야기하고자 합니다. 여러분은 [ 2. 조도와 휘도 ] 에서 조도와 휘도의 개념에 대해 공부했습니다. 여기에서는 조도와 휘도를 어떻게 측정하는지에 대해서 다루도록 하겠습니다. 하지만 수학적인 계산보다는 단위와 개념을 이해할 수 있도록 하는데 치중했기 때문에, 이를 구현하고자 하는 사람에게는 좀 부족한 글이 될 수 있습니다.

조도( illuminance )라는 것은 조명이 비추는( illuminate ) 빛이 얼마나 표면( surface )에 도달하느냐를 측정한 값입니다.

이를 광속 개념을 통해 정의하면 다음과 같습니다.

조도는 단위 면적( 제곱미터, m2 )당 광속( luminous flux )입니다. 이는 입사광이 표면을 얼마만큼 비추고 있는지를 측정하는 것입니다[1].

( [ 4. 광원의 밝기( 광속 ) ] 에서 광속( luminous flux, luminous power )은 광원이 방출하는 전체 빛의 양이라고 했습니다. )

말이 좀 어렵나요? 이럴땐 그림을 봅시다.

어떤 표면이 있고 거기에 빛을 비춘다고 해 봅시다. 그러면, 그림1 에서 보이듯이, 그 표면의 1m2 내에 들어 온 빛의 양이 조도이며, 그것을 1 럭스( lux, lx )라고 합니다.

림1. 조도. 단위 면적당 광도.

광속의 단위는 루멘( lumen, lm )이고 단위 면적은 제곱미터( square meter, m2 )이므로 럭스는 다음과 같이 계산됩니다.

식1. 럭스 계산.

조도와 거리( 감쇠 )

그런데 눈치가 빠르신 분들은 뭔가 문제가 있다는 것을 깨달으셨을 겁니다. 실세계에서는 빛과 광원간의 관계가 위의 그림에 있는 것처럼 편리하게 빛과 1 미터 떨어져서 존재하는 것이 아닙니다.

우리는 [ 3. 빛의 감쇠 ] 에서 빛의 양은 거리가 멀어질 수록 감쇠하게 되어 있으며, 1 / distance2 의 비율로 감쇠한다고 배웠습니다. 

그렇기 때문에 조도를 계산할 때는 거리를 고려해야 합니다.

구의 중심이 광원이라고 가정해 봅시다. 반지름이 r 일 때 r2 만큼의 겉면적을 커버하는 원뿔형의 입체각을 1 스테라디안이라 한다고 했습니다. 여기에서 r 을 오브젝트와의 거리라고 가정해 봅시다. 그리고 오브젝트의 면의 방향( 노멀, normal )은 구의 중심을 바라보고 있다고 가정해 봅시다.

만약 r 이 1 m이라면 면적은 1 m2 이고 식1 에서 나온 것과 같은 결과를 냅니다. 하지만 r 의 값이 1 보다 커질수록 r2  만큼 넓은 면적을 커버해야 하며 1 / r2 만큼 받는 빛이 약해지겠죠. 반대로 r 이 1보다 작아지면 더 좁은 면적을 커버해야 하며 빛이 강해지겠죠. 이를 좀 더 쉽게 이해할 수 있도록 그림2 에 평면도로 표현해 보았습니다.

그림2. 거리에 따른 조도의 변화. 중간의 면( 붉은색 )은 빛과 1 스테라디안의 입체각을 이룸.

그림2 를 보면서 좀 헷갈리는 사람이 있을 수 있습니다. 가장 좌측의 입체각이 크고, 가장 우측의 입체각이 작습니다. 1스테라디안당 N 개의 광자를 쏘았다고 하면, 가장 좌측은 N 개보다 많은 광자를 받았고, 가장 우측은 N 개보다 적은 광자를 받은 것입니다.

조도와 기울기

눈치가 빠른 분들은 다른 문제도 있다는 것을 깨달았을 것입니다. 실세계에서는 면이 광원을 마주보고 있는 경우가 거의 없습니다.

조도를 계산할 때 고려해야 할 다른 부분은 면의 기울기입니다. 면적이 같은 두 개의 평면이 존재할 때, 하나는 면의 노멀이 빛 방향과 수직이고, 다른 하나는 수직이 아니라고 합시다. 이 경우 수직이 아닌 면은 그림3 처럼 빛을 덜 받게 됩니다.

그림3. 기울기에 따른 조도의 변화.

이러한 기울기에 따른 차이를 고려해서 조도의 양을 계산하는 것이 램버트 코사인 법칙( Lambert's Cosine Law )입니다.

그림4. 램버트 코사인 법칙. 출처 : Lambert's Cosine Law, Ocean Optics.

사실은 이 코사인 법칙을 증명( ? )하려 했는데, 너무 어려운 글이 될 것 같아서 생략했습니다. 가능한한 쉽게 쓰려고 하는데 자꾸 프로그래머 본능이 꿈틀대네요.

정리

조도라는 것은 표면에 들어 온 빛의 양을 의미합니다. 이것을 시리즈의 앞 부분에서 언급한 광도측정 단위들을 사용하면, "단위 면적당 광속"이라고 표현할 수 있습니다. 이 조도의 단위는 럭스( lux )이며 lux 혹은 lx 로 표기합니다.

조도는 면과 광원의 거리 및 기울기에 영향을 받습니다. 거리에 의한 영향은 빛의 감쇠 공식에 의해 계산되며, 기울기에 의한 영향은 램버트 코사인 법칙에 의해 계산됩니다.

참고로 태양빛의 경우에는 거리에 의해 감쇠되지 않는다고 가정합니다. 모든 빛이 평행하게 들어오고 있다고 가정하기 때문이죠. 다시 말씀드리지만 거리가 멀어졌을 때 감쇠되는 것은 커버해야 할 면적이 늘어나기 때문이지 단순히 거리가 늘어났기 때문이 아닙니다. 태양빛은 평행하다는 가정을 깔아 버리면, 거리가 멀어지더라도 커버해야 할 면적에 변화가 없기 때문에 감쇠가 되지 않는 것입니다.

참고자료

[1] Illuminance, Wikipedia.

 

잘못된 내용이 있을 수 있으므로 이상하면 참고자료를 확인하세요.


[ PBR 이란 무엇인가 ] 4. 광원의 밝기( 광속 )

개요

3. 빛의 감쇠 ] 에서는 좀 지루한 수학과 기하에 대해서 이야기했습니다. 거리, 호도( radian, 단위 : rad ), 입체각( solid angle, steradian, 단위 : sr ) 등에 대해서 이야기한 것은 바로 오늘의 주제인 빛의 측정단위에 대해서 이야기하기 위함이었습니다.

노파심에 다시 이야기하지만 우리는 방사측정( radiometry )가 아니라 광도측정( photometry )의 관점에서 빛을 측정하는 단위에 대해서 이야기할 것입니다. 광도측정은 빛을 구성하는 다양한 파장 중에서 가시 파장에 대해서 다루는 측정방법입니다.

지금부터는 약간의 수식이 나올 수 있습니다. 하지만 원리를 이해한다면 크게 어렵지 않을 것이라 생각합니다. 이해가 안 가면 질문을 주세요. 모르는 것이 부끄러운게 아닙니다. 알려고 하지 않는 것이 부끄러운거죠. 지금은 어렵게 느껴지지만 가면 갈수록 익숙해질 것이고, 지금 고민하고 공부한 것들이 나중에는 큰 차이를 만들어낼 것입니다.

광선속( 광속, Luminous Flux, Luminous Power )

광선속( 光線束 ) 혹은 광속( 光束 )이라는 것은 속도를 의미하는 것이 아닙니다. 빛 광( 光 )과 묶을 속( 束 )입니다. 말 그대로 빛다발이죠. 빛의 속도를 의미하는 광속( 光速 )이 아닙니다. 요새는 사람들이 한자를 잘 모르니 영어로 표현하면, luminous 는 "빛나는" 이란 뜻이고 flux 는 "흐름" 이라는 뜻입니다.

일단 단어의 구성은 그렇구요, 광속이란 단위시간에 광원에서 나오는 빛( 가시광선 )의 총량입니다. Radiometry 관점에서 보면 Radiant Flux( 방사속 ) 라는 용어가 이에 대응됩니다.

그림1. 광속은 광원에서 나오는 빛의 총량입니다. 출처 : Watts, Lumens, Candles and Lux.

여러분이 어떤 조명을 보고 "저 조명의 밝기는 XX 입니다" 라고 말할 때 사용하는 것이 바로 광속입니다. 단위는 루멘( lumen )이죠. 루멘은 라틴어로 빛이라는 뜻이며, 기호로는 lm 을 사용합니다.

요즘 조명기구 회사에서는 밝기를 표기할 때 루멘( lm )으로 표기합니다. 기존에는 와트( 일률, W ) 단위를 많이 표기했는데, 와트는 에너지를 얼마나 소비하느냐를 의미하는 것이지 얼마나 밝냐를 의미하는 것이 아니기 때문입니다.

조명 회사의 LED 제품 소개의 예. 출처 : CREE.

그렇다면 루멘은 어떻게 결정되는 것일까요? ( 이것과 관련한 글이 없어서 저의 추측으로 소설을 써 봤습니다. )

우리는 아주 옛날부터 초( candle )라는 것을 사용해서 빛을 비춰왔습니다. 그래서 과학자들은 촛불을 기준으로 해서 빛의 밝기를 측정하려고 한 것 같습니다. 이러한 관점에서 보면 촛불이 방출하는 전체 빛의 양을 1 루멘이라고 하는 것이 편리하겠죠.

하지만 LED 처럼 빛이 방출되지 않는 영역이 존재하는 경우도 있습니다. 게다가 일반적으로 측정기를 광원을 완벽하게 둘러싼 형태로 만들어내기가 어렵습니다. 보통 한 방향에서 일정 영역만큼을 측정한 값을 가지고 전체 결과를 추정하는 경우가 많죠. 그렇기 때문에 촛불의 빛의 양을 1 루멘이라고 하면, 다른 광원들의 빛의 양을 측정하기가 조금 곤란할 것입니다.

뭔가 기준이 되는 단위가 필요했을 것이고, 1 sr( 스테라디안을 ) 기준으로 삼았을 것입니다.

만약 1 sr 만큼의 입체각으로 방출되는 빛의 양을 알게 된다면, 빛을 비추지 않는 영역은 배제하고 빛을 비추는 영역만을 모아서 빛의 양을 수집하는 것이 쉽겠죠.

[2]에서는 광도( luminous intensity )를 다음과 같이 정의하고 있죠.

광도는 점 광원에서 특정 방향으로 단위 입체각( solid angle, 1 스테라디안 )당 방출되는 광속( luminous power )입니다. 광도의 단위는 칸델라( candela, cd )입니다.

그림3. 광도( luminous 칸델라. 출처 : Watts, Lumens, Candles and Lux.

이를 수식으로 표현하면 식1 과 같습니다. 여기에서 광도를 X, 광속을 Y, 빛을 방출하는 전체 입체각을 Z 라 하겠습니다 :

식1. 칸델라의 정의. 1 스테라디안당 광속.

점광원 같은 경우에는 전방향으로 빛을 방출하기 때문에 단위 입체각은 1/4pi 가 됩니다( 단위구의 최대입체각이 4pi 입니다 ). 그러므로 점광원에서 광도( 칸델라 )를 구하는 식은 식2 와 같습니다.

식2. 점광원에서의 광도 계산.

광속( 루멘 )은 다음과 같이 정의됩니다.

식3. 루멘의 정의. 광도 X 입체각.

만약 점광원이라면 그것의 광속은 다음과 같이 계산되는 거죠.

식4. 점광원에서의 광속 계산.

뭔가 순환논리같다는 생각이 듭니다. 여기에서 엄청나게 헷갈리는거죠. 광속은 칸델라를 사용해서 정의되는데, 칸델라는 광속을 사용해 정의됩니다.

이에 대한 자료는 지금까지 찾지 못했는데요... 그래서 그냥 소설을 써 보겠습니다( 제 친구 햄짱과 같이 쓴 소설입니다 ).

과학자들은 처음에 촛불을 1 루멘이라고 불렀다가, 위에서 언급했던 것처럼 전방향으로 빛을 방출하지 않는 광원이 나오면서, 전방향에서 방출한 빛의 양을 기준으로 삼는 것은 어렵다고 생각했을 것입니다. 그래서 특정방향으로 일정 범위( 단위 입체각 ) 안에서 방출되는 빛의 양을 기준으로 삼아야겠다는 생각을 했을 것입니다. 그리고 그것을 빛의 양을 측정하는 기본 단위인 광도( luminous intensity )라 정의했을 것입니다.

그런데 촛불의 광속이 1 루멘이라고 하면, 그것의 광도는 1 보다는 작은 소수점 아래 단위의 값이 될 것입니다( 구의 전방향을 커버하는 면적보다는 1 스테라디안이 커버하는 면적이 훨씬 적겠죠 ) . 이를 피하기 위해서 최소단위인 광도를 1 칸델라로 맞췄을 것이라고 생각합니다. 

머리가 아파 보이지만 1 칸델라는 국제 표준으로 정의된 빛의 양입니다. 1 리터( l )라든가 1 그램( g )이라든가 하는 정해져 있는 양입니다. 이제 칸텔라가 뭔지 알게 되었으니 초의 광속( 루멘 )을 계산해 보죠. 초가 전방향으로 빛을 방출한다고 하면, 그것의 입체각은 4π 스테라디안입니다( 반지름이 r 인 구의 겉면적이 4πr2 이고 1 스테라디안은 r2 만큼의 겉면적을 커버하는 입체각이므로 구의 전체 입체각이 4π 스테라디안이 되는 것입니다 ).

그러면 이제 촛불의 밝기( 광속 )를 계산해 볼까요?

식3. 촛불의 광속 계산.

실제로 촛불 하나의 광속은 12.57 루멘입니다.

정리

특정 방향으로 1 스테라디안 영역에서 방출된 촛불의 빛의 양을 광도( luminous intensity )라 하면 단위는 칸델라( candela, cd )입니다.  1 스테라디안( steradian, sr ) 범위에서 방출된 칸델라를 루멘( lumen, lm )이라 합니다. 루멘을 사용해 광원의 전체 빛의 양을 측정한 것을 광속( luminous flux, luminous power )이라 합니다.

참고자료

[1] Lumious flux, Wikipedia.

[2] Candela, Wikipedia.

주의 : 잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요.


[ PBR 이란 무엇인가 ] 3. 빛의 감쇠

개요

시리즈의 3 번째입니다. 지난번에 [ 2. 조도와 휘도 ] 에서 방사측정( Radiometry )과 광도측정( Photometry )의 차이에 대해 언급했습니다. 기억이 잘 안 나시는 분들을 위해 복습하자면 방사측정은 빛의 모든 파장 영역의 에너지( power )를 측정하는 것이고, 광도측정은 빛의 가시 파장 영역이 밝기( brightness )를 측정하는 것입니다.

그런데 모든 물리단위들은 기준이라는 것이 있어야 합니다. 우리가 물리기반( Physically-based )를 이야기하고 있으니, 당연히 물리적으로 납득할 수 있는 기준과 단위들이 필요하겠죠.

UE4 엔진의 경우에는 포인트/스포트 라이트의 세기를 설정하는 기준 단위가 루멘( lumen )이라고 이야기하고 있습니다[1]. 세기( intensity )를 밝기( brightness )라고 표현하기도 합니다.

그림1. UE4 에서의 빛의 세기를 설정하는 속성. 루멘단위.

요새 다른 PBR 엔진들도 루멘을 사용하는 추세이죠. 이렇게 된 이유는 광원의 세기를 아티스트의 기분에 따라 설정하지 말고 어떤 기준을 잡고 설정하라는 의미일 것입니다. 그래서 아티스트들이 루멘이 무엇인지 이해할 필요가 있습니다. 루멘이 무엇인지 이해하는 것은 빛에 대해서 더 깊게 이해할 수 있는 기반을 제공할 것입니다.

이 문서에서는 어떤 조명( 광원 )의 광속( luminous flux ), 광도( luminance intensity ), 조도( illuminance ), 휘도( luminance )가 어떤 의미인지 이해하기 위한 선행학습 과정에 대해 다룰 것입니다. 여기에서부터는 약간의 기하와 산수가 나오기 때문에 조금 짜증나실 수는 있습니다. 하지만 여러분은 이 개념들에 대해서 무작정 외우려고 하실 필요는 없습니다, 어떤 원리인지를 이해하고 단위만 잘 기억하시면 됩니다.

그렇게 어려운 내용은 아니니 차분히 읽어 보시면 이해하실 수 있을 거라 생각합니다.

빛은 왜 감쇠할까요?

일반적으로 우리는 빛이 감쇠( attenuation )한다고 알고 있습니다. 강한 빛도 멀리 갈 수록 약해집니다. 여기에서 주의하실 점은 감쇄( reduction )가 아니라 감쇠( attenuation )라는 것입니다. 감쇠는 힘이나 세력이 약해짐을 의미하고, 감쇄는 힘이나 세력이 약해져서 최종적으로는 없어짐을 의미합니다. 지금은 왜 뜬금없이 차이를 이야기할까 싶으시겠지만 뒤에 좀더 설명을 할 것입니다.

빛이라는 것은 전자기파들의 조합이기는 하지만( 파동성 ), 어떤 경우에는 입자들처럼 보일 때가 있습니다( 입자성 ). 입자처럼 보일 때의 빛을 광자( photon, 포톤 )라고 합니다. 그냥 그러려니 하시면 됩니다. 여기에서 더 들어 가면 저도 잘 모르는 양자론에 대해 주절거려야 하기 때문에 더 나아가지는 않겠습니다. 대신에 빛이라는 것을 대충 이런 식으로 이해하시면 됩니다( 정확하지는 않지만 그러려니 하십시오 ).

그림2. 광자의 느낌? 여러개의 전자기파의 묶음을 입자의 관점에서 볼 때 광자라 부릅니다.

어쨌든 광자의 개념에서 빛이 발산하는 모습을 생각해 봅시다.

진공상태라고 가정하면 다른 입자( 먼지, 대기중의 분자들 )들에 의한 산란( 투과, 흡수, 반사 )이 발생하지 않습니다. 그러므로 눈에 들어 오기 전까지는 영원히 직진하겠죠.

그림3. 진공상태에서의 광자의 이동.

눈치가 빠르신 분들은 이 시점에서 한 가지 의문을 가지게 될 겁니다; "그럼 왜 거리가 멀어지면 빛이 감쇠하나요?".

우리는 태양광에 대해서는 평행하게 빛이 도달한다고 생각합니다.

그림4. 태양에서 오는 빛은 평행하다고 가정합니다.

이것이 사실일까요? 그렇지 않습니다. 태양과의 거리는 엄청나게 멀기 때문에 지구에서 사는 사람의 입장에서는 상대적으로 빛이 평행하게 오는 것처럼 느껴질 뿐입니다( 그림5 참조 ). 단지 그래픽스 영역에서는 그 차이가 무시할 수 있을 정도로 의미가 없을 뿐이죠.

그림5. 같은 크기를 가진 물체가 광원에서 멀어졌을 때의 들어 오는 빛들의 각도차이의 변화.

자, 그럼 여러분은 이제 포인트/스포트 라이트와 태양광과의 차이를 아실 수 있습니다. 그냥 거리의 차이입니다. 빛을 받는 오브젝트들의 거리가 너무 가깝기 때문에 각도의 차이가 커집니다. 태양광의 경우에는 엄청나게 많은 광자를 내 뿜고 있으며 태양과 지구와의 거리가 너무 멀기 때문에 거의 평행하게 광자들이 도달합니다. 그래서 우리는 태양광에 대해서 따로 감쇠 거리를 설정하지 않는 것입니다. 하지만 포인트/스포트 라이트들은 내뿜는 광자의 개수가 상대적으로 적으며 가까운 오브젝트가 가까운 거리에서 빛을 받기 때문에 감쇠 거리라는 것이 중요해진 것입니다.

그런데 이 각도가 감쇠라는 것과는 무슨 상관일까요?

세상이 2차원의 평면이고 광원이 점광원이라고 가정합시다. 이 광원은 16 개의 광자를 내뿜을 수 있는 능력을 가졌는데, 광자의 속도가 초당 1 m 라고 가정합시다( 그냥 가정입니다. 광자의 속도는 빛의 속도입니다 ). 1 초 단위로 깜박인다고 가정해 봅시다. 그러면 모든 방향으로 빛을 내 뿜겠죠? 2초 뒤에 광자의 위치는 어떻게 될까요? 시간의 추이에 따라 어떻게 변하는지 그림6 에서 설명하고 있습니다.

그림6. 시간의 변화에 따른 광자의 위치. 2초후에 보면 처음 발사한 광자들은 2 m 를 이동했고, 두번째로 발사한 광자들은 1m 를 이동했습니다.

여러분은 그림6 을 보고 어떤 생각을 하셨나요?

광원으로부터의 거리가 멀어질 수록, 광자끼리의 거리도 멀어집니다. 결국 같은 각도 내에 존재하는 광자의 개수는 동일하지만, 그것이 커버해야 하는 면적이 넓어졌습니다. 이것을 3D 관점에서 보면 그림7 과 같은 느낌이 됩니다.

그림7. 3D 에서 빛의 감쇠. 출처 : [2].

r 의 거리에서 한칸에 해당하는 면적에 광자가 3( = 3/1 ) 개가 있었다면, 2r 의 거리에서는 에서는 한칸에 평균적으로 3/4 의 광자가 존재합니다. 물론 광자의 위치에 따라 3 개나 2 개가 있을 수 있겠죠. 그림7 에서는 2 개가 있는 것으로 나왔군요.  3r 의 거리에서는 한칸에 평균적으로 1/3( = 3/9 )의 광자가 존합니다. 그림7 에서는 1 개로 나왔구요. 그물을 잡아 당겨서 늘리면 구멍이 커지는 느낌으로 생각하시면 됩니다.

이렇게 면적당 광자의 개수관계를 생각하면, 거리에 따라 빛의 밝기가 감쇠하는 것과 관련한 공식을 다음과 같이 쓸 수 있습니다. 일단 여기에서는 광자 1 개당 세기를 1 이라고 가정했습니다.

식1. 거리에 따른 빛의 세기의 감쇠. 거리의 제곱에 반비례합니다.

수학을 좀( ? ) 배우신 아티스트들은 이 공식을 보면서 의문을 가지게 될 것입니다; "언제 빛의 세기가 0 이 되나요?".

Distance 가 무한대가 되더라도 0 에 수렴할 뿐 0 이 되지는 않습니다. 즉 거리가 멀어질 수록 세기가 기하급수적으로 낮아지기는 하지만 아예 영향력이 없는 것은 아니라는 것이죠. 그러므로 대부분의 엔진들의 광원에는 UE4 에서와 같은 "Attenuation Radius( 감쇄 반경 )" 라는 속성이 있습니다[1]. 광원의 영향력을 모든 오브젝트에 반영한다는 것은 현실적으로 힘들기 때문입니다( 라이팅 계산이 무겁기 때문에 현재 하드웨어에서는 힘듭니다 ). 게다가 인간의 눈은 성능이 별로( ? ) 안 좋기 때문에 0 에 가까운 밝기를 인지하지 못합니다. 계산해 봐야 크게 의미가 없는 것입니다. 그래서 아티스트가 보기에 이 정도까지만 라이팅을 처리해도 괜찮겠다 싶은 거리를 지정하게 하는 것입니다. 쓸데없이 거리를 길게 잡게 된다면, 눈에는 거의 안 보이는데 처리를 해야 해서 계산비용이 늘어나겠죠.

예전에는 감쇠를 위해서 "Light Radius" 혹은 "Source Radius" 라는 용어를 사용했지만, area light 라는 개념이 나오면서 "source radius" 는 광원 자체의 반지름을 의미하는 것으로 바뀌었습니다. 그러므로 "Attenuation Radius" 와 "Source Radius" 를 혼동하지 마시기 바랍니다.

감쇠는 어떻게 계산된 것인가요?

앞에서 감쇠된 빛의 세기는 거리의 제곱에 반비례한다는 결론을 냈습니다. 물론 그림7 에서 볼 수 있듯이 거리가 1r 일 때 1칸, 2r 일때 4 칸, 3r 일때 9 칸, 이런 식으로 하면 거리의 제곱에 반비례한다는 사실이 유추되기는 합니다. 하지만 그림7 은 단순화해서 표현한 것일 뿐입니다.

이것이 어떻게 유도되었는지를 명확하게 이해해야 앞으로 나올 개념들을 이해하는데 도움이 됩니다. 이를 위해서는 입체각( solid angle )이라는 개념에 대해 먼저 알아야 합니다.

호도법

입체각에 대해 알려면 호도법에 대해 먼저 이해하는 것이 편합니다. 입체각이라는 것은 3차원에서의 각을 표현하는 것이기 때문에 2차원에서의 각인 호도법을 살펴 봄으로써 좀 더 쉽게 이해할 수 있기 때문입니다.

사람들은 평면에서 각을 표현할 때 도( degree )라는 단위를 선호합니다. 그래서 아티스트가 접하게 되는 대부분의 단위는 도 단위로 표현이 됩니다. 하지만 수학적인 영역으로 들어 가면 도 단위보다는 호도( radian ) 단위를 선호합니다. 매우 직관적이고 편하기 때문입니다.

여러분은 학교에서 반지름( radius )이 1 인 원의 둘레는 2π( pi, 파이 ) 라고 배우셨을 겁니다. π 는 순환하지 않는 무한소수로 원주율이라고 불립니다. 그 값인 3.1415926... 을 열심히 외우셨을테구요. 이때 질문이 들어갑니다. 각도가 a° 일 때 만들어지는 부채꼴의 호의 길이( arc length )는 얼마일까요?

그림8. 반지름 1인 원에서 각도가 a 도일 때의 부채꼴의 호의 길이는?

360 도일 때 원의 둘레가 2π 였기 때문에 비례식을 쓰면 a 도일때의 부채꼴의 호의 길이를 알 수 있죠.

식2. 반지름 1인 원에서 a 도인 부채꼴의 호의 길이 x 구하기.

좀 더 응용해 봅시다. 반지름이 r 일 때는 원의 둘레가 2πr 입니다. a 도일때의 부채꼴의 호의 길이는 무엇일까요? 식2 에서처럼 비례식을 사용해 값을 구할 수 있습니다.

식3. 반지름이 r 인 원에서 a 도인 부채꼴의 호의 길이 x 구하기. 

반대로 해 봅시다. 반지름 r 인 원에서 부채꼴의 호의 길이가 x 일 때 부채꼴의 각은 몇 도인가요? 식2, 3 에서 처럼 비례식을 써서 구할 수 있습니다.

식4. 반지름이 r 인 원에서 호의 길이가 x 인 부채꼴의 각 a 구하기. 

뭔가 숫자를 외워야 하고 나눗셈이 들어갑니다. 이건 매우 귀찮은 작업이며 실수의 여지가 있습니다. 그래서 수학자들은 이를 쉽게 할 수 있는 방법을 찾게 되었고, 호도법이라는 것이 나오게 되었습니다( 1714 년에 Roger Cotes 라는 사람이 호의 길이를 각처럼 사용하자는 제안했다고 합니다[3] ). 호도법이라는 것은 반지름이 r 일 때 부채꼴의 호의 길이가 r 인 경우를 1 라디안( radian )이라고 표현하는 것입니다. 즉 각의 크기를 도에서 길이의 단위로 바꿔버리는 겁니다( 그림9 참조 ).

그림9. 반지름이 r 인 부채꼴의 호의 길이가 r 일 경우 각도를 1 라디안이라 합니다.

여기가 바로 질문이 나올 타이밍입니다; "대체 뭐가 편한데요?".

우리는 반지름이 r 인 원의 둘레가 2πr 이라는 것을 알고 있습니다. 반지름이 r 인 부채꼴( 반원 )의 호의 길이는 πr 이죠. 이 때의 각은 π 입니다( 그림10 참조 ).

그림10. 반지름 r 인 ( 그리고 각이 π 인 ) 반원의 호의 길이는 πr 입니다.

관계가 명확하게 보이시나요? 만약 반지름이 r 인 부채꼴의 각도가 a 라디안이라고 하면, 그것의 호의 길이는 ar 인 것입니다( 그림11 참조 ).

식5. 반지름이 r 이고 각이 a 인 부채꼴의 호의 길이 x 구하기.

그림11. 반지름이 r 이고 부채꼴의 각이 a 라디안이면, 호의 길이는 ar 입니다.

뭔가 복잡하게 변환할 필요가 없습니다. 각과 반지름 알면 호의 길이를 알 수 있고, 각과 호의 길이를 알면 반지름을 구할 수 있고, 반지름과 호의 길이를 알면 각을 구할 수 있습니다. 매우 직관적이고 계산이 단순해집니다.

3차원에서의 각

평면에서의 각은 라디안이라는 단위를 사용해서 쉽게 표현할 수 있다는 것을 알게 되었습니다. 하지만 3 차원에서의 각도는 어떻게 표현해야 할까요?

애초에 우리는 각이라는 것을 평면에서만 사용해 왔습니다. 삼차원에서 10 도라는 개념이 상상이 되시나요?

그림12. 3차원에서 10도를 상상해 봅시다.

3D 에 익숙하신 분들이라면 이를 경도와 위도처럼 나누어서 생각하실 수 있을겁니다. 그림13 처럼 중심이 되는 방향( 벡터 )를 기준으로 수평으로 몇도 수직으로 몇도 이렇게 나눌 수 있겠죠( 물론 다른 표현들도 존재합니다만, 머리만 복잡해지므로 여기에서 굳이 다루지는 않겠습니다 ).

그림13. 3차원에서의 각을 수직각과 수평각으로 나누어서 생각할 수 있습니다.

하지만 수학자들은 호도법을 발명했듯이 입체각( solid angle )이라는 것을 발명하게 되었습니다[4]. 반지름이 r 인 구에서, 면적이 r2 인 면적을 포함하는 원뿔형의 각을 1 스테라디안( steradian, sr )이라고 부르고, 이러한 각도를 입체각이라 정의한 것입니다( 그림14 참조 ).

그림14. 반지름이 r 인 구에서 r2 인 면적을 포함하는 원뿔형의 입체각을 1 스테라디안이라 부릅니다. 출처 : [4]. 

그럼 여기에서 또 뭔가 룰이 보이시나요? 호도법이 호의 길이를 각으로 치환했듯이, 입체각은 겉넓이( 면적 )를 각으로 치환한 것입니다. 호도법에서는 1차원적인 곱인 "호의길이 X 반지름" 으로 표현되듯이, 입체각은 2차원적인 곱인 "겉면적 X 반지름의 제곱" 으로 표현되고 있습니다.

우리는 구의 겉면적을 4πr2 로 알고 있습니다. r2 이 1 스테라디안을 의미하므로 구 전체의 입체각은 4π 인 것입니다.

만약 반지름이 r 인 구에서 입체각이 a sr( 스테라디안 )인 원뿔형의 겉면적을 구해야 한다면 다음과 같은 관계로 표현될 수 있습니다.

식6. 반지름이 r 인 구에서 입체각이 a sr 일 때 원뿔형의 겉면적 x 구하기.

호도법처럼 매우 단순하게 표현되는 것을 알 수 있습니다.

빛이 거리의 제곱에 반비례해 감쇠하는 이유

반지름이 r 인 구에서 입체각 a 인 원뿔형의 겉면적이 ar2 이라는 사실을 알게 되었습니다. 만약 r 값이 늘어난다고 해도 a 는 각이기 때문에 변하지 않습니다. 어떤 광원이  a 라는 입체각 내에 광자를 1 개를 내 보낸다고 가정해 봅시다. 그리고 그것의 밝기를 1 이라고 하죠. 1초가 지났을 때의 반지름은 1 이고 r 초가 지났을 때 반지름은 r 이겠죠. 그렇다면 각각의 겉면적은 a ( = a X 12 ) 과 ar2 입니다. 겉면적의 비율은 1 : r이 됩니다.

면적이 r2 만큼 늘었으니, 광자가 커버해야 하는 영역은 더 넓어지며, 밝기는 반대로 1 / r2 에 비례하는 것입니다.

정리

빛이 감쇠하는 것은 엄밀히 말해 거리가 멀기 때문이 아닙니다. 거리가 멀어질 수록 면적에 비해 광자의 개수가 줄어들기 때문이죠. 거리에 따라 면적이 얼마나 커지느냐는 입체각의 정의를 통해 알 수 있습니다.

참고자료

[1] 라이팅 기초, Unreal Engine Documents.

[2] Light Attenuation, Technical Grahic Director.

[3] Radian, Wikipedia.

[4] Solid Angle, Wikipedia.

+ Recent posts