본문 바로가기
FrontEnd/THREE.js

Light

by oncerun 2023. 5. 6.
반응형

 

Three.js에서 Light를 추가하면 할수록 성능이 떨어진다.

 

그 이유는 간단하다. 빛이 하나 있을 때 버텍스에 대해 버텍스 수만큼만 빛을 처리하면 되는데  빛이 여러 개 있는 경우 모든 버텍스에 빛의 수만큼 곱한 연산이 필요하기 때문이다.

 

그렇기에 빛을 사용할 때 조심해서 사용해야 한다. 

 

기본적인 조명 모델에 대해 알아보자.

 

1. Light Radiation 

 

네온사인, 태양과 같이 자체적으로 빛을 내는 모델이 있다. 그러면 단색으로 칠하기만 하면 된다. 

 

비슷하게 surface Ambient가 있다. 모든 물체가 이 정도의 에너지를 가진다고 가정하는 것이다. 

 

기본적으로 완전히 빛을 차단하는 것은 지구에서 불가능하다. 난반사로 인해 빛의 세기가 감소하더라도 아주 조금이라도 모든 곳에 닿기 때문이다. 

 

물론 우주와 같이 물체가 거의 없어 직진하는 경우에는 빛을 받는 반대 방향은 완전히 빛이 차단되어 검은색으로 보일 순 있습니다.

 

2. Surface Diffues + Light

 

난반사를 표현하는 램버트 모델이 만들어지려면 광원이 필요하다. 표면의 노멀벡터와 라이트 방향벡터를 내적 하여 만들기 때문이다. 

 

3. Surface Specular + Light

 

위 사진의 반짝이는 효과를 만들 수 있다.

 

Light Radiation, Surface Ambient, Surface Diffuse, Surface Specular를 통해 Phong Model을 만든다. 

 

합이 1이되도록 각 값을 조절하여 적용시킬 수 있다.

 

 

4. Transparency 

 각 모델을 투명하도록 할 수 있다.

 

5.Reflection

 

 

이와 같이 반사되는 물체를 표현해야 하는 경우도 있다.

 

 

6. Refraction

 

이는 굴절을 표현한다. 위 구에서 물체들이 약간 휘어진 것처럼 보인다. 이처럼 굴절을 표현하기도 한다.

 

이는 three.js에서 예제 중에 environment 환경을 굴절시키는 예제를 찾아보자.

 

 

7. Shadow casting

 

그림자에 대한 표현이다.

 

 

Transparency, Reflection, Refraction, Shadow casting을 합쳐 Ray Tracing이라고 한다.

 

 

마지막으로 Global Illumination이 있다.

 

이는 전체 광원이 전방향으로 퍼저나 갈 때 만난 물체의 색이 있을 것이다. 

 

각 물체가 색을 가지고 있다는 것은 해당 색은 반사하고 나머지 색은 흡수한다는 이야기다.

그러면 해당 물체는 각 반사되는 색의 광원의 역할을 한다는 것입니다.

 

그리고 해당 물체는 광원 간의 거리에 따라 가까우면 많은 세기를 멀면 작은 빛 세기를 발광합니다. 

 

만약 물체가 많다면 이러한 계산을 엄청 많이 계산을 할 것입니다. 

 

그래서 global Illumination은 Real Time Rendering은 거의 불가능하고 만약 한다면 1시간에서 2시간 정도의 렌더링을 합니다.

 

 

 

Light Source Model에서 surface Light 모델에 대해 알아봅니다.

 

면 광원을 쓰는 이유는 그림자는 부드럽게 만들고 그림자의 테두리를 부드럽게 만들기 위함입니다.

 

하지만 이렇게 그림자의 테두리를 부드럽게 만드는 작업은 상당히 많은 계산양을 필요로 합니다.

 

그래서 three.js에서는 이를 지원하지 않습니다.

 

three.js에서 `Light` 클래스는 모든 라이트 타입의 기본 클래스입니다. 다양한 라이트 타입을 만들기 위해 이 클래스를 상속하거나, 이 클래스로부터 직접 인스턴스를 만들 수 있습니다.

`Light` 클래스의 파생 클래스로는 아래와 같은 것들이 있습니다.

1. `AmbientLight`: 주변광을 나타내는 라이트입니다. 모든 방향에서 일정한 세기의 빛을 발산합니다. 장면 전체에 균일한 밝기를 제공하는 데 사용됩니다.


2. `PointLight`: 한 점에서 모든 방향으로 빛을 발산하는 라이트입니다. 조명의 위치와 세기를 조절하여 조명의 위치에 따라 씬의 물체를 강조할 수 있습니다.


3. `DirectionalLight`: 무한히 먼 거리에서 모든 방향으로 일정한 세기의 빛을 발산하는 라이트입니다. 태양 등과 같은 방향성이 있는 빛을 표현할 때 사용됩니다.


4. `SpotLight`: 특정 위치에서 일정한 방향으로 빛을 발산하는 라이트입니다. 조명의 위치와 방향, 스포트라이트의 범위와 세기를 조절하여 특정 물체를 강조할 수 있습니다.


5. `HemisphereLight`: 상하 반구에서 각각 다른 색상의 빛을 발산하는 라이트입니다. 하늘과 지표면을 표현할 때 사용됩니다.

각 라이트 타입은 조명의 색상, 위치, 방향, 세기 등의 속성을 설정할 수 있습니다. 또한, 그림자를 사용하려면 `LightShadow` 클래스를 사용해야 합니다. `LightShadow`는 각 라이트 타입마다 그림자를 생성하기 위한 구체적인 구현을 제공합니다.

LightShadow는 기본 클래스로 파생 클래스는 3개 입니다. 

 

스포트라잍, 점, 직선에 대한 그림자만 지원하는 것을 알 수 있습니다.

 

추가적으로 광원 중에 RectAreaLight라고 있는데, 이는 아까 말했던 것처럼 면 광원인데, 여기서 발생하는 그림자를 계산하는 것을 three.js에서 지원하지 않아 파생클래스가 없습니다. 

 

const createLight = () => {
    const light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(0, 6, 6);
    scene.add(light);

    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);

    const pointLight = new THREE.PointLight(0xffffff, 1, 100);
    pointLight.position.set(0, 5, 10);
    scene.add(pointLight);
  }

 

 

여기서 재밌는 시도를 할 수 있습니다. 물체가 색이 있다는 것은 나머지 색은 흡수하고 보이는 색을 반사한다는 것을 의미합니다. 

 

만약 빛의 색에서 반사하는 빛의 색을 전달해주지 않으면 어떻게 될까요?

  const light = new THREE.DirectionalLight(0xffff00, 1);
    light.position.set(0, 6, 6);
    scene.add(light);

    const ambientLight = new THREE.AmbientLight(0xffff00, 0.5);
    scene.add(ambientLight);

 

파란색의 구가 검정색으로 변한 것을 알 수 있습니다. 

 

이 효과를 동적으로 사용해도 재밌는 효과를 줄 수 있을 것 같습니다.

 

 

 

반응형

'FrontEnd > THREE.js' 카테고리의 다른 글

Antialiasing  (0) 2023.05.06
Texture  (0) 2023.05.06
flat, smooth shading  (1) 2023.05.06
Three.js 라이브러리를 확장한 객체지향 구조  (0) 2023.04.26
물리공간 구축  (0) 2023.04.24

댓글