Technology[Front]

3D맵 구현하기 - light 제어하기

Thunderland 2022. 2. 28. 09:13

미로에서 모든 빛을 제거하고 캐릭터의 주변에서만 빛을 생성하여 미로탈출 느낌을 부여하는 방법에 대해 알아보겠습니다.

 

(1) test.js

 

      let light;
      let LightHelper;
      
      //라이트 설정
        light = new THREE.SpotLight(0xFFFFFF, 2);
        light.position.set(0, 100, 0);
        light.target.position.set(0,0,0);
        light.angle = THREE.Math.degToRad(50);
        light.penumbra = 1;
        
        scene.add(light.target);
        scene.add(light);
        
        LightHelper = new THREE.PointLightHelper(light);
        scene.add(LightHelper);
        
        Update(timeInSeconds) {
        
          const x = this._camera.getWorldDirection(cameraDirection).x;
          const z = this._camera.getWorldDirection(cameraDirection).z;
          
          if(light) {
              const smallSphere = controlObject.children[0];
              smallSphere.getWorldPosition(light.position);
              light.position.x = controlObject.position.x + Math.sin(this._camera.rotation.y)*5;
              light.position.y = 5;
              light.position.z = controlObject.position.z + Math.cos(this._camera.rotation.z)*5;
              if(LightHelper) {
                LightHelper.update();
              }
              if(light.target) {
                light.target.position.set(x*500, this._camera.getWorldDirection(cameraDirection).y*500, z*500);
              }
            }         
        }

위의 코드에서 LightHelper의 경우 빛의 광원을 화면에 보여주는 도우미로 코드 구현 시 도움을 주는 역할만을 수행하므로 추후 실제 구현시 삭제해주시면 됩니다. light는 THREE.js의 SpotLight를 사용했으며 해당 광원은 특정 target이 존재하고 해당 target을 현재 position에서 비추는 광원입니다. 해당 광원을 생성할 때 첫 번째 인자로 빛의 색을 지정했으며 두 번째 인자로 숫자를 지정하고 해당 숫자의 크기에 따라 빛의 세기가 달라집니다. 이후 해당 광원의 위치를 position.set을 이용해 지정하고 target의 위치 또한 position.set을 이용해 지정합니다. 이후 빛의 각도와 비추는 빛의 원형크기를 angle과 penumbra 속성을 이용해 지정하고 scene에 light와 light의 target을 추가하여 화면에 생성합니다. LightHelper 또한 scene에 추가합니다. 이후 매초 실행되는 Update가 수행되는 함수에서 light가 현재 존재한다면 controlObject(움직이는 캐릭터)의 children[0]을 가져와서 캐릭터의 현재 position을 저장하고 있는 변수를 생성하고 이를 getWorldPosition메서드를 이용해 광원의 현재 위치에 캐릭터의 현재 위치를 대입합니다. 이후 light.position을 이용해 현재 광원의 위치가 캐릭터의 위치와 동일한 게 아니라 일정부분 떨어져서 비추기 위해(정확히 위치가 동일할 경우 광원이 해당 위치에서 target을 비추기 때문에 캐릭터는 어둡게 보입니다.) light.position의 x,y,z 속성을 이용해 camera의 rotation 정도를 sin, cos메서드로 움직이는 캐릭터와 일정부분 거리를 유지하며 target을 비추게 지정합니다. 이후 LightHelper가 존재한다면 update 메서드를 이용해 광원의 현재 위치를 업데이트하고 light.target이 존재한다면 해당 target을 카메라가 비추는 곳에 위치시키기 위해 camera.getWorldDirection을 이용해 카메라가 보는 각도에 특정 값을 곱해서 target의 위치를 업데이트합니다.

 

이번 게시글에서는 광원이 캐릭터의 주위를 카메라의 이동에 의해 회전하고 target을 카메라가 보는 방향에 위치시켜서 360도 사방에서 해당 캐릭터와 카메라가 보는 위치를 광원이 모두 비추게 만드는 방법에 대해 알아보았습니다.