Light
Texture 가 물체의 표면에 그림을 입히는 것이라면, Light 는 그 물체에 입체감과 깊이를 부여하는 '생명력'입니다. RedGPU의 모든 조명은 LightManager 를 통해 통합 관리되며, 다양한 광원을 조합하여 극적인 연출을 할 수 있습니다.
1. 빛의 물리적 단위 (Light Units)
RedGPU는 물리 기반 렌더링 (PBR)을 지원하므로, 현실 세계의 물리적 빛 단위로 광원의 세기를 제어합니다.
| 단위 | 속성 | 적용 광원 | 설명 |
|---|---|---|---|
| Lux (룩스, lx) | lux | DirectionalLight, AmbientLight | 특정 면적에 도달하는 빛의 밝기(조도)입니다. 맑은 날 한낮의 태양광은 약 100,000 Lux 수준입니다. |
| Lumen (루멘, lm) | lumen | PointLight, SpotLight | 광원에서 사방으로 방출되는 빛의 총량(광속)입니다. 전구나 조명의 밝기를 나타낼 때 사용합니다. |
2. LightManager
조명은 생성하는 것만으로는 화면에 영향을 주지 않습니다. 반드시 Scene 의 lightManager 에 등록해야 엔진이 이를 계산에 포함합니다.
[기본 조명 상태]
광원을 사용해야 하는 재질 (PhongMaterial, PBRMaterial 등)의 경우, 조명을 설정하지 않으면 화면에 아무것도 보이지 않습니다.
[광원 등록 한계치]
RedGPU 셰이더 및 버퍼 연산 최적화를 위해 각 광원 종류별로 등록할 수 있는 최대 개수가 제한되어 있습니다. 한계치를 초과하여 등록하려고 시도하면 에러가 발생합니다.
- DirectionalLight (방향광): 최대 3개
- PointLight + SpotLight (클러스터 조명): 합산 최대 1,024개
- AmbientLight (환경광): 씬 (Scene)당 최대 1개 (속성으로 직접 할당)
// 방향광 추가 (여러 개 가능)
scene.lightManager.addDirectionalLight(directionalLight);
// 점광원 추가 (여러 개 가능)
scene.lightManager.addPointLight(pointLight);3. 주요 조명의 종류
RedGPU는 물리적 특성이 다른 네 가지 광원을 제공합니다. 각 조명의 특성을 이해하고 상황에 맞게 조합하는 것이 중요합니다.
3.1 DirectionalLight (방향광)
태양처럼 무한히 먼 곳에서 특정 방향으로 평행하게 쏘는 빛입니다.
- 특징 및 용도: 위치에 상관없이 방향 (
direction)이 일정하며, 전역 조명과 그림자 생성에 주로 사용합니다. - 사용 단위: Lux (
lux, 기본값100,000)
3.2 PointLight (점광원)
전구처럼 공간의 한 지점에서 모든 방향으로 퍼져나가는 빛입니다.
- 특징 및 용도: 거리에 따라 밝기가 줄어드는 감쇠(Attenuation)가 발생하며,
radius속성으로 빛이 도달하는 반경을 제어해 특정 영역을 강조할 때 사용합니다. - 사용 단위: Lumen (
lumen, 기본값1,000)
3.3 SpotLight (스포트라이트)
손전등이나 무대 조명처럼 특정 지점에서 한 방향으로 원뿔 모양의 빛을 쏘는 광원입니다.
- 특징 및 용도: 내각 (
innerCutoff)과 외각 (outerCutoff), 도달 반경 (radius)을 조절하여 집중된 조명 효과를 연출합니다. - 사용 단위: Lumen (
lumen, 기본값1,000)
3.4 AmbientLight (환경광)
모든 방향에서 물체를 균일하게 비추는 채움 빛 (Fill Light)입니다.
- 특징 및 용도: 위치나 방향이 없으며 그림자가 생성되지 않습니다. 조명이 닿지 않는 어두운 부분을 완화하고 전체적인 기본 밝기를 보정할 때 사용합니다.
- 사용 단위: Lux (
lux, 기본값50)
[재질 주의]
ColorMaterial 은 조명의 영향을 받지 않고 단색으로만 출력됩니다. 조명 효과를 확인하려면 반드시 PhongMaterial 이나 PBRMaterial 과 같은 광택/질감이 있는 재질을 사용해야 합니다.
4. 실습: 다채로운 조명 구성
바닥과 여러 개의 구체를 배치하고, 서로 다른 색상의 PointLight 두 개를 움직여 빛이 공간에 퍼지는 효과를 구현해 봅니다.
import * as RedGPU from "https://redcamel.github.io/RedGPU/dist/index.js";
const canvas = document.getElementById('redgpu-canvas');
RedGPU.init(canvas, (redGPUContext) => {
const scene = new RedGPU.Display.Scene();
// 1. 파란색 점광원
const blueLight = new RedGPU.Light.PointLight('#0000ff');
blueLight.radius = 15;
scene.lightManager.addPointLight(blueLight);
// 2. 빨간색 점광원
const redLight = new RedGPU.Light.PointLight('#ff0000');
redLight.radius = 15;
scene.lightManager.addPointLight(redLight);
// 3. 바닥 및 물체 생성 (PhongMaterial 사용)
const material = new RedGPU.Material.PhongMaterial(redGPUContext);
// 바닥
const floor = new RedGPU.Display.Mesh(
redGPUContext,
new RedGPU.Primitive.Ground(redGPUContext, 30, 30),
material
);
scene.addChild(floor);
// 구체 25개 배치
const sphereGeometry = new RedGPU.Primitive.Sphere(redGPUContext, 1, 32, 32);
for (let i = 0; i < 25; i++) {
const mesh = new RedGPU.Display.Mesh(redGPUContext, sphereGeometry, material);
mesh.x = (i % 5 - 2) * 4;
mesh.z = (Math.floor(i / 5) - 2) * 4;
scene.addChild(mesh);
}
const controller = new RedGPU.Camera.OrbitController(redGPUContext);
controller.distance = 25;
const view = new RedGPU.Display.View3D(redGPUContext, scene, controller);
redGPUContext.addView(view);
const renderer = new RedGPU.Renderer();
// 4. 조명 애니메이션
renderer.start(redGPUContext, (time) => {
const t = time / 1000;
blueLight.x = Math.sin(t) * 10;
blueLight.z = Math.cos(t) * 10;
blueLight.y = Math.sin(t * 0.5) * 5 + 5;
redLight.x = Math.sin(t + 3.14) * 10;
redLight.z = Math.cos(t + 3.14) * 10;
redLight.y = Math.cos(t * 0.5) * 5 + 5;
});
});라이브 데모
광원의 위치가 이동함에 따라 물체의 표면에 맺히는 빛의 변화를 확인해 보세요.
관련 예제
다음 학습 추천
조명의 빛을 받아 정교한 표면 질감과 입체감을 표현하는 Phong Material에 대해 알아봅니다.