반응형

오늘 다룰 주제는 맥스의 카메라 와 뷰포트 입니다.

3D 공간의 개체를 보여주기 위하여는 카메라 라고 하는 가상의 개체가 필요합니다. 카메라에 보여지는 대상을 이미지화 하여 사용자에게 보여주는 것(랜더링) 인데요. 실제 카메라가 있는 건 당연히 아니고 카메라라는 개념을 담은 것이죠.

일반적인 뷰포트 역시 가상의 카메라라고 할 수 있는데 화면을 보여주는 방식, 다시말하면 3D 공간의 개체를 랜더링 하는 방식에 따라 크게 orthogonal 또는 perspective 로 나눌 수 있습니다. 

이러한 카메라와 뷰포트를 다루는 예제를 몇가지 오늘 소개해 드릴까 합니다.

 

타겟 카메라 생성하고 위치 설정하기.

물론 카메라를 max UI 를 이용하여 수동으로 생성할수 있지만 스크립트 공부 중이므로 자동으로 생성해 봅니다. 수동으로 카메라를 설정하게 되면 손으로 생성한 뒤 z 축으로 이동하거나 타겟의 위치를 조정해 주어야 하지만 자동으로 생성하면 항상 원하는 각도와 위치에 생성할 수 있답니다.

예를 들면

Teapot01 이라는 개체가 있다고 했을 때 항상 카메라를 XY 평면에서 우하단, Z 위치로 약간 위에서 보는 각도에서 보도록 만들어 줄 수 있습니다. 어쩌면 Teapot 의 크기가 크건 작건 항상 적당한 위치에 생성하는 것도 가능하겠죠. 아래 코드를 봐주세요.

obj = $Teapot01

-- 타겟 카메라를 생성한다.
myCamera = Targetcamera fov:45  pos:[0,0,0] target:(Targetobject transform:(matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0]))
myCameraTarget = myCamera.Target 

-- 대상물의 크기에 따라 카메라 위치를 자동으로 설정해 주기 위하여 tepot 의 radius 를 얻어 온다.
teapotRadius = obj.radius
	
-- 카메라의 위치를 티팟의 우하단으로 위치하고 위로 높이를 조정한다. 
myCamera.pos = [teapotRadius * 4, teapotRadius * -4, teapotRadius * 3] 

-- 카메라 타겟의 위치를 티팟의 중앙으로 설정한다.
myCameraTarget .pos = obj.pos 
	
-- 타겟이 너무 바닥에 있으므로 radius 만큼 올려준다.
myCameraTarget .pos.z += teapotRadius 
	

이렇게 해주고 실행하면 (ctrl+E) 카메라가 하나 자동으로 생성되는 것을 볼 수 있습니다.

자동으로 생성된 카메라

만약 Teapot 이 엄청 크거나 작더라도 아마 비슷한 각도에 생성이 될겁니다.

훨씬 큰 teapot 을 생성하였지만 역시 유사한 각도에 카메라가 생성되었다.

동일한 스크립트로 실행 하였지만 역시 teapot 에 묻히지 않는 위치에 카메라가 생성이 되었습니다.

각도와 거리까지 완전히 동일하게 만들 수도 있지만 약간 복잡한 코드가 필요하므로 나중에 설명 드리겠습니다.

 

 

카메라 회전하기!

카메라 개체 역시 node 에 속하므로 rotate, move 와 같은 일반적인 속성을 제어할 수 있습니다.

그런데 오늘 제가 소개해 드릴 코드는 조금 다릅니다. 

카메라를 대상 피사체가 될 오브젝트를 중심으로 빙글 돌릴 겁니다.

흔히 제품 랜더링 할때 많이 쓰일 법한 샷 인데요. 보통은 물체를 돌려서 360도 촬영을 합니다. 그런데 드라마 씬 처럼 카메라를 빙글 돌려야 한다면요? 손으로 예쁘게 돌게 세팅하기가 쉽지 않습니다. 

자 그럼 어떻게 해야 할까요?

 

중심은 타겟의 위치로 하겠습니다. 회전은 한바퀴 할거고요. 제가 소개해드릴 코드를 이용하면 한바퀴를 돌며 10장을 찍을 수도 있고 100장을 찍을 수도 있습니다.

여기서 삼각함수가 필요한데요.. 음.. 삼각함수라 하면 sin(),  cos() 기억 나시나요? 기억 안나시죠? 

sin 이 0~90 으로 가는동안 값은 0.0 ~ 1.0 으로 변하고요. cos 가 0 ~ 90 으로 가는동안 값은 1.0 ~ 0.0 으로 변한다는 것만 정확하게 기억하시면 됩니다. 또 90에서 180 까지 가는동안은 그 반대의 값이 됩니다.

sin 그래프를 보면 아래와 같습니다.

sin 함수의 그래프

저 구불 구불한 그래프 기억나시나요? 아직 안나신다고요?

네... 기억 못하셔도 상관 없고요. sin cos 을 붙여서 원을 그릴 수 있다는 것만 기억하시면 됩니다.

 

sin cos 을 이용하여 원을 그리는 방법

바로 이렇게요.

 

이해 되시나요? 

 

그래서 우리는 맥스에서 360도를 돌면서 sin cos 에서 받아지는 값에 카메라에서 타겟까지의 거리를 곱해주면 카메라가 원 운동을 하게 되겠죠.

코드를 한번 보실까요?스에서 360도를 돌면서 sin cos 에서 받아지는 값에 카메라에서 타겟까지의 거리를 곱해주면 카메라가 원 운동을 하게 되겠죠.

-- 아까 만들어 두었던 카메라를 이용하겠습니다.
myCamera = $Camera01
myCameraTarget = myCamera.Target 


center = myCameraTarget.pos
distanceFromCam = myCamera.targetDistance

-- 사진을 찍을 랜더링 장 수
step = 12

for xx = 0 to step do
(
          -- sin cos 를 이용하여 원형으로 회전된 위치를 각 단계마다 계산한다.
          camXpos = sin(360.0 / step * xx) * distanceFromCam
          camYpos = cos(360.0 / step * xx) * distanceFromCam
		
          -- 실제 카메라의 위치를 계산된 위치로 설정한다.
          myCamera.pos.x = center.x + camXpos
          myCamera.pos.y = center.y + camYpos
		
          -- 랜더링하여 이미지로 저장한다
          render camera:myCamera outputSize:[320, 240] vfb:false outputfile:("D:\\testRender" +(360.0 / step * xx) as string + ".png" )
)

코드에 생소한 개념 (ventor)이 들어가긴 했지만 크게 어렵지는 않습니다.  위에서 설명 드린 것처럼 sin cos 를 이용하여 카메라의 위치를 설정하고 매 프레임마다 랜더링을 해주는 스크립트 입니다. 

vector 와 render 에 대한 부분은 나중에 별도로 포스팅을 하도록 하겠습니다. 

이렇게 자동으로 랜더링된 이미지를 한번 볼까요? 

12 프레임으로 나누어 랜더링된 이미지들

 

저 코드의 step 개수만큼 랜더링이 되었는데요. 해당 숫자를 24로 하든 36 으로 하든 아니면 360으로 필요하신 만큼 변경하여 랜더링 하여도 아마 잘 랜더링이 될 것 입니다.

에니메이션 등을 주고 임의로 사용자가 회전하는 위치에 따라 랜더링을 한다는건 사실상 엄청나게 귀찮고 힘든 작업이므로 랜더 세팅만 잘 되었다면 이렇게 걸어 놓고 자고 오면 깔끔하게 원하는 만큼 랜더링이 되어 있을 거에요.

 

그럼 선택한 물체로 카메라를 이동 시키는 방법은? 

네.. 간단하죠. 선택한 물체의 pos 를 이용해서 target 을 이동 시키고 이동시킨 만큼 카메라도 이동시키면 됩니다.

objs = getCurrentselection()
obj = objs[1] -- 선택한 오브젝트

myCam = $Camera01
myCam_target = myCam.target

-- 선택한 오브젝트 까지 이동할 거리 
delta = obj.pos - myCam_target.pos

myCam_target.pos += delta
myCam.pos += delta

이렇게 하면 되는 것이죠. 이동할 거리 (delta) 를 구한뒤 타겟과 카메라의 위치에 더해주면 됩니다.

아주 간단하죠?

 

 

타겟은 그대로 두고 카메라 거리만 조정하는 방법

3DS Max 의 타겟 카메라에서 타겟 까지의 거리를 조정하면 카메라는 가만히 있고 타겟만 움직이지 않습니까? 그런데 이게 영 불편할때가 있습니다. 타겟은 가만히 두고 distance 를 조정하여 카메라를 움직이고 싶을때가 있지요.

스크립트로 한번 해당 기능을 만들어 볼까요?

myCam = $Camera01
myCam_target = myCam.target

-- 현재 카메라로부터 타겟까지의 거리
currentDistance = myCam.targetDistance 

-- 이동할 거리 (상대거리)
deltaDist = 50

-- 타겟으로 부터 카메라의 방향
vecCam = normalize(myCam.pos - myCam_target.pos)

--최종 이동될 위치
finalCamPos = myCam.pos + (vecCam * deltaDist)

myCam.pos = finalCamPos

역시 간단합니다. 아직 vector 개념이 없으신 분은 중간에 잘 이해가 안되는 부분이 있으실 텐데요. 역시 나중에 별도로 포스팅하도록 하겠습니다.

deltaDist 값을 음수를 넣게되면 카메라의 위치가 타겟 방향으로 가까워 질겁니다.

위의 코드에 deltaDist 를 바꾸어 테스트를 해본 모습입니다.

물론 UI 에서 이런 기능을 지원하기는 하지만 정확한 거리를 이동하기 위하여는 스크립트 만큼 정확하고 편리한 것이 없기 마련입니다.

 

 

그외의 기능들

물론 카메라의 각종 프라퍼티를 스크립트를 이용하여 조정하는 것도 가능합니다.

orthoProjection 을 true 또는 false 로 설정하여 원근감을 없애고 isomatric 이미지 처럼 만든다거나

FOV 를 조정한다거나 near, far range 를 변경하거나 하는 등의 변경은 아주 쉽습니다.

F1 키를 누르시고 camera 를 검색하시면 친절하게 설명이 되어 있답니다.

 

이상으로 카메라 관련한 스크립트 소개를 마치도록 하겠습니다.

 

감사합니다.

2022.05.31 - [DEV/MAX SCRIPT] - [3ds max script] ray 에 대하여 알아보기

 

[3ds max script] ray 에 대하여 알아보기

가끔 아니 어쩌면 자주 3D 공간안에서 물체의 위치를 지정할때 이 물체가 저쪽에 닿는 면에 딱 위치하고 싶은데... 할때가 있죠? 예를 들면 나무나 돌덩이 이런걸 랜덤하게 막 생성한 다음 굴곡진

diy-dev-design.tistory.com

2021/02/24 - [DEV/MAX SCRIPT] - 3DS MAX 스크립트, 프라퍼티 와 매소드 이해하기

 

3DS MAX 스크립트, 프라퍼티 와 매소드 이해하기

오늘은 3DS MAX script 를 개발하면서 이해하면 도움이 될 용어 두가지를 설명 드릴까 합니다. 바로 property 와 method 입니다. 프라퍼티와 매소드 정도로 발음하시면 됩니다. 도대체 이게 뭐고 왜 이런

diy-dev-design.tistory.com

2020/04/29 - [DEV/MAX SCRIPT] - 3DS MAX 스크립트로 개체 선택하기

 

3DS MAX 스크립트로 개체 선택하기

Max Script 를 이용하여 무엇인가를 하려면 필수 요소라고 할 수 있는 것 중의 하나가 개체를 선택하거나 지정하는 방법입니다. 여기서 개체는 3D Scene 안의 오브젝트, 스플라인, 헬퍼 등과 같은 사

diy-dev-design.tistory.com

2019/12/11 - [DEV/MAX SCRIPT] - 3DS MAX 스크립트로 초간단 다이얼로그 창 , UI 버튼 만들기

 

3DS MAX 스크립트로 초간단 다이얼로그 창 , UI 버튼 만들기

3DS MAX 스트립트를 이용하여 스크립팅을 하기 시작하면 MAX 로 할 수 있는 일이 너무나 많고 빠르게 진행된다는 것을 알 수 있게 됩니다. 이 놀라운 기능들을 스크립트를 매번 실행시키는 것이 번

diy-dev-design.tistory.com

 

 

반응형

+ Recent posts