3. 왜 물은 물처럼 보이는 걸까?

반응형

앞의 글 참조
1. http://mgun.tistory.com/1282
2. http://mgun.tistory.com/1294

BRDF라는 개념이 왜 중요한가?
BRDF는 단순하게 말하자면 입사하는 빛에 따른 반사하는 빛의 비율에 대한 함수다.
우선 물을 물처럼 보이기 위해 Lighting이라는 개념이 들어가는데 렘버트의 단순함 만으로는 사실적인 결과물을 얻기 힘들다.
그 이유는 렘버트는 빛이 입사하는 방향에 관계없이 모든 방향으로 같은 양의 빛을 반사한다고 가정하기 때문이다.
(렘버트 모델은 상수 BRDF에 의해 완벽하게 분산 표면을 표현한다.)
하지만 실제로 물을 본다면 물을 바라보는 위치에 따라 물의 빛의 반사정도나 투과정도가 다르다는 것을 알 수 있다.
즉, 특정 표면이 현재 내가 바라보는 시점과 빛과의 관계에 따른 특정값을 얻을 필요가 있는 것이다.


위 그림들은 BRDF함수들을 가시화 한 것들이다.
Lambertian model, Lommel Seelinger, Phong reflectance model, Blinn Phong model, Torrance Sparrow model,
Cook Torrance model, Ward's anisotropic model, Oren Nayar model, Ashikhmin Shirley model, HTSG,
Fitted Lafortune model, Lebedev model...          
겁나 많구만이라~~ ㄷㄷ.

다양한 BRDF의 이론적 모델중 하나로 미립면(Microfacet) 이론이 있다.
이에 대한 설명은 "Directx 9 셰이더 프로그래밍" 타카시 아저씨 책에 보면 301p 에 자세히 잘 나와있다.
기본적인 내용은 평평해 보이는 면도 사실 세밀하게 거친 면이 있기 때문에 거울처럼 완전 평면한 물체에서 나타나는
정반사가 나타나는게 아니라 각 미립자간의 상호 반사나 표면물질의 자체적인 산란으로 인해 빛의 반사가 희미해 진다
정도?..

이 그림이 모든 내용을 담고 있다.

이 미립자 BRDF 샘플의 공식을 한번 보자.

위의 분수식에서 분자를 유심히 보자.
F, G, D...요것들이 중요한데 요것들에 대한 설명도 타카시 책에 잘 나와 있다.
F는 프레넬, G는 기하감쇠 계수, D는 미세면 분포 함수인데 프레넬에 대한 이해가 중요하다.
프레넬에 대한 내용은 설명이 깔끔하고 명료하게 잘 된 http://gamedevforever.com/35 의 글을 참조하면 된다.

이 그림은 프레넬 개념을 잘 설명해 주는 그림이다.

물을 바라보는 관측자의 시야에서 바라보는 물의 지점까지의 방향의 각도에 따른 물의 투과 및 반사에 대한 설명이다.
바로 위 이미지를 보면 물을 위에서 아래로 내려다 보면 물 내부가 투과되서 않의 물고기가 보인다.
고개를 들어 좀 더 멀리있는 물을 볼 수록 투과률은 줄어들고 주위 환경의 반사율이 높아진다.
이러한 현상을 실제로 찍은 것이 위의 호수를 실제로 찍은 사진이다.

float base = 1 - dot(V, H);
float exponential = pow(base, 5.0);
float fresnel = exponential * F0 * (1.0 - exponential);
specVal *= fresnel;

위의 계산식으로 프레넬의 밝기를 구할 수 있다.

Unreal에서는 이미 Fresnel 이라는 노드가 제공된다.


이 노드는 언리얼이 자동으로 생성해 주는 소스를 보면 아래와 같다.
half3 GetMaterialEmissive(FMaterialPixelParameters Parameters)
{
   float3 Local1 = (UniformPixelVector_0.rgb * GetPerInstanceSelectionMask(Parameters));
   float Local2 = dot(float3(0.00000000,0.00000000,1.00000000),Parameters.TangentCameraVector);
   float Local3 = max((0.00000000),Local2);
   float Local4 = ((1.00000000) - Local3);
   float Local5 = ClampedPow(Local4,(3.00000000));
   float3 Local6 = (Local5 + Local1);
   return Local6;
}

1. dot(float3(0.0, 0.0, 1.0), Parameters, TangentCameraVector);

물체의 법선벡터인 0,0,1와 카메라의 시선벡터를 내적한다.
여기서 내적의 공식을 생각해 보면 v1 dot v2 = |v1| * |v2| * cos각도 인데
구체표면의 중심 법선은 카메라의 방향 벡터와 일치하므로 cos0 이며 이는 1의 값이다.
반면에 구체의 가장자리의 법선은 카메라의 방향벡터와 수직이므로 cos90 이며 이는 0의 값이다.

잠깐 내용 더하기) ---------------------------------------------------------------------------------------------------------
내적의 목적은 두 벡터사이의 각도를 측정하기 위해서 이다.
렘버트 공식은 기본적으로 dot(L, N)이고 하프 렘버트 공식은 dot(L,N) * 0.5f + 0.5f이다.
렘버트의 기본 개념은 균일하게 반사된다는 개념을 깔고 간다.
그래서 렘버트 반영 반사는 아래와 같다.
Ia*ka + Id*kd*dot(N,L)
앞의 Ia와 Ik는 환경광(ambient light)를 뒤의 Id와Kd는 환산광(diffuse light)를 나타낸다.


여기에 하이라이트를 추가한 모델이 바로 퐁 모델.
그리고 시선이 물체에 반사되었을 때, 그 방향이 빛의 입사 방향에 가까울 수록 밝게 보인다의 컨셉인 퐁 반영반사
Ia*ka + Id*kd*dot(N,L) + Is*ks*dot(L,R)n 으로 나타낼 수 있는데
여기에 새로 등장한 R은 반사벡터로 -E + 2*dot(N,E)*N 으로 구할 수 있다.
E는 시선 벡터로 물체에서 카메라를 바라보는 방향이며 n은 반사지수로서 반사하이라이트가 적용되는 범위를 나타내는데 클수록
작고 강하게 나타난다.

블린 퐁은 퐁과 거의 같다. 블린의 개념은 반사벡터인 R을 구하기 힘드니까 쉽게 하프벡터인 H를 구해서 쓰자. 이다.
H는 (E+L ) / (|E+L|) 로 구할 수 있는데 최종적으로
Ia*ka + Id*kd*dot(N,L) + Is*ks*dot(L,H)n 으로 나타낼 수 있다.
--------------------------------------------------------------------------------------------------------------------------


Local3, Local4 계산

내적한 결과 값을 0과 비교해서 큰 값을 선택한다.
이는 단순히 음수값을 없애기 위한 계산이며 여기서는 Clamp를 사용하였다.

그 후에 "OneMinus"라는 노드를 사용하여 Local4의 계산을 해 주었다.

Local5의 계산 식과 같이 Pow3을 해 준다. 이 값은 세제곱 해주는 건데 프레넬 공식에서 나오는 pow 항의 지수 파라미터이다.
적당한 값으로 넣어주면 된다. 여기선 프레넬 기본에 설정되어 있는 3의 값을 넣어주었다.
프레넬 노드를 쓴 것과 결과물이 거의 똑같다.
여기에 ClampedPow이므로 Clamp 하나 추가해 주는 센스를 발휘해 주면 된다.



참고 :
- udk로 프레넬 구현 : http://donggas90.blog.me/100156266047
- udk로 렘버트와 하프렘버트 : http://donggas90.blog.me/100133823753
- 환경맵으로 알아보는 프레넬 : http://blog.naver.com/sorkelf/40157708229
- 조명방정식 : http://cagetu.egloos.com/1746970
- 프레넬 이펙트 : http://gamedevforever.com/35
- ShaderFX를 이용한 효과 : http://chulin28ho.tistory.com/100
- 프레넬 반사 : http://allosha.tistory.com/54
- microfacet BRDF : http://blog.naver.com/hsg556/110129600105
- Physically Based Lighting  : http://wiki.peppercode.net/wiki/published/Physically+Based+Lighting
         

*ps - 위 이미지들은 대부분 직접 만들려고 했지만 퍼온것도 있습니다. 이익창출의 목적이 아니니 이해해 주세유~!
- 잘못 설명된 부분이 있거나 이상한 부분이 있으면 과감한 지적질 감사유~!

TAGS.

Comments