본문 바로가기

「three.js」턴테이블 카메라 생성하기

by Recstasy 2023. 1. 12.

 

 

 

 

 

three.js에서 카메라를 빙빙 돌려보자. CG포트폴리오 중에서 3D 모델링을 만들어 카메라를 빙빙 돌리는 작품이 바로 이번 포스팅의 주제다. 

 

 


three.js CG카메라 용어

CG 프로그램에서 카메라 속성에는 ' FOV' , 'Depth of Field' , 'Aspect Ratio' , 'resolution gate' 등.. 과 같은 용어들을 볼 수 있다. 우선 CG에서 가장 기본적으로 알아둬야 할 카메라 용어를 정리해보자.

 

아래 사진을 보면, Field Of View를 볼 수 있다. 줄여서 FOV라고 하며, 쉽게 말해 '시야'라고 이해하면 된다. 필자는 FOV를 단순히 '시야'라고 생각한다. 가령, FOV가 클수록 전방 시야가 넓어지기 때문이다. 실제 구글에는 FOV값에 관한 여러 설명 중, '광각' , '망원' , '어안' 렌즈와 같은 분야까지 나오는데 그냥 무시하자. 

 

 

위의 사진에서 Near의 수치가 작을수록 카메라와 피사체 사이의 거리가 짧아지는 점을 알 수 있다. 즉, 'Near'수치가 작을수록 카메라 바로 앞의 피사체를 촬영할 수 있다. 만일, Near수치를 0.1(Default:1)로 한다면, 일종의 '접사'라 할 수 있다. 반면, Far는 어디까지 촬영할 수 있는지를 알 수 있으며, 이는 '망원'을 의미한다. three.js의 경우, 카메라 파라미터 설정에서 Near와 Far 부분의 값에 따라 카메라의 촬영범위가 결정된다. 

 

Aspect Ratio는 아래 사진처럼 '가로&세로 비율'을 의미한다. 가령, 16:9 , 4:3과 같은 설정값이 Aspect Ratio에 해당한다. 

 

 

Three.js에서 카메라를 설정하는 부분은 간단하다. 아래의 공식에 해당하는 파라미터에 값을 넣으면 카메라의 설정이 마무리된다. 자세한 부분은 threejs.org에서 확인할 수 있다.

 

https://threejs.org/docs/index.html?q=camera#api/en/cameras/PerspectiveCamera

 

 

 

 


| three.js 카메라 회전하기

오브젝트 주변을 빙빙 돌아가는 카메라를 만들어보자. 먼저 간략하게 설계한다. (설계라 할 것까지 없지만) requestAnimationFrame 재귀함수에 cos, sin으로 원회전을 하는 카메라를 업데이트 하는 설정이다.

 

let scene, camera, renderer, light1;
let cylinder,sphere,plane;
let ADD = 0.01, default_value = 0;

let createGeometry = function(){}

let init = function(){}

let render = function(){}

init()
render()

 

 

카메라는 x축과 z축의 값으로 Cos( )함수와 Sin( )함수를 넣으면, 회전 운동을 한다. 아래와 같이 자바스크립트 내장함수인 "Math"를 이용해 Math.Cos(default_value)값을 position.x에 넣고, Math.Sin(default_value)값을 position.y에 넣어준다.

 

 

let render = function(){
    
    camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );
    camera.position.x = 40 * Math.sin( default_value );
    camera.position.z = 40 * Math.cos( default_value );

    default_value += add;

    requestAnimationFrame( render );
    renderer.render( scene, camera );

}

 

 

createGeomtry( )함수는 3D 오브젝트들을 생성하며, 여기서는 plane, sphere, cylinder를 씬에 넣고 있다.

 

 

let createGeometry = function(){

    let geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 )
    let material = new THREE.MeshPhongMaterial({
        color: 0x448844, 
        shininess: 100, 
        side: THREE.DoubleSide 
    });

    cylinder = new THREE.Mesh( geometry, material );
    cylinder.position.set( 6, 0, -2 );
 
    geometry = new THREE.BoxGeometry( 2000, 1, 2000 );
    material = new THREE.MeshPhongMaterial({
        color: 0xabcdef, 
        side: THREE.DoubleSide
    });

    plane = new THREE.Mesh( geometry, material );
    plane.position.y = -1;

    geometry = new THREE.SphereGeometry( 5, 30, 30 );
    material = new THREE.MeshPhongMaterial({
        color: 0x693421, 
        side: THREE.DoubleSide
    });

    sphere = new THREE.Mesh( geometry, material );
    sphere.position.set( -5, 5, 2 );    

    scene.add( cylinder );
    scene.add( plane );
    scene.add( sphere );

}

 

 

위의 구현에서 가장 중요한 부분은 Render() 함수다. 카메라는 계속 중점(0, 0)을 보고 있어야 하는데, 이를 위해 (dummy데이터) 3차원 벡터 오브젝트를 생성해준다. 그리고 다음과 같이 lookAt()메서드에 dummy데이터를 넣는다.

 

 

let render = function() {
        
        camera.lookAt(new THREE.Vector3(0, 0, 0));
        camera.position.x = 40 * Math.sin(default_value);
        camera.position.z = 40 * Math.cos(default_value);
        default_value += add;
        
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    };

 

 

카메라의 x, y위치값이 각각 sin, cos운동을 하므로 원회전이 완성된다.

 

 

 

댓글

최신글 전체

이미지
제목
글쓴이
등록일