안녕하세요 풍풍풍 입니다 (퐁퐁퐁 아닙니다 __)
티스토리도 당연히 되는줄 알고 네이버에서 작업하고 여기다 올렸더니
Xbox가 뜨는 대 참사가 있었네요 __)
조심하겠습니다..__)
오늘 알아 볼 것은 Ashikhmin-Shirley 조명 모델입니다
Satin이나 Velvet에 적합한 조명모델이라고 합니다.
Satin
Velvet
개념. |
Ashikhmin-Shirley 조명 모델이란
Michael Ashikhmin 과 Peter ShirleyCook-Torrance 모델과 마찬가지로 물리적으로 정확한 반사율을 얻기 위하여 프레넬 가중치를 선택하고 있습니다.
아래는 이방성 파라미터(Nu, Nv)에 변화에 따른 조명모델의 효과를 애니메이션으로 나타낸 것입니다
두개의 이방성 파라미터를 조절하여 Velvet 과 Satin의 느낌이 나온다고 보시면 되겠습니다@_@
들어가기 전에 BRDF란 용어가 자주 나오는데 간단하게 BRDF가 무엇인지 알아 보겠습니다
Bidirectional Reflectance Distribution Funtion의 약자로 양방향 반사 분포 함수를 말합니다
Surface에 상태에 따른 반사율을 구하는 함수입니다
공식. |
이번 조명은 다음과 같은 식에 의해 만들어집니다
간단하죠^_^
Ashikhmin-Shirley 조명 모델의 공식의 최종 모델은 다음과 같습니다
죄송합니다 __) 웃길 줄 알았어요...
다시 본론으로 가서...
다시 본론으로 가서...
하나하나 풀어 갑니다..
----------------------------------------------------------------------------------------------------------------------------------------------------------
일단 위에 그림에서 최종공식은 간단하게 다음과 같이 표현할 수 있습니다
어렵게 생각 할 필요 없이 Diffuse + Specular 라고 보시면 되겠습니다.
여기서 pd와 ps는 다음과 같은 공식이 됩니다
각 파라미터는 아래와 같습니다
Rd | 디퓨즈 컬러 |
Rs | 일반 입사에 따른 스펙큘러 |
Nu, Nv | 스펙큘러의 모양을 제어하기 위한 지수. Nu=Nv일때는 등방성 하이라이트가 된다 |
과정은 다음과 같이 되겠습니다 @_@ ( 뭔가 저번 포스팅하고 비슷하군요-.-)
위에서 본 공식하고는 다소 틀린데 위 그림은 Steigleder 과 McCool의 구현의 형태를 띄고 있습니다
연산 방식만 틀릴 뿐 내부적으로는 같습니다 __)
결과적으로 P = Pd + Ps 의 형태를 지니고 있는것입니다. 이해하기 쉽도록 참조 용으로 보세요~
위에서 본 공식하고는 다소 틀린데 위 그림은 Steigleder 과 McCool의 구현의 형태를 띄고 있습니다
연산 방식만 틀릴 뿐 내부적으로는 같습니다 __)
결과적으로 P = Pd + Ps 의 형태를 지니고 있는것입니다. 이해하기 쉽도록 참조 용으로 보세요~
차근 차근 살펴 보겠습니다.
Ps 부터 살펴 봅니다
Ps 는 기본모델을 Phong 모델로 잡습니다
이 때, n은 면의 거칠기를 나타냅니다.
이 때, BRDF의 정의를 하기위한 공식에서
입사 방향에 Cosine 각이 들어가므로 이 항을 상쇄 하기 위해 (n·l)로 나누어 줍니다
(자세한 부분은 리얼타임 렌더링 2판 6장 3절에 BRDF이론을 보시면 됩니다 @_@)
이 때의 Ps는 BRDF가 갖춰야 할 Helmholtz 호환성을 만족하지 않습니다
László Neumann &Attila Neumann 은 이러한 조건을 만족 시키는 BRDF를 제안했는데
(자세한 부분은 리얼타임 렌더링 2판 6장 3절에 BRDF이론을 보시면 됩니다 @_@)
이 때의 Ps는 BRDF가 갖춰야 할 Helmholtz 호환성을 만족하지 않습니다
(Helmholtz reciprocity) :입사각과 반사각은 바뀔 수 있으며 함수 값은 동일하다) |
László Neumann &Attila Neumann 은 이러한 조건을 만족 시키는 BRDF를 제안했는데
그 BRDF는 다음과 같습니다
맨끝에 F는 프레넬 가중치이며 이때 사용하는 공식은 Schilck의 프레넬 근사치가 사용되었고
여기에 (Half · Normal)위에 있는 n 부분을
이등방성 파라미터로 확장하고
Specular를 구한것이 Ashikhmin-Shirley 조명 모델의 Specular 성분 입니다
써놓고도 뭔소린지 모르겠습니다...
왜 저렇게 될까 라는건 수학 고수이신 이 글의 리플러분 들을 믿겠습니다..__)
Pd (Diffuse에 관한 식) 계산은 BRDF에 Diffuse 공식
으로부터 Diffuse 와 R의계수를 구하여 다음과 같은식을 이끌어 냅니다
성능 개선이 필요할 경우는 위의 식 대신 일반 램버트 방정식을 사용하는 것도 좋은 방식입니다
Pd (Diffuse에 관한 식) 계산은 BRDF에 Diffuse 공식
으로부터 Diffuse 와 R의계수를 구하여 다음과 같은식을 이끌어 냅니다
성능 개선이 필요할 경우는 위의 식 대신 일반 램버트 방정식을 사용하는 것도 좋은 방식입니다
구현 |
이 공식에서는 cos, sin을 제거하기 위해 GPU 친화적인 내적 연산을 사용한 약간 수정된 공식을 사용합니다.
Ps에서 요구되는 Nu, Nv 벡터는 Tangent Vector 와 BiTangent Vector 이며,
픽셀 셰이더에서는 (1,0,0) 이나 (0,1,0)으로 방정식을 단순화 할수는 있지만,
가능한 그렇게 하지 않는 것이 좋습니다
이를 HLSL로 표현해 보겠습니다
float4 psAshikhminShirley ( in VS_OUTPUT f ) : SV_TARGET { // 보간된 입력값 과 정규화된 상수 파라미터 float3 n = normalize( f.normal ); float3 l = normalize( -vLightDirection ); float3 v = normalize( pCameraPosition - f.world ); float3 h = normalize( l + v ); // 좌표 프레임 선언 float3 epsilon = float3( 1.0f, 0.0f, 0.0f ); float3 tangent = normalize( cross( n, epsilon ) ); float3 bitangent = normalize( cross( n, tangent ) ); // 계산하기 쉽게 몇가지 변수를 미리 생성한다 float VdotN = dot( v, n ); float LdotN = dot( l, n ); float HdotN = dot( h, n ); float HdotL = dot( h, l ); float HdotT = dot( h, tangent ); float HdotB = dot( h, bitangent ); float3 Rd = cDiffuse; float3 Rs = 0.3f; float Nu = fAnisotropy.x; float Nv = fAnisotropy.y; // 디퓨즈 계산 float3 Pd = (28.0f * Rd) / ( 23.0f * 3.14159f ); Pd *= (1.0f - Rs); Pd *= (1.0f - pow(1.0f - (LdotN / 2.0f), 5.0f)); Pd *= (1.0f - pow(1.0f - (VdotN / 2.0f), 5.0f)); // 스펙큘러 계산 float ps_num_exp = Nu * HdotT * HdotT + Nv * HdotB * HdotB; ps_num_exp /= (1.0f - HdotN * HdotN); float Ps_num = sqrt( (Nu + 1) * (Nv + 1) ); Ps_num *= pow( HdotN, ps_num_exp ); float Ps_den = 8.0f * 3.14159f * HdotL; Ps_den *= max( LdotN, VdotN ); float3 Ps = Rs * (Ps_num / Ps_den); Ps *= ( Rs + (1.0f - Rs) * pow( 1.0f - HdotL, 5.0f ) ); // 최종 값 출력
return float4( Pd + Ps, 1.0f ); }
Oren-Nayer 때도 설명했지만 역시 마찬가지로
종속 되는 부분을 찾아 텍스처 룩업을 통해 처리가 가능하지만 일부 작업들 중에는
보틀넥의 주요 원인이 된다는 점 잊지 마세요~
구현은 위의 파일을 다운받아 역시 렌더몽키로 돌리시면 됩니다.
이방성 파라미터인 u와 v (구현 파일 내에서는 fAnisotropy의 x,y 값이 u,v 입니다)의 값들을
조절 하시면 되겠습니다 밑의 예에서는 PI값을 1.0으로 주었을때 입니다
Nu = 10 , Nv = 5000
Nu = 100, Nv = 100
Nu = 5000, Nv = 10
Nu = 5000 , Nv = 5000
Nu가 커질수록 윤곽을 따라 수평 하이라이트를 보여주며
Nv가 커질 수록 수직 하이라이트를 보여주는 반면
100,100일때는 등방성 분포를 보여주고 있습니다 @_@
여기까지 보시느라 수고 하셨구요
더 알고 싶으신 분은 적당한 구글링을 해주시면 쉽게 찾으실 수 있습니다.. 도망__)
언제나 최선을 다하며 멋지게 사시는 개발자 여러분들
늘 화이팅입니다
Reference: http://www.cs.utah.edu/~shirley/papers/facets.pdf
http://www.t-pot.com/program/81_Ashikhmin/index.html
http://azzrael.wo.to/study/graphic3d/illumi/phyillum1.htm
http://en.wikipedia.org/wiki/Bidirectional_reflectance_distribution_function
http://mathinfo.ens.univ-reims.fr/IMG/pdf/A_new_class_of_BRDF_models_with_Fast_importance_sampling_-_Neumann.pdf
반응형
'프로그래밍' 카테고리의 다른 글
표준 rand()함수보다 유용한 랜덤 생성 알고리즘 – MT, WELL (23) | 2012.02.27 |
---|---|
D3D에 익숙한 개발자을 위한 OpenGLES 개발 소개 (16) | 2012.02.26 |
Implement Hash String ID Index #2 (4) | 2012.02.21 |
UMDH로 메모리 릭 제거하기. (7) | 2012.02.17 |
게임 오브젝트 설계.. 나도 잘하고 싶다! #2 (13) | 2012.02.17 |