모델 생성
_setupModel() {
const groundGeometry = new THREE.PlaneGeometry(10, 10);
const groundMaterial = new THREE.MeshStandardMaterial({
color: "#2c3e5a",
roughness: 0.5,
metalness: 0.5,
side: THREE.DoubleSide,
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = THREE.Math.degToRad(-90);
this._scene.add(ground);
const bigSphereGeometry = new THREE.SphereGeometry(1.5, 64, 64, 0, Math.PI);
const bigSphereMaterial = new THREE.MeshStandardMaterial({
color: "#fff",
roughness: 0.1,
metalness: 0.2,
});
const bigSphere = new THREE.Mesh(bigSphereGeometry, bigSphereMaterial);
bigSphere.rotation.x = THREE.Math.degToRad(-90);
this._scene.add(bigSphere);
const torusGeometry = new THREE.TorusGeometry(0.4, 0.1, 32, 32);
const torusMaterial = new THREE.MeshStandardMaterial({
color: "#9b59b6",
roughness: 0.5,
metalness: 0.9,
});
for (let i = 0; i < 8; i++) {
const torusPivot = new THREE.Object3D();
const torus = new THREE.Mesh(torusGeometry, torusMaterial);
torusPivot.rotation.y = THREE.Math.degToRad(45 * i);
torus.position.set(3, 0.5, 0);
torusPivot.add(torus);
this._scene.add(torusPivot);
}
const smallSphereGeometry = new THREE.SphereGeometry(0.3, 32, 32);
const smallSphereMaterial = new THREE.MeshStandardMaterial({
color: "#e74c3c",
roughness: 0.2,
metalness: 0.5,
});
const smallSpherePivot = new THREE.Object3D();
const smallSphere = new THREE.Mesh(
smallSphereGeometry,
smallSphereMaterial
);
smallSpherePivot.add(smallSphere);
smallSpherePivot.name = "smallSpherePivot"; // 이름을 부여해주면 scene 객체를 통해 언제든 조회할 수 있다.
smallSphere.position.set(3, 0.5, 0);
this._scene.add(smallSpherePivot);
}
단순히 Scene에 존재하는 모든 물체에 대해 단일 색상 광원으로 랜더링되도록 한다.
대부분 밝기 값을 밝기 값을 매우 약하게 지정해서 장면에 추가하여, 광원의 영향을 받지 못하는 물체도 살짝 보여지도록 하는데 사용된다.
new THREE.AmbientLight(0xffffff, 0.2);
주변광인 것은 AmbientLight와 동일하지만 위, 아래 광원의 색상을 다르게 설정할 수 있다.
const light = new THREE.HemisphereLight("#b0d8f5", "#bb7a1c", 1);
빛과 물체간의 거리에 상관없이 동일한 빛의 효과를 준다.
_setupLight(){
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 5, 0); // 빛의 위치
light.target.position.set(0, 0, 0); // 타겟의 위치
this._scene.add(light.target);
// 광원을 시각화해주는 헬퍼 객체
const helper = new THREE.DirectionalLightHelper(light);
this._scene.add(helper);
this._lightHelper = helper;
this._scene.add(light);
this._light = light;
}
update(time) {
time *= 0.001;
const smallSpherePivot = this._scene.getObjectByName("smallSpherePivot");
if (smallSpherePivot) {
smallSpherePivot.rotation.y = THREE.Math.degToRad(time * 50);
// 업데이트 시 광원이 타겟을 바라보도록 설정
if (this._light.target) {
const smallSphere = smallSpherePivot.children[0];
smallSphere.getWorldPosition(this._light.target.position);
//smallSphere의 좌표계의 위치를 구해서 광원의 타겟 위치에 지정한다
if (this._lightHelper) this._lightHelper.update();
}
}
}
distance: 이 속성값으로 지정된 거리까지만 광원의 영향을 받도록 함. default: 0 (무한한 거리)
_setupLight() {
const light = new THREE.PointLight(0xffffff, 2);
light.position.set(0, 5, 0);
light.distance = 0;
const helper = new THREE.PointLightHelper(light);
this._scene.add(helper);
this._scene.add(light);
this._light = light;
}
update(time) {
time *= 0.001;
const smallSpherePivot = this._scene.getObjectByName("smallSpherePivot");
if (smallSpherePivot) {
smallSpherePivot.rotation.y = THREE.Math.degToRad(time * 50);
if (this._light) {
const smallSphere = smallSpherePivot.children[0];
smallSphere.getWorldPosition(this._light.position); //smallSphere의 좌표계의 위치를 구해서 광원의 타겟 위치에 지정한다
if (this._lightHelper) this._lightHelper.update();
}
}
}
빛이 광원의 위치에서 깔대기 모양으로 퍼져나감
_setupLight() {
const light = new THREE.SpotLight(0xffffff, 1);
light.position.set(0, 5, 0); // 광원의 위치
light.target.position.set(0, 0, 0); // 광원의 타겟 위치
light.angle = THREE.Math.degToRad(45); // 광원이 만드는 깔대기의 각도
light.penumbra = 0; // 빛의 감쇄율. default: 0 (빛의 감쇄가 없음)
this._scene.add(light.target);
const helper = new THREE.SpotLightHelper(light);
this._scene.add(helper);
this._lightHelper = helper;
this._scene.add(light);
this._light = light;
}
update(time) {
time *= 0.001;
const smallSpherePivot = this._scene.getObjectByName("smallSpherePivot");
if (smallSpherePivot) {
smallSpherePivot.rotation.y = THREE.Math.degToRad(time * 50);
if (this._light.target) {
const smallSphere = smallSpherePivot.children[0];
smallSphere.getWorldPosition(this._light.target.position);
if (this._lightHelper) this._lightHelper.update();
}
}
}
target의 위치를 지정하는게 아니라 각도로 방향을 정해 빛을 비춘다.
import {RectAreaLightUniformsLib} from "three/examples/jsm/lights/RectAreaLightUniformsLib";
import {RectAreaLightHelper} from "three/examples/jsm/helpers/RectAreaLightHelper";
_setupLight() {
RectAreaLightUniformsLib.init(); // 광원을 사용하기 위해 초기화 코드 선행
const light = new THREE.RectAreaLight(0xffffff, 10, 6, 1);
// 색상, 세기, 광원의 가로길이, 광원의 세로길이
light.position.set(0, 5, 0);
light.rotation.x = THREE.Math.degToRad(-90); // -90도 방향으로 빛을 비춤
const helper = new RectAreaLightHelper(light);
light.add(helper);
this._scene.add(light);
this._light = light;
}