HatchTest_060123_parkch.zip




http://blog.naver.com/pch413/10001173790



< 자작 해칭 예제 스크린샷 >

 

 

아주~아주~아주~ 오래전에 제가 회사에서 세미나하고 올린

해칭 관련 예제 포스트(http://blog.naver.com/pch413/7330265)를 보시고

세부 구현이나 관련 자료를 문의하시는 분들이 가끔~가끔~ 계셨습니다.

(사실 REAL-TIME RENDERING 2nd Edition 책 보면 다 나옵니다.)

 

사실 자작 구현이라기 보다는 책에 있는 내용을 공부삼아 HLSL로 옮겨본 것 밖에 없고,

귀찮기도 하고 소스가 별로 깔끔하지도 못하고 엉망이라서 공개를 꺼렸는데...

이래저래 문의하시는 분들이 나중에도 생기면 더 귀찮아질 수도 있으므로

예제 실행 파일과 함께 HLSL 소스까지 공개합니다.

 

첨부된 HatchTest_060123_parkch.zip 압축파일을 받아서 적당한 곳에 풀어놓으신 후,

HatchTest 폴더 안에 있는 HatchTest.exe를 실행시키시면 예제를 돌려보실 수 있습니다.

HLSL 소스는 HatchTest.fx 파일을 참조하시면 됩니다.

 

예제를 실행하실려면 DirectX 9.0c 런타임 최신 버전이 깔려있어야 합니다.

(http://www.microsoft.com/downloads/details.aspx?displaylang=ko&FamilyID=3F2828FA-0E3C-4837-AFC0-6C67DCAA54BF)

그리고 Vertex Shader 1.1 이상, Pixel Shader 1.4 이상을 지원하는

그래픽 카드(ATI RADEON 8500급 이상)가 있어야 합니다.

 

실행시키시면 가상 광원의 위치를 나타내는 노란색의 구(sphere)가 물체 주위를 빙글빙글 돌아가는 것을 보실 수 있습니다. 그리고 그 광원 위치에 따라 해칭 패턴이 변화하게 됩니다. 마우스로 물체를 회전시킬 수도 있으니 조작해보시길 바랍니다. 그리고 우측에 있는 콤보 박스를 이용하면 표시되는 물체(구, 원뿔, 주전자, 호랑이)를 바꿀 수 있습니다.

 

< 해칭의 개념 >

 

해칭(Hatching) : 펜/잉크 소묘에서 가늘고 세밀한 평행선이나 교차선을 사용하여 객체의 음영 차이 및 요철을 표현하는 기법에 대한 일반적인 용어.

 

(개념 : 인간이 마땅히 알아야 할 상식과 도리로서 이를 알지 못하면 '개'가 된다고 하여 개념이라 함.)

 

이 예제에서 보여주는 해칭(Hatching)은 비실사 렌더링(Non-Photorealistic Rendering;NPR) 방식 중의 하나로서 해치 패턴의 밀도를 통해 그 지점의 표면이 얼마나 많은 빛을 반사하는지를 표현해주는 기법입니다. 여기서 사용하는 해칭 기법은 매우 드문드문한(빛을 많이 받는) 영역으로부터 매우 조밀한(빛을 받지 않는) 영역에 이르는 해치 패턴 맵을 이용하게 됩니다. 각 정점 별로 빛에 대한 가중치를 계산한 다음, 각 픽셀 별로 보간된 가중치에 따라 해치 패턴 맵을 적절히 혼합하여 표현해주는 방법을 사용하고 있습니다.


< Tonal Art Maps >

 

어떤 분께서 E-Mail로 Tonal Art Map(TAM)을 이용해서 구현했는지 물어보셨는데, 맞습니다.

앞서 언급한 해칭 패턴 맵이 바로 Tonal Art Map으로서 여기서는 6단계의 텍스처를 사용하게 됩니다.

하지만, 팔레트가 6개-즉, 텍스처를 6장이나 쓰게 되면 그만큼 처리 비용이 엄청나겠죠?

그래서 위의 그림과 같이 각 단계의 맵이 단색(Grayscale)임을 이용하여

텍스처의 각 색상 채널에 하나씩 할당해서 2장의 텍스처로 줄여 쓸 수 있게 합니다.

(단색 텍스처는 0~255 값을 가지는 하나의 채널로 표현할 수 있으므로

R, G, B 각각의 채널에 하나씩 집어넣을 수 있습니다.)

즉, 1,2,3 단계의 맵은 첫번째 텍스처, 4,5,6 단계의 맵은 두번째 텍스처에 할당됩니다.

(첨부된 압축 파일 안의 Hatch123.dds, Hatch456.dds가 이것입니다.)

 

이 내용은 "REAL-TIME RENDERING 2nd Edition" 책에 소개된 기법으로서

2001년 시그라프(SIGGRAPH) 논문에 있는 내용입니다.

 

Emil Praun, Hugues Hoppe, Matthew Webb, and Adam Finkelstein, "Real-time Hatching," (SIGGRAPH Proceedings, 2001), pp. 581-586.

 

아래 링크를 클릭해보시면 논문을 직접 보실 수 있습니다.

http://research.microsoft.com/~hoppe/hatching.pdf

(다소 영어의 압박을 느낄 수도 있습니다.)

 

< Vertex program source >

 

위의 소스는 정점 프로그램으로서 각 정점 별로 빛에 대한 가중치를 계산합니다.

워낙 코딩 실력이 딸려서 소스가 복잡하고 다소 더럽지만 그렇다고 나무라지는 마시길 바랍니다.

clamp, abs 함수들을 좀 복잡하게 써 놓긴 했지만, 내용은 단순합니다.

(abs는 절대값, clamp는 min~max 밖의 값을 잘라냄; max보다 크면 max로, min보다 작으면 min으로 함.)

 

쉽게 설명하면, 정점에 대한 노말 벡터와 광원 방향 벡터의

내적을 구해서 빛을 받는 정도를 [-1, 1] 구간 사이로 구한 다음, [0, 6] 구간으로 바꿉니다.

그리고나서 가장 적합한 단계들에게 가중치를 부여합니다.

 

예를 들어, 'n dot l'의 계산 결과가 0.5가 나왔다고 합시다. 어중간하게 좀 밝은 쪽이 되겠죠?

그러면, 1단계와 2단계 텍스처가 중간 정도 혼합된 형태가 되어야 할 것입니다.

위의 복잡한 식대로 계산하면 oTexWeight123과 oTexWeight456은 다음 값들을 가지게 됩니다.

 

oTexWeight123 == (0.5, 0.5, 0.0)

oTexWeight456 == (0.0, 0.0, 0.0)

 

의도한 대로 1단계와 2단계에 0.5씩 가중치가 들어갔죠?

한마디로, abs랑 clamp를 써서 적절한 단계에 가중치가 부여될 수 있도록 했습니다.

만일, 이 글을 보시는 다른 분들께서 조금 더 간단하게 쓸 수 있다고 생각하시면 알려주세요.

아직 HLSL를 많이 써보지 못하다보니 코드가 좀 엉망입니다.

(지금 생각해보니 clamp(..., 0.0, 1.0)이 아니라 saturate(...)를 쓰면 되었을 것을... 왜 저랬을까? 이런 바보같은 짓을... ㅡㅡ;)


< Fragment program source >

 

마지막으로 위의 소스는 프래그먼트 프로그램으로서

각 픽셀 별로 보간된 가중치에 따라 TAM을 혼합하게 됩니다.

 

앞 쪽에서 보여드린 TAM 그림을 다시 보시면 스트로크(stroke) 패턴들이 검정색,

바탕은 흰색으로 된 것을 알 수 있습니다.

사실 우리가 해야 할 일은 스트로크 패턴들만 뽑아내서 잘 혼합하는 것입니다.

 

그래서 이 프래그먼트 프로그램에서는 별도로 구현된

GetInverseColor 함수를 이용해서 색상을 뒤집습니다.

즉, 바탕이 검정(0.0)으로 바뀌고, 스트로크가 흰색으로 바뀌므로

스트로크 요소만 따로 혼합될 수 있습니다.

 

보간된 가중치를 각 채널에 들어있는 Grayscale 값과 곱해서 더하고,

이를 다시 GetInverseColor 함수로 뒤집어주면 우리가 원하던 최종 색상을 얻어낼 수 있게 됩니다.

 

< 참고 자료 >

 

 

1) Real-Time Rendering(2nd Edition)/Tomas Akenine-Moller, Eric Haines/A.K.Peters Limited

 

해칭 관련 내용은 이 책 보고 쁼(feel) 받고

실제로 돌려보고 싶다는 생각이 들어서 HLSL로 구현해봤던 겁니다.

현존하는 실시간 렌더링 관련 서적 중에서는 최고의 참고서입니다.

7장의 Non-Photorealistic Rendering 파트에 해칭 관련 내용이 소개되어 있습니다.

 


2) Direct3D ShaderX:Vertex and Pixel Shader Tips and Tricks/Wolfgang F. Engel/Wordware Publishing

 

사실 제 소스는 이 책에 있는 어셈블리로 작성된 해칭 소스를 거의 베끼다시피해서 HLSL로 옮긴 것에 불과합니다. 그리고 TAM 텍스처도 부록 CD 안에 들어 있는 것을 가져와서 쓴 것입니다. 원본 소스를 보고 싶으시다면 참조하십시오.


< 마침 >

 

간만에 긴 글을 포스팅해봤습니다. HLSL 써본지도 꽤 오래된 지라 가물가물하기도 하고, 글도 생각처럼 잘 써지지도 않는군요. 그리고 나름대로 머리 좀 굴려봤다고 자부했었는데... 오히려 글을 쓰고 보니 부족했던 점이 더욱 눈에 띕니다. 제가 참여하고 있는 프로젝트도 셰이더를 맘껏 쓸 수 있는 환경이 되면 좋겠지만... 렌더링과는 점점 더 멀어지는 일만 하고 있네요. 좀 더 재미있는 것을 할 수 있다면 좋으련만...

 

오뎅장수 P군

블로그 : http://blog.naver.com/pch413/

반응형

+ Recent posts