꽃미남 프로그래머 김포프가 창립한 탑 프로그래머 양성 교육 기관 POCU 아카데미 오픈!
절찬리에 수강생 모집 중!
프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by 대마왕J

자아 오늘은 그럼 진짜 마지막회로, 외곽선을 구현해 보겠습니다.

사실 외곽선 구현은 shader로 해야 하는데, shaderFX로 구현해 보려고 해 봤더니
기능이 부족한 부분이 있더군요.

첫 번 째 방법은 그냥 하면 되니까 문제 없는데...
두 번째 방법이 문제가 있어요.

일단 면을 뒤집어야 하는데, 앞면만 컬링하는 기능이 없어요 ...
그리고 vertex의 normal을 받아와야 하는데, vertex normal은 없고 surface normal만 있네요.
써봤더니 일단 뭐 작동은 하길래 뒤집는거 외에는 잘 되나보다.. 했더니,
이번엔 max의 normal 뒤집기 기능과 충돌이 나는지, 뒤집어도 안 나오더라고요.

그래서 에라 모르겠다 하고 두 번째 방법은 그냥 맥스 기능으로 설명해 버리려 합니다.
자 여러분 모두 기대하세요 :)

기대하셔야 합니다.

 

중간중간 개그를 치고 싶지만, 양이 워낙 많고 이제 초보자 분들도 아니니 건조하게 빨리 설명해 볼께요.
여기까지 따라 오셨으면 이미 개그 보러 오신 분들이 아니잖아...

 

 

외곽선 구현하기
첫 번째 방법

첫 번째 방법은 매우 싱겁습니다. 림라이트 기능을 이용하는 거거든요.
일단 이 부분을 이해하셔야 이번 강의가 가능합니다.

림라이트 구현이 이해 안되시면, 아래 강의를 읽고 실습하고 오세요.
 다 잊어 버린거 아니까, 화내지 않을 테니까 실습하고 와요 좀.

http://gamedevforever.com/259

 

 

 

(공부하는 중)

네 이걸 보시면 외곽선 구현 어떻게 하실지 알겠지요?

림라이트로 하는 방법이 있습니다.
구현도 대빵 간단하지요.

일단 림라이트를 만드세요.

 

이 정도는 뭐 금방이잖아요.

자, 여기서 거의 답이 나왔습니다.

바로 전전 시간에 했던 'if문을 이용한 셀 셰이딩 방법' 과 같은 원리로 외각선을 만들어 주는 거지요.

설명을 또 하자니 구차하네요. 간단히 보여만 드려도 다 아실 듯.

 

이겁니다. 마지막에 색상 곱하는 부분을 없애고, if문을 넣어서 일정 숫자 (지금은 0.3)을 넣었습니다. 이상이면 흰색을 출력하게 해 놓은거죠. 이렇게 하면 외곽선이 됩니다. 외곽선을 흰색으로 만든 이유는 맥스 배경이 어두운 색이라 잘 안보일까봐...

그냥 간단히 if문의 부호만 바꿔주면 검은 외곽선이 됩니다.

 

간단하죠? 그리고 결과값이 흰색과 검은색이 나왔다는데 집중하세요.
무슨 얘기냐면, 이 결과값과 다른 결과 (셀 셰이딩 결과) 를 같이 적용하고 싶으면, '곱하기' 만 하면 된다는 거니까요.
흑백으로 만들면 이게 좋아요.

무슨 얘기인지 다시 설명하자면.... 직접 지난번에 만든 셀셰이딩 가지고 실습해 보지요.

 

 

이게 일단 지난 시간에 만든 wrap 텍스쳐를 이용한 셀 셰이딩입니다.
이거랑 위의 외곽선 공식을 같이 대입해서 외곽선 있는 셀 셰이딩을 하려면...

 

이렇게 두 공식의 결과물을 곱해주기만 하면 되거든요 :) 뭐 굳이 더 설명 안해도 되겠지요.

이렇게 외곽선을 구해주면 간단합니다.
이 방식에는 장단점이 있는데요.

- 일단 장점으로는 외곽선의 두께가 다양해 집니다. 폴리곤의 집중과 각도에 민감하게 변화할 수 밖에 없거든요.
그래서 모델링만 신경써서 한다면 어딘지 모르게 '동양화스러운', 변화되는 두께의 선 느낌도 낼 수 있다는 장점이 있습니다.

- 물론 단점도 있습니다. 말씀드렸든 노말 방향에 민감하기 때문에 , 이 방법은 둥글둥글한 오브젝트에밖에 제대로 사용하기 힘듭니다. 박스처럼 각진 물건에는 이상하게 외곽선이 나올 수 밖에 없거든요. 그도 그럴 것이 넓은 면의 노말이 모두 같아 버리니까 말이죠.

박스에는 외곽선이 이상하게 나오는 것을 볼 수 있습니다.

 

그래서 게임에서도 림라이트는 주로 캐릭터에만 사용되고, 건물에서는 잘 사용되지 않는 겁니당.  

 

 

 

 

 

외곽선 구현하기
두 번째 방법

이 방법이 바로 '살아있는 편집점' 오즈라엘이 설명한 바로 그 방법입니다.
http://gamedevforever.com/18

이 방법은 원래 shader로 구현하는 방법이지만... 이래저래 해 봤는데 shaderFX에서는 일단 2pass 구현이 안되는데다가,
Vertex 제어도 불완전한 면이 있어서
그냥 맥스만으로 구현해 보겠습니다.[각주:1]

2pass란 간단히 말해서 '두 번 그린다'는 말입니다.[각주:2]
shader에서는 필요에 의해, 혹은 한계 때문에 한 번에 그리지 못하고 두 번에 나눠서 그려야 하는 경우가 꽤 있습니다.
보통 이것은 shader 코드 내에서 두 번 처리하도록 해주면 되는데, shaderFX에서는 거기에 대한 고려가 되어 있지 못해서 변칙적인 방법으로 해야만 합니다.

지금 그리는 이 방식이 바로 2Pass로 처리해야 하는 방식입니다.
두 번 그리도록 시킬 수는 없으니까, 주전자를 복사해서 두 개로 만들어 사용하도록 하지요 :)
이번에 설명드릴 방식은 3Dmax 초보 분들에게는 조금 곤란한 내용이 있을 수도 있습니다. 모르는게 나오면 질문해 주시거나 주변 아티스트 분들의 도움을 얻어 보세요 .

 

1. 오브젝트 복사하고 하나 숨기기 

일단 주전자를 하나 그리도록 하죠. 이게 첫 번째 pass를 상징합니다

 

2pass를 흉내내기 위해, 주전자를 완전히 동일한 자리에 복사하겠습니다.
이렇게 복사하려면, 주전자를 선택하고 snapshot 을 실행시켜 주면 됩니다.
뭐라고 뭐라고 나오면 그냥 OK 하세요. :)

 

그럼 이전의 주전자에 '완벽히 같은 자리에' 완벽히 같은 주전자가 복사되어 있습니다.
너무 완벽히 겹쳐져 있어서 하나로 보이지만요.

이제 이 중에 하나를 숨겨봅시다. 방해되니까요.

그냥 선택된 주전자를 (선택이 안되어 있으면 그냥 주전자를 선택하세요) 오른쪽 클릭해서 Hide 시켜 버립니다.

 

아무 변화가 없는 것 같습니다.
그렇지만 동일한 자리에 있던 주전자 2 개중 하나가 숨겨진 상태입니다.

그러므로 지금 남아 있는건 주전자 1개 뿐인거죠.
하나는 숨겨져 있으니까.

2. 면을 뒤집기

자 이제 남은 주전자로 1pass를 처리해서 외곽선을 만들어 봅시다. 
이제  할 일은, 면을 '뒤집는' 겁니다. 노말을 뒤집는 거예요.

그러기 위해 첫 번째 할 일은 '양면 렌더링' 을 끄는 겁니다. 언제가부터인가 max의 모든 오브젝트는 양면 렌더링이 되기 시작했거든요.

 양면 렌더링을 끄기 위해서 오브젝트를 선택하고 오른쪽 클릭한 후.
Object Properties를 선택해 줍니다.

Properties가 나오면, General 탭에서 Backface Cull을 켜줍니다. 이것이 양면 렌더링을 꺼주는 기능입니다. 

 양면 렌더링을 꺼줬으면, 이제 면을 뒤집을 차례입니다. 오브젝트를 선택하고 오른쪽 모디파이어 탭에서,
Normal 모디파이어를 선택해 줍니다.

 이상이 없으면 이제 면이 뒤집혔습니다. 볼록하던 주전자가 오목해졌음을 알 수 있습니다.
이 상태로 공이나 박스 같은게 주전자 안쪽에 들어가 있다면 보이겠지요.

3. 면을 확장하기

외각선을 만들기 위해서 스케일을 키워서는 안됩니다.
스케일을 키우면 http://gamedevforever.com/18 에서의 글처럼 이런 이상한 외각선이 나오게 되거든요.

그러니 우리는 스케일을 멀리하고 노말 방향으로 확장하는 것이 낫습니다.

자 그렇게 하기 위해서 ... 일단 주전자를 선택하고 오른쪽 클릭해서 Editable Poly로 바꿔줍시다.

 

 Editable Poly로 바뀌었다면, Polygon 선택 모드를 활성화 시켜 줍니다.

 주전자를 다 덮을 만큼 큼지막하게 마우스 왼쪽 드래그로 선택해 주세요. 이렇게 하면 주전자의 모든 Polygon이 선택되게 됩니다. 빨갛게 선택되었나 확인하세요.문제가 생기면 주위의 아티스트에게 문의하세요 :)

 Polygon 선택이 완료되었으면, 이번엔 확장할 차례입니다. 오른쪽 메뉴에서 Extrude라는 명령을 찾고, Extrude와 함께 있는 창 모양의 버튼을 누르세요.

 그러면 아래와 같은 모양이 될 수도 있고, 아닐 수도 있습니다. 하여간 기괴하게 될 가능성이 큽니다.
신기한 메뉴가 주전자 가운데에 떠 있습니다.

 침착하게, Group으로 되어 있는 저 부분을 Local Normal로 바꿔주세요. 각 노말 방향으로 확장해야 하니까요.

 그 다음, 저 부분의 숫자를 조작해서 약간 통통할 정도로 주전자를 확장시켜 주세요.
약간 음수가 나오면 통통해 지네요.

 마음에 들었으면 이제 확인 버튼을 눌러 작업을 끝냅니다.

이제 다시 Polygon버튼을 눌러서 꺼 줍니다.

 오브젝트가 확장되었습니다.

 

4. 색을 바꾸고 숨긴 오브젝트 나타나게 하기

색을 바꾸는 것은 쉽습니다.
오브젝트를 선택한 채, 아래 부분의 화살표 부분의 색상을 눌러 검은색으로 바꿔주기만 하면 됩니다. [각주:3]

 

 

이렇게 해서 첫 번째 Pass를 다 그렸습니다.
이제 두 번째 패스 (인 척하고) 를 그려봅시다. 주전자를 한 번 더 그리는 거지요.

이미 정석은 저 멀리 안드로 메다로 갔지만, 그래도 정석이라면 동일한 위치에 주전자를 한 번 더 생성시켜 주는 것일텐데요, 우리는 이미 맨 처음에 주전자를 복사해서 숨겨놨기 때문에 그 주전자를 다시 보여주기만 하면 됩니다.
이제 화면의 '빈 부분에서 오른쪽 클릭' 을 하고, 나오는 메뉴에서 Unhide All을 선택합시다.

주전자가 나왔습니다! 개념상으로 까만 주전자 안에 분홍 주전자가 들어 있는 모양새겠지요!
하지만 까만 주전자가 면이 뒤집혀서 저렇게 보이게 됩니다.

자 정리하자면, 첫 번째 주전자(1pass) 는 확장하고 뒤집어서 까맣게 칠한거고,
두 번째 주전자(2pass) 는 그냥 그린 겁니다.  [각주:4]

좀 많이 두껍게 만들어서 여기저기 뚫린 곳이 보이는군요. 얇게 만들면 거의 완벽하게 보입니다.

 

자, 이렇게 외곽선을 좀 얅게 만들고, 주전자의 폴리곤을 좀 올리고, 외곽선의 색도 좀 바꿔 보고,
안에 있는 주전자에다가 저번 시간에 배운 셀 셰이딩 공식으로 만들어 보면 이렇게 됩니당.

 

 

 

이 방법도 장단점이 있습니다.

- 장점은 일단 균일한 두께의 외곽선을 만들 수 있습니다. 그리고 box와 같은 평평한 오브젝트에서도 제대로 작동합니다.
때문에 일반적인 외곽선 제작 기능은 이걸 많이 사용합니다.

- 단점도 있습니다. 선이 너무 두꺼우면 아까처럼 끊어진 부분이 보입니다. 뒷면이 끊어지거나 오브젝트의 vertex가 끊어진 면에서도 확장할때 문제가 생깁니다. 그래서 일정 이상 두께로 만들기 힘들지요.
그리고 아무래도 오브젝트를 두 번 그리는거라, 부하가 좀 있는 편입니다.
역시 단점도
http://gamedevforever.com/18 에 잘 설명되어 있지요 . 

 

 

  1. 지금은 맥스로 하지만 실무에서는 shader로 짠다는 말입니다. 그치만 어쨌건 max에서 외각선 만들어 보기에는 이 방법도 좋아요 [본문으로]
  2. 프로그래머들이 알아 듣는 용어입니다 '원패스로 그려' '투패스로 그려' ... 물론 투패스로 그리면 같은 오브젝트를 두 번 그리는 거리 부담이 상당합니다. [본문으로]
  3. 사실 메터리얼 에디터를 이용해 하이라이트가 없게 제대로 검은 색으로 바꿔줘야 하지만, 직접 해 보면 외곽선만 나오는 거라 사실 큰 문제 없어서 단순한 방법으로 대충 넘어갑니다. [본문으로]
  4. 본 강의에서는 외곽선에 해당하는 주전자를 먼저 그리고 정상적인 주전자를 나중에 그린다는 것 처럼 말했지만, 실제 실무에서는 픽셀 연산 부하를 줄이기 위해 거꾸로 하기도 합니다. 그래도 결과는 똑같아요 :) [본문으로]
반응형
,
Posted by 대마왕J

Diffuse Warping을 이용한 고급 셀 셰이딩

 

18강입니다! 저번 시간에 이어서 만화같은 툰셰이더를 만드는 얘기를 계속 해 보도록 하지요.

원래는 오늘 외각선을 해버리고 끝내려 했는데, 저번 강의의 리플에 재미있는 얘기가 씌여 있어서... 후후후
계획을 좀 바꿨습니다.

 

마루님 땡큐요 ㅋ

 

 

 

지난 번에는 if 문을 이용해서 1 ~ -1 까지 되어 있던 조명값을
딱! 한 숫자로 나눠서 두 가지 색상으로만 이루어지게 만들었습니다.

일정 숫자보다 크면 흰색을, 일정 숫자보다 작으면 붉은 색을 말이죠. 

그 예제가 아래입니다.  if문을 이용해서, 0보다 크면 무조건 흰색을 내놓고, 0보다 작으면 무조건 붉은색을 내놓으라는 내용이었습니다.

안내놓으면 구워서 먹으리

 

이것 말고  ceil 함수를 이용한 방식도 있었는데,
저번 시간 반응이 별로 안좋아서 설명 안할래요 ㅋ 리플 백개 안달려서 삐쳤뜸.
나 원래 이런 남자임

궁금하면 포프님한테 물어보시덩가 흥ㅋ

흥 난 비싼 남자임

 

 

 

그렇지만 옛정이 있으니 오늘은 다른 방식 하나 더 설명하죠. 요것도 아주 재미있는 방식이예요.
응용도 아주 무궁무진하구요.

일단 시작은 대인배 밸브사에서 발표한 팀 포트리스 논문에서 시작합니다. [각주:1]

 이 논문은 그냥 Diffuse 계산은 너무 썰렁하니까 Warped diffuse를 사용하자는 얘기였습니다.
이 기술이 여기서 처음 사용한 것인지 아닌지는 모르겠지만 제가 본 건 여기가 처음이긴 합니다.
(제가 잘못 알고 있으면 프로그래밍 스승님들 좀 알려주세요 ... )

이 논문에서 그 부분은 다음과 같습니다.

뭔가 줄무늬처럼 생긴 그림이 하나 있습니다.
그리고 '영어' 가 있습니다 .... ............................

 

영어랑 수학 싫어 무서워

어쨌건 위에 설명된 이런 기능을 이용하면

 

이렇게 나온다는 얘기였죠.

 

얼핏 봐서는 이거랑 셀 쉐이딩이랑은 별 관련 없는 것으로 보입니다만... 그렇지 않습니다!
사실 매우매우매우매우매우매우매우  연관이 있어요!!!

일단 주저리 주저리 떠들기 전에, 먼저 구현해 봅시다.

 

 

 

 

Diffuse Warp 구현

 

그러니까 이것은 UV의 구조를 잘 이해하는 데에서부터 시작합니다.

6강을 배웠던 것을 다시 꺼내어 보죠. http://gamedevforever.com/96
6강을 보면 오브젝트에 그림이 입혀질 때, UV 좌표에 따라 그림이 입혀진다고 되어 있습니다.

흐음 그렇군요. 뭐 이제 이거야 아무 것도 아니죠 :D 아하하하하하하

 

근데 여기서 잘 한번 생각해 보세요.

어쨌거나 UV도 float2 의 단순한 '숫자' 란 말입니다.
네 숫자예요.

이미 앞에서도 많이 보셨듯, UV라고 이름붙여진 특별한 무엇을 꼭 받아와서
UV에 집어넣어야 동작하는 것은 아니었습니다.
float2 라면 뭐든지, UV 자리에 집어넣기만 하면 UV인줄 알고 동작한다고 그랬었죠.

즉 뭐가 되던 숫자 2개만 어디서 구해오면 UV를 만들 수 있다... 라는 거란 말이죠.

흐음 ... 알겠어요.

근데

여러분 모두 아시겠지만...

조명 있잖아요 조명...

참 지겹게도 보네요.

 

이거 있잖아요. 이것도 0~1 가 될 수 있잖아요????

-1부터 1인데요? 0부터 1이 아니고.. 라고 하시는 분은 http://gamedevforever.com/233 
"하프 램버트" 부분 다시 보세요!!
*0.5+0.5 를 해 주면, -1~1인 영역을 0~1 로 만들어 줄 수 있습니다.

흐음... 그러니까 저 조명 영역을 UV의 요소로 사용하는 것도 가능하단 말입니다. 0~1만 되면 무조건 쓸 수 있으니까요.
맞지요?

 

 

 

본격적으로 시작해 봅시다.

필요한 것은 두 개입니다. 하나는 warp 시킬 텍스쳐, 또 하나는 Lambert 공식입니다.
그러고 보니 Dot 공식 하나 배워서 참 많을 걸 해 왔군요 ...

 

dot 하나만 대충 배워도 엄청나게 많은게 가능해요...

 

 

 

자아 그럼 첫 번째로, 텍스쳐를 준비합시다.
아래와 같은 텍스쳐를요.
좌측이 어둡고, 우측이 어두운 이미지입니다.  
만들기 귀찮으신 분들은 아래 이미지를 다운받아서 사용하셔도 좋습니다. [각주:2]

이 그림이 3D 데이터에 입혀진다면
 좌측 위는 UV (0,0) 이겠고, 오른쪽 아래는 UV (1,1) 에 씌여지겠죠?
넹넹 좋습니다.

 

 자 그리고 또 준비할 것은, 반도의 흔한 Lambert 연산 공식입니다.
이젠 뭐 몇 번째 하는 거니까 이정도는 눈감고 만드시잖아요?

이번에도 역시  Prevent Negative Result 를 꺼서 음수가 제대로 나오게 만듭시다.

 

 

네 이제 기본적인 준비물은 끝났습니다.

 

그럼 일단 위의 텍스쳐를 불러와서 공에 입혀보도록 할까요.
기존 조명 연산은 끊고, 단순히 텍스쳐를 불러와 공에 입혀 봅니다.
그러면 아래처럼 됩니다.

비치발리볼 돋네....

 

공에 내장된 UV에 배열되다 보니까 저런 이미지가 나왔습니다. 뭐 어쩔 수 없지요. 흠흠. 저게 정상 맞죠 뭐 사실.
그럼 이제 저 공에 들어갈 UV를 직접 ★커스텀★ 으로 만들어 봅시다. Lambert 라이트에서 나온 숫자를 이용해서 말이죠.

 

일단 Lambert 연산에서 LightColor는 더이상 필요 없으니까 그 부분은 날려 버립시다. 우리는 닷 연산된 부분만 필요합니다.

 

지웁시다.

그럼 float 으로, -1~1까지 나오는 dot 값만 존재하게 됩니다.

그런데 우리는 -1~1 이 아니라 0~1 까지의 값이 필요하므로, 하프 램버트에서 사용했던 매직 넘버[각주:3]를 사용해서 0~1로 만들어 줍시다.

 

이제 0~1 까지의 값이 준비되었습니다. 밝은 곳은 1로 나오고 어두운 곳 끝은 0으로 나오겠지요.

이 부분이 좀 이해하기 어려우실 수도 있겠는데 잘 보세요.

UV에서, U가 가로고 V가 세로입니다.

 

 

그리고 위 그림에서, 세로 방향은 별로 의미가 없습니다. 색이 변하는건 가로 방향이지요.
그래서 세로 (V) 는 그냥 상수 0.5를 넣도록 하겠습니다.
그리고 가로(U) 에다가는 위에서 연산한 Lambert 조명 값을 넣는 겁니다.

 

이렇게 다른 값들을 연결해서 UV를 수동으로 만들어 주려면 어떻게 해야 했었지요?

Vector Construct !!! 백터를 조합해주는 이 녀석이 있었습니다 !!! [각주:4]
이 녀석은 숫자1개를 입력해주면 float으로 , 2개를 입력해주면 float2로, 3개를 입력해주면 flaot3로, 4개를 입력하면 flaot4로... 만들어 주는 녀석이었습니다.  

 

 

그러므로 이 녀석을 이용해서 UV를 만들어 보죠.

X는 U와 같으므로, X 에다가 아까 만든 0~1까지 된 dot 연산을 집어넣으면 되겠구요.
Y는 V와 같으므로, Y에다가는 그냥 0.5를 넣으면 될 것 같습니다. [각주:5] [각주:6]

자, 이렇게 UV가 완성되었습니다.

U에는 0~1 까지의 값이 들어가 있고,
V에는 0.5의 값이 들어가 있으므로...

UV는 (0.0 , 0.5) ~ (1.0, 0.5)  까지의 값이 나오게 되는 겁니다.
그림으로 보면, 아래 그림에서 텍스쳐의 가운데를 질러가는 빨간 화살표와 같겠죠.

 

 

 

그럼 이렇게 완성된 UV를 아까 텍스쳐의 UV 입력에 집어 넣어 볼까요?

 

짜잔

 

우와! 셀 쉐이딩이 완성되었습니다!!! 조명 방향에 맞춰서, 그림에 그려진 대로 음영이 표현됩니다!!!

굳이 말하자면 "Diffuse Warp를 이용한 custom texture 방식의 셀 세이딩" 정도 될까요. 텍스쳐가 UV에 맞추어 입혀진다는 것을 바탕으로, UV를 빛의 밝기에 맞는 방향으로 만들고, 조명 대신 텍스쳐를 입혀 놓았다고 말할 수 있겠네요

보통 이런건 공으로 보면 안이쁘죠. 그래서 주전자에 입혀보면 이렇습니다. 좀 더 이쁘네요 :)

 

오오 확실히 공보다 주전자가 낫습니다. ㅎㅎ

 

 

 

이렇게 해서 또 하나의 셀 셰이딩 표현 법을 알아봤습니다. 오늘 강의 끝!!!

 

아이 좋아라

 

 

 

 

 

 

 

... 하려고 하려 했는데,

 

뭔가 이상한 것이 보입니다.

 

 

 두둥.

 

이게 뭐시여. 왠 점이여...

 

네 점이 보입니다. 난데없이. 이게 왜 생긴 걸까요? 어떻게 없앨 수 있을까요?

 

 

점을 없애 봅시다.

 

점을 없애봐라 민소희

 

뭐 사실 조작은 간단합니다. 별거 아닙니다. 원리도 간단합니다.
일단 이렇게 된 이유부터 알아야 겠지요?

texture는 보통 기본 옵션이 wrap 옵션입니다.
Wrap 옵션이란건 프로그래밍적 용어고, 3D max 에서는 'Tile' 이라는 옵션으로 존재합니다.  
아래와 같이, 텍스쳐의 Tiling 수치를 준 다음에 보면 텍스쳐가 연속해서 사방에 계속 찍어진다는 것을 볼 수 있겠지요.

그리고 이 Tile 옵션을 끄면 이렇게 한 장만 나오게 됩니다.

3D max에서는 이렇게 되어 있습니다만... 게임에서는 비슷하지만 좀 다릅니다. 그건 나중에 설명하고.

어쨌건 'Wrap' 옵션이 타일링 되는건, 게임이나 3D max나 똑같습니다. 그러므로 우리가 입힌 텍스쳐도 사실 이렇게 계속 중복되어 있다고 볼 수 있는거죠. 기본이 Wrap 이니까요.

 

굳이 억지로 그림으로 표현해 보자면 이렇게 생겼단 말이겠죠. 사방팔방으로 계속 연속된.... 검은 외각선은 구별하기 쉬우라고 그렸을 뿐입니다. 사실 저 외각선은 없겠죠.

그러므로 가장 어두운 색 옆 색은 가장 밝은 색이고,

가장 밝은 색 옆 색은 가장 어두운 색이 다시 인접하고 있는 겁니다.

 

 

그럼 이제 아까 우리가 만든 UV를 보죠. 우리가 만든건 0~1까지의 float 입니다.


그런데 이 float이 그렇게 작은 수가 아니예요. float의 단계가 얼마나 된다고 생각하십니까?
float 의 범위는 10진수로 하면 10의 38승이나 된데요. 소숫점으로 하면 소숫점 아래 6자리의 정밀도지요.
사실 실제 쓸 때는 부족하기도 하지만, 일반적인 생활에서는 굉장히 넓은 값입니다.

그런데 우리가 그린 이 음영 그림은 그렇게 크지가 않지요. 실무였다면 기껏해야 가로 256 사이즈나 그렸을까요? [각주:7]

그렇다보니까 이미지가 아무래도 좀 번지게 됩니다. 그러다보니 UV 영역이 딱 끝나는 경계선 부분에, UV의 다른 쪽 부분의 찌꺼기가 '번져서' 침범해 올 수도 있다는 겁니다. [각주:8]

3D 게임은 2D와 달라서, 픽셀로 딱 맞게 끝나는게 아니거든요... 아아 그렇군요 ㅠㅠ


 

 

하지만 걱정하지 마세요. 이런 것 때문에 만든 해결책이 있습니다.
아까 max에서 본 Tile 옵션을 끄는 것 같은 해결책 말이죠.

 

 

 

 

일단 텍스쳐 노드를 선택하고, 여기에 있는 Address 옵션을 보면 Wrap으로 되어 있는 것을 볼 수 있습니다.

 

이걸 CLAMP로 바꿔 주면 됩니다! [각주:9]

 

그럼 어떻게 되냐면요.  

Wrap이던 기존 텍스쳐의 '연속' 옵션 기능이

이렇게 바뀌게 됩니다! 마지막 픽셀을 좌아악 이어가는 것이죠! 이것이 3DMax의 타일링 옵션을 끄는 것과 다른 점입니다.
즉 이 CLAMP 옵션을 쓴다면, 밝게 끝나는 부분은 그 밝은 색을 받아서 주우욱 늘어나고, 어두운 부분도 주우욱 늘어단다는 겁니다. 즉  어두운색----->밝은색에서 다시 어두운색 ----> 밝은 색 이 아니라,
어두운색-----> 밝은 색 옆에는 주우우우우욱 밝은 색... 이 되는 것이지요!
이렇게 되면 다소 오차가 생기더라도, 색이 침범하는 일은 없어집니다!!!

 

멋집니다.

그래서 이렇게 단순하게 CLAMP옵션을 켜고 다시 오브젝트를 보면.

 

 

멋지니까 크게 올려야징 ㅋ

와아아아아아아아아아앙

이제 정말 문제가 없습니다 ㅠㅠ 쥘쥘

이번에야말로 정말로 끝입니다. 수고하셨습니다.
이제 아티스트한테 저 텍스쳐를 주기만 하면, 알아서 이쁜 셀셰이딩을 만들 것입니다 이히힛 
우리 아티스트들은 이런거 짱 좋아하거든요.

 

이런거 만들어 주면 아티스트의 표정이 이렇게 바뀌어요. ㅋ

 

 

 

 

참고로, 이 기능은 단순히 셀 셰이딩이 아닌 일반적인 라이팅의 개선에도 사용할 수 있습니다.
빛이 넘어가는 부분의 색상을 완전히 제어할 수 있기 때문에 Fake SSS 에서도 사용할 수 있고, 있지도 않은 역광을 만들 수도 있으며, 조명 연산과는 전혀 다른 색감의 이미지를 만들 수도 있습니다.

단, 아무래도 텍스쳐를 한 장 더 샘플링 한다는 부담이 있다는 건 확실합니다만....
잘 쓰면 정말 독특한 느낌을 맘대로 줄 수 있지요.

 아래 이미지는 ,같은 셰이더에 같은 라이트에
Warp 텍스쳐만 바꿔서 구현해본 이미지입니다.

이렇게 말이죠

 

 

18강.SFX

 

그럼 다음 시간에는, 진짜로 외곽선을 만들어 보도록 하겠습니다.

여러분 그럼 다음 시간까지 안녕~

  1. 이분들은 자신들이 개발한 기법들을 몽땅 다 발표하기로 유명한 분들이라서 대인배라 불립니다. [본문으로]
  2. 이 이미지는 공부를 위해서 만들었습니다. 사실 세로는 1픽셀만 되어도 충분하고, 가로는 2의 제곱으로 만들어 주는게 게임에서 사용하는게 가장 좋겠지요. 뭐 지금은 아무렇게나 만들어도 됩니다. [본문으로]
  3. *0.5+0.5 [본문으로]
  4. math 항목의 맨 아래에 VectorConstruction이라고 있습니당. 설마 벌써 잊으신건 아니겠지요? 이전에 UV 컨트롤 할때 해봤는뎅 [본문으로]
  5. 사실은 그냥 0~1 사이 아무 값이나 넣어도 됩니다. 세로니까요. ㅎ [본문으로]
  6. 아래 글 보면 constant를 하나만 만들어서 세 군데에 연결한걸 보실 수 있으실 겁니다. 이건 상수가 필요한 3개의 부분이 모두 0.5가 필요한 관계로... 하나만 만들어서 연결해준 겁니다. 각각 따로 만들어도 상관 없습니다 ㅎ [본문으로]
  7. 지금 위의 저 그림도 가로 630 밖에 안되는 녀석이기도 하구요. [본문으로]
  8. float 을 사용하면 이런 오차들, 자주 보게 됩니다. float의 정밀도도 그다지 믿을만한 놈이 못 되거든요. [본문으로]
  9. 사실 여기서는 U만 바꿔줘도 됩니다. 그냥 버릇이 되어서 다 바꿨... [본문으로]
반응형
,
Posted by 알 수 없는 사용자

오픈 전날 저녁 남아 있는 버그 목록을 보는 각 팀장들

smh_o_GIFSoup.com

 

 

 

 

 

 

 

 

 

저녁부터 새벽까지 QA팀

tumblr_me29kjArb81rpj04no1_500

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

저녁부터 새벽까지 개발팀

csfsdc_o_GIFSoup.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

그 와중에 몇몇 사람들

gravity-falls-gnome_o_GIFSoup.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

마지막 중요 버그를 수정해 QA팀에 전달하는 개발자

tumblr_lk161mWoM91qclt3z

 

 

 

 

 

 

 

 

 

 

 

 

 

새벽 3시 수정됐다는 중요 결함이 수정되지 않았다고 개발팀에 급히 전달하는 테스터

tumblr_ma9dp4MKGY1r2knh6

 

 

 

 

 

 

 

 

 

 

 

 

 

버그가 수정되지 않았다는 보고를 받은 개발자

scared-finn_o_GIFSoup.com

 

 

 

 

 

 

 

 

 

오픈 전 드디어 중요한 버그가 모두 수정된 것을 확인한 개발팀과 QA팀

dance-of-joy_o_GIFSoup.com

 

 

 

 

 

 

 

 

 

 

 

 

 

드디어 게임 오픈 그리고 서버 다운을 지켜보는 운영팀

tumblr_mdnghflfHn1r2gxlo

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

서버 다운을 보고 받는 개발자

tumblr_mdxfz4DbSN1qbtb8qo1_500

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

동접 기록을 보고 받는 사업팀

tumblr_m8iv6rFwvb1qbrt0b

  

2013년 새해 인사겸 웃어보자고 만든 자료입니다.

모두 올해 하고 있는 일들 만들고 있는 게임들 잘 되시길 바랍니다. ^^

tumblr_m56tvsWlon1r97a4b

 

 

 

 

 

 

반응형
,
Posted by 알 수 없는 사용자

게임과 확률의 관계는 꽤 밀접하다. 과거 PC게임이 없던 시절에도 사람들은 RPG를 즐겼다. D&D라고도 불리는 이 게임은 사람들이 테이블에 둘러앉아 판타지 소설에 나오는 직업들(전사, 마법사, 성직자등등)을 각자 맡아 진행자가 들려주는 이야기의 모험을 즐기는 게임이다.

Welcome to the D&D World!

Welcome to the D&D World!

이 게임을 진행시키는 가장 중요한 요소는 주사위이다. (D&D에서 사용되는 주사위는 6면체 말고도 8면체부터 21면체까지 다양하다.)

tumblr_maoeeqchfX1rh6vpho1_500

나누고 나누고 나눠 봅시다.

주사위를 굴려 나온 숫자에 따라 전투가 진행되고 이야기의 흐름에 적절한 방해도 받고 하는 것이다. (적절한 방해와 장애물은 이야기에 몰입하는데 매우 중요하다.)

이러한 주사위 확률 룰은 그 뒤 D&D가 PC의 RPG게임으로 변하면서도 계속 유지되어 오고 있는 중요한 요소이다.

확률은 매우 중요한 게임 요소이다. 그리고 게임 외적으로도 중요한 요소이기도 하다.

그렇다면 이러한 확률은 어떻게 테스트를 할까?

테스터에게 이런 과제가 주어졌다.

“고블린 사냥을 성공 했을 시 ‘고블린의 귀’ 아이템이 1/10 확률로 받게 되어 있다. 고블린의 귀가 1/10 확률로 받을 수 있는지 확인해 달라.”

테스터는 고블린을 10번 사냥했고 ‘고블린의 귀’ 아이템은 안타깝게도(?) 3개가 나왔다.

그렇다면 테스트 결과는 실패한 것일까?

테스터는 생각한다.

테스터는 생각한다.

아니다. 확률에 대한 코드는 정상적으로 동작했고. 그 결과. ‘고블린의 귀’ 아이템은 나오거나. 나오지 않는 결과가 나온 것이다.

확률 코드에 대해 좀 더 구체적인 결과를 얻고 싶다면 1/10 과 1/100 확률이 나오는 테스트를 할 것이 아니라 1/10, 10/10 에 대한 확률을 테스트 하는 것이 좋을 것이다.

위와 같은 테스트 통해 테스터는 다음과 같은 결과를 얻을 수 있다.

1/10 – 1,2번의 당첨

10/10 – 10번의 당첨

경계값을 좀 더 고려하고 싶다면 9/10을 추가 할수도 있다. 받을 때보다 못 받는 경우가 더 적어야 정상이다.

그리고 테스터는 확률 코드가 정상임을 확인 할 수 있다.

아마도 확률의 이런 부분에 대해 “아니 그럼 이 희귀템이 정말 서버 통틀어 하나 정도면 나와야 하는데 확률을 못 믿으면 어떻 하나요?” 라고 생각 할 수도 있다.

어... 그건.. 그러니까..

어… 그건.. 그러니까..

정말 서버 통틀어 하나만 나와야 하는 희귀 아이템이고 제약에 대한 부분이 필요하다면 확률 외에 해당 아이템이 한번 이라도 나오면 그 뒤로는 나오지 않는 조건이 코드에 추가되어야 한다.

나는 실제로 그런 상황을 본 적이 있다. 이벤트로 확률에 의해 당첨되는 아이템이 확률에만 의존하여 기획자의 의도와 다르게 생각했던 수량보다 더 나간 것이다. 아마도 수량의 제약까지 있었으면 문제는 발생하지 않았을 것이다.

 

한번 확률만 있어도 되는 경우와 확률과 제약이 같이 있어야 하는 경우를 나눠 보았다.

확률만 있어도 되는 경우

전투 시의 확률 (공격율,방어율,회피율)

파티 플레이 시 루팅 확률

루팅되는 아이템이 밸런스상 기획자의 제약 안에 있지 않아도 되는 경우

 

확률과 제약이 같이 있어야 하는 경우

이벤트 시 당첨되는 상품 수량이 제한되어 있을 경우

루팅되는 아이템이 밸런스 상 기획자의 제약 안에 있어야 하는 경우

 

P.S 디아블로 같은 게임은 유니크템이 떨어지는데 제한이 있지 않다. (디아2 말기 그 귀한 조던링이 뭉치로 돌아다녔다.) 결국 제한을 거느냐 마느냐도 해당 게임의 게임성에 따라서 기획자가 정할 일이다. 가정으로 서버 하나에서 모든 유저들이 최고의 무기를 가지기 위해 서로 싸우는 게임이 있고 그 무기가 조던링같이 루팅이 된다면 모든 유저들에게 해당 게임을 하는 목표가 사라지기 때문에 안 될 것이다.


P.S2 아이구 오랫만에 글을 쓰네요. 최근에 게임 오픈 시키고 주말 모니터링차 회사 나와서 겸사겸사 글을 작성했습니다. 앞으로 시간이  나는대로 다시 글 올리도록 하겠습니다. :)

반응형
,
Posted by 대마왕J

간만입니다. 우후후

연재가 늦은 이유는 여행을 좀 갔다와서 .. .후후후

 

상하이의 야경은 좋군요.

 

 

대륙의_문화컬쳐.jpg

 

 

자 그러면 오늘은 또 재밌는걸 해보요 우후후
오늘 할 건 이겁니다.

File:Toon-shader.jpg

툰 셰이더! [각주:1]

그렇습니다. 만화처럼 나오게 만드는 저 셀 셰이딩. 저걸 해 보도록 하겠습니다.
보통, shader의 진짜 강점을 아티스트들이 매우 표면적으로 느끼게 되는 순간이 저걸 하는 순간이지요.

 

그럼 일단 만화처럼 보이는 툰 셰이딩에 대해 생각해 봅시다. 툰 셰이딩은 어떤 특징을 가지고 있나요?

1. 외곽선이 있다

2. 음영이 2~3 톤으로 되어 있다.

 

물론 아닌 경우도 있지만, 보통 저런 식으로 되어 있습니다.

이것은 셀 에니메이션의 특성상, 투명한 합성수지에 애니메이션 캐릭터를 그릴 때 그림자를 부드럽게 그려서 작업하면 효율이 너무나 떨어졌기 때문에 대량 생산을 위해 만들어진 방식으로, 게임에서는 굳이 이 방식을 사용할 이유는 없지만 이 방식을 흉내내서 셀 에니메이션 처럼 보이게 하는 방식이지요. [각주:2]

일단 첫 번째로 외곽선은... 지금 설명하기에 좀 이릅니다. shader FX로 실습하기 좀 까다로운 면이 없지 않거든요.
그래서 실습하려면 shader가 아닌 MAX의 기능을 좀 이용해야 합니다.

일단 뭐 외곽선에 대한 이론은 여기를 보시면 됩니다.

http://gamedevforever.com/18

그래서 외곽선은 다음 시간에 합니다.
왜냐하면...

귀찮으니까요.

 

그러니 일단 오늘은 음영을 구현하는 것만 해 보죠.

 

음영이라... 음영을 ... 셀 에니메이션에는 2도나 3도 쯤 단계로 하잖아요?
우리도 그걸 만들어 보죠. 어떻게 하면 될까요?

다시 이 그림에서부터 시작해 봅시다.

이 그림을 좀 더 자세히 보면요..

 

뭐  이런 거 아니겠습니까. 1.0 ~ -1.0 까지의 음영의 변화 말이죠. 요런 식으로 숫자로 되어 있다는거, 다 아시잖아요?

이제 이걸 셀 에니메이션 스타일로 만드는 것은 아주 간단합니다.

... 자, 생각해 보죠.

1.0~0.7 까지를 흰 색으로 칠하라고 하고
0.7~ 0.0 까지를 회색으로 칠하라고 하고
0.0 ~ -1.0 까지를 검은색으로 칠하라고 할 수 있다면?

 

네 이렇게 몇 단계로 나눠서 강제로 색을 지정할 수 있다면... 그렇습니다. 그렇다면 방법이 뭔가 보이지요?

 

 

자, 간단하니까 실습해 봅시다.

그럼 이제 간단하게 답이 나온 것 같으니까 실습을 한 번 해 보도록 하죠.

일단 먼저 필요한 것은 흔하디 흔한 램버트 공식의 조명입니다.

 

흔합니다. 근데 Prevent Negative Result는 꺼주세요

Prevent Negative Result가 켜져 있으면 음수가 전부 0으로 바뀌므로, 이런 특이한 작업을 할 때는 꼭 꺼 누는 것이 좋습니다. 

 

그럼 여기서 아까 이론대로 만들어 보죠

드디어 if문의 출현입니다.

프로그래밍 모르신 분들도 if 문에 대해서는 들어보셨을 겁니다. 이런걸 '분기문' 이라고 하죠.

'만약 ~ 하면 ~ 하고 아니면 ~ 해라' 뭐  이런 식입니다.

제가 셰이더 처음 배울때만 해도 if문을 쓰면 대박 느려지니까 쓰지 말라고 했지만, 요즘엔 뭐 그래픽 카드 성능이 좋아져서 그런거 신경 안쓰나 봅니다.

자 그럼 if문이 어딨을까요?

 

요기있지요

일종의 연산이니까 Math에 있는거죠. IF then Else 라고 씌여 있지요?
이 말은 단순히 IF 문으로 끝난다는게 아니라 Else 까지 되어 있다는 말이지요. [각주:3]

그럼 if 노드의 구조를 보겠습니다.
조금 어려우니까 크게 보죠.

 

 

일단 if A = B 라는 그림이 있지요? 이것은 "만약 A와 B가 같을 때" 라는 의미일 겁니다. 네 그렇죠.
입력 (InputA / B) 는 float 값을 받고,
출력(Output 1/2) 값은 아무거나 나갑니다.

그리고 Input A 가 있고 Input B 가 있습니다.
즉 이 Input A 와 Input B에 같은 값이 들어가면 결과는 '참' 이라는 것입니다.

그렇다면 이렇게 '참' 일 경우에는 뭘 뱉어낼까요? (출력해 낼까요?)

참일 경우에는 Outout 1 을 출력해 냅니다! 무슨 값을 출력해 낼지는 지금은 모르지요. 저기에 어떤 값을 연결하느냐에 따라 다르겠지요.

그렇지만 거짓일 경우에는? Output 2를 출력해 낼겁니다! 즉 Output 2 에다가는 거짓일 경우에 출력할 값을 내놓으면 되겠지요.

 

이게 뭔소리야...

 

네, 조금 어려운 설명이 나오니까 머리아파하시는 분들이 약 296분쯤 계시는군요.

말로 하니까 좀 힘들어요 확실히. 그래서 퀴즈를 내 보겠습니다.

 

자아. 위와 같은 그림이 있습니다 .

Input A와 B에는 각각 1이라는 숫자가 들어갔습니다.

Output 1과 2에는 각각 흰색과 붉은 색이 들어갔구요.

그럼 이 상태에서 출력되는 색상은 흰색일까요 붉은 색일까요?

답은 다음 블럭을 긁으시면 나옵니다.

답은 흰색입니다. A 에 들어간 숫자도 1이고 B에 들어간 숫자도 1입니다. 즉 A=B 라는 말은 '참' 이 됩니다.
그러므로 '참' 에 해당하는 '흰색' 이 출력되겠지요.  

 

두 번째 문제입니다. 이번엔 조건이 바뀌었습니다 ! A=B 가 아니라는 점을 주의하세요!

다음 경우에는 무슨 값이 나올까요?

 

역시 답은 다음 블럭을 긁으시면 나옵니다 .

조건을 보시면 A가 B보다 크다라고 합니다.
그런데 조건을 보시죠 A는 1이고 B는 2입니다.
A>B 라는 조건인데, 1>2 이라는 거죠. 이게 맞습니까? 틀리죠?
그럼 '거짓' 입니다. 그러면 붉은색이 출력될 겁니다!!

자, 이렇게 if문에 대한 기본 개념이 끝났습니다.

if문의 조건식은 이렇게 한 두 개가 아니라, 여러 개가 있습니다.
if 노드를 선택하고 메뉴를 보시면 선택할 수가 있지요

 

 

무슨 메뉴가 있는지 봅시다

Equal (A==B) : A와 B가 같을 때 [각주:4]
Greater Than (A>B) : A가 B보다 클 때
Less Than (A<B) : A가 B보다 작을 때
Greater or Equal (A>=B) : A가 B보다 크거나 같을 때
Less or Equal (A<=B) : A가 B보다 작거나 같을 때
Not Equal (A!=B) : A와 B가 같지 않을 때 [각주:5]

전부 다 필요하지는 않겠지만 3-4개 정도는 쓸모가 있을 것 같네요.

자 이제 if문에 대한 모든 걸 알았습니다. 이제 본격적으로 작업을 시작해 보죠

 

사실 어려워요. 풋. 어렵지 않다고 하는건 다 거짓말이예요. 이걸 알아들은 당신들이 천재일 뿐이예요. 후훗.

 

작업을 시작합시다.

일단 if문에 들어가는 숫자가 float 이라는것은 중요합니다. 한 자리의 숫자가 들어간다는 거지요.
다행히 dot공식에서 출력되는 숫자도 한 자리의 float 숫자입니다.

그러므로 여기에다가 끼워 주면 좋겠지요 [각주:6]

 

바로 저기가 1~ -1 까지 값이 나오는 그 구간이잖아요. 색이 곱해진 다음은 값이 순수하게 되지 않기 때문에 그 전에 해야만 합니다 .

 

자 저기에 if문을 넣죠

이렇게 만들어 봅시다.

 

위의 노드를 해석해 보겠습니다.

일단 A 에 입력된 값은 dot공식입니다. 1에서부터 -1 까지의 값이 들어오겠지요.
B에 입력한 값은... 0으로 했습니다. 즉, A 값이 0보다 크면 참이란 말입니다. 현재 이런 상태입니다.

그리고 출력값은, 참일때 흰 색으거짓일 때 (A값이 0보다 같거나 작으면 거짓) 에는 붉은 색이 나오게 만들어 진 것입니다.

 

이 그림을 다시 보시면, 어디가 흰 색일지 어디가 붉은 색일지 알 수 있으시겠지요?

자 이렇게 해서 ... 출력을 최종 색상 출력에 연결해 줍시다.

 

짜잔.

 

 

오오 셀 셰이딩입니다!!!! 만화처럼 나와요!!! 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만 외곽선은 아직이지만

 

기분이 좋아지는군요. 이걸 한 번 더 응용하면 두 단계도 가능할 듯 합니다! 해볼까요!!!

 

 

 

근데... shader FX에서는 안됩니다 (OTL)
음영을 두 개로 주는게 안된다고요. 하나밖에 안됩니다. 흐규흐규

이런게 노드 구조의 한계에요.

셰이더를 직접 코딩한다면 이렇게 하면 돼요
if (A>0)
 { 흰색을 내놓아라 }
else if (A>-0.5)
{ 뻘겅색을 내놓아라}
else
{검은색을 내 놓아라}

이런 식으로 if문을 여러 번 거치게 할 수 있어요. 혹은 if문 안에 if문을 넣을 수도 있어서, 이론적으로는 무한대로 계산하게 할 수 있구요.

하지만 노드는 안돼요 OTL 노드는 정해진대로 써야만 하니까요. 아니면 else if 노드를 만들어 준다던가...
이런 식으로 제약이 있을 수 밖에 없는게 노드 구조입니다. 어쩌겠습니까. 그래서 아티스트용이라는 거지요. 사실 최적화도 안좋고 해서, 코딩 좀 해보면 정말 별로인 구조예요 ㅎㅎ

하지만 즐겁거든요 ㅋ

뭐 어쨌건 결론적으로 shader FX에서는 if문은 한 번 밖에 못쓰게 되는군요. 그러므로 2단계 외에는 안되겠습니다. 아쉽네요.

 

추가로 pope 스승님 책에서 보면 ceil 함수를 이용해서 하는 법이 있습니다. 이걸 이용하면 여러 단계로 만들 수 있어요.
shaderFX에서도 동일한 노드가 있습니다.  이름이 좀 달라요. "Round" 라고 하는 노드입니다.
이 노드 옵션에 보면 Round UP(Ceil) 이라고 하는 올림 기능이 있습니다. 이걸 이용하면 포프님 책에서 있는대로 똑같이 만들 수 있어요.
근데 왜 그걸로 안했냐고요? ... ㅋㅋ
그건요.. .그건 너무 기계적으로 일정 비율마다 딱딱 끊어주는거라 안이쁘거든요 OTL
아티스트들은 원하는 곳에 끊고 싶어하니까요. ㅋㅋㅋ 그래서 안했어요.
게다가 색상도 맘대로 집어 넣을 수도 없구요..

그래도 혹시나 해보고 싶은신 분들은 노드를 공개해 드릴테니까 참고해서 해 보세요 :)

 

[각주:7]

 


 

그럼 다음 시간에는 외곽선에 대해 해보는 것을 목표로 잡아 보도록 하겠습니다.
아마 shader FX 보다는 MAX 시간이 되지 않을까 싶지만.. 뭐.. 어쨌건..

 

단신:

유니티에 플러그인 식으로 들어가 있는 노드 구조의 shader 에디터인 SSE 라는 녀석이 있습니다.
shaderFX보다 무척 안이쁘지만 그런대로 쓸만한 녀석이라 그 녀석으로 연재를 할 수 있을까 싶어서 봤습니다만
몇 가지 치명적인 단점 때문에 안하고 있었는데요,
이번에 유니티 코리아의 더스틴 스승님께서 SSE를 친히 개조해 주셔서 잘 하면 쓸 수 있게 될 것 같습니다.
조금 더 만져보고 괜찮으면 다다음 시간부터 한번 그걸 연재해 볼까 생각하고 있습니다.

  1. 뭐.. 셀 셰이딩이라던가 등으로 불리기도 합니다. [본문으로]
  2. 요즘에는 이런 전통적 방식의 셀 셰이딩 외에 새로운 느낌으로 응용된 셀셰이딩도 사용되곤 합니다. [본문으로]
  3. 뭔 소린지 모르겠으면 그냥 그런가보다 하세요 [본문으로]
  4. 어째서 A=B 가 아니라 A==B인지 궁금하신 분들이 계실 겁니다. 프로그래밍에서 등호 = 는 오른쪽의 값을 왼쪽에 집어 넣으라고 하는 명령어입니다. 그래서 같다라는 의미로 사용할 때에는 두 개를 써서 == 이렇게 표현합니다. 나중에 코딩할때에도 매우 유용한 상식이므로 알아두면 좋습니다 [본문으로]
  5. 이것 역시 유용합니다. "같지 않다"라고 하는 ≠ 이 표시는 특수문자이기 때문에, 프로그래밍에서는 != 라고 표현을 합니다. 여기 있는 표현 모두 프로그래밍 에서 쓰이는 표현이므로 매우 유용합니다 :) [본문으로]
  6. 그냥 따라하지 말고 왜 그런지 생각하고 해요!!! [본문으로]
  7. 보고 분석이 잘 안되시면... 혹시 뭐... 위 노드에 대해 해설해 달라는 리플이 100개쯤 달리면 또 모르죠.. 후후후 [본문으로]
반응형
,
Posted by Junios

크런치 타임에 겹쳐서 올려야 하는데

못 올리고 아는게 없어서 공개 할 내용이 그닥 없네요 ㅠ.ㅠ

넘 초보 내용뿐이 그래서 이번에 올리는것도 초보적인 싱글턴 클래스 입니다.

C++를 사용하면 많이들 쓰실테고 현재는 Unity3D를 사용중인데 

다덜 싱글턴 클래스를 상속이 아니라 만들어서 사용들 하시는거 같아서 사용해서 싱글턴이 되도록 만든 간단한 클래스입니다.


using System;

public class Singleton<T> where T : class, new()
{
	public static T Instance
	{
		get;
		private set;
	}

	static Singleton()
	{
		if (Singleton<T>.Instance == null)
		{
			Singleton<T>.Instance = new T();
		}
	}

	public virtual void Clear()
	{
		Singleton<T>.Instance = null;	
		Singleton<T>.Instance = new T();
	}
}


사용법은 아래와 같이


/*예제*/
class Sample : Singleton<Sample>

별거 없지만 도움이 되시길 바라며.


다음에는 더 좋은 내용을 올릴께요. ㅠ.ㅠ

반응형
,