본문 바로가기

3D Project/3D 인터랙티브 웹

[3D 인터랙티브 웹] Three.js 기초 - 실시간 조명 세팅하기, 3D Scene에 이미지 적용하기

[ Three.js에서 만들 수 있는 조명의 종류 4가지 ]

  • Directional Light - 한쪽 방향으로만 쏟아지는 조명
  • Point Light - 한 점에서 방사형으로 뿜어져 나오는 조명
  • Ambient Light - 화면 전체적으로 빛을 조여주는 조명
  • Hemisphere Light - 그라데이션으로 조명을 주는 방법

 

- Three.js 기본세팅

import * as THREE from "three";

let renderer, scene, camera;

//canvas setting
const canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);

function init() {
    renderer = new THREE.WebGLRenderer({canvas:canvas}); //canvas와 renderer 연결
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera();
    camera.fov = 32;
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();
 
    camera.position.set(0,0,10);

    const geometry = new THREE.SphereGeometry();
    const material = new THREE.MeshStandardMaterial();
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh)

    //조명을 넣어야 3D 물체가 보임 + 카메라 위치 선정
    const directionalLight = new THREE.DirectionalLight();
    directionalLight.position.set(1,1,1);
    scene.add(directionalLight);

    render();
}

function render() {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
}

init();

 

4가지 조명 적용하기

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"

let renderer, scene, camera, controls;

//canvas setting
const canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);

function init() {
    renderer = new THREE.WebGLRenderer({canvas:canvas, antialias:true}); //canvas와 renderer 연결
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera();
    camera.fov = 45;
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();

    camera.position.set(0,0,10);

    controls = new OrbitControls(camera, canvas);

    const geometry = new THREE.SphereGeometry();
    const material = new THREE.MeshStandardMaterial();
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh)

    //조명을 넣어야 3D 물체가 보임 + 카메라 위치 선정
    //Directional Light
    const directionalLight = new THREE.DirectionalLight(
        new THREE.Color("white"),
        0.85
    );
    directionalLight.position.set(1,1,1);
    scene.add(directionalLight);
    const dirHelper = new THREE.DirectionalLightHelper(directionalLight);
    scene.add(dirHelper)

    //PointLight - 도형에 어떤 효과를 주거나 강조할 때 사용
    const pointLight = new THREE.PointLight(
        0xffffff,
        0.1
    ); //원점에 PointLight 생성
    pointLight.position.set(2,0,2)
    scene.add(pointLight);
    const pointHelper = new THREE.PointLightHelper(pointLight);
    scene.add(pointHelper)


    //Ambient Light - 전역에서 빛을 쏘기 때문에 Helper는 존재하지 않음
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.2)
    // scene.add(ambientLight);

    //Hemisphere Light - 그라데이션으로 빛을 쏨
    const hemisphereLight = new THREE.HemisphereLight(
       new THREE.Color("yellow"),
       new THREE.Color("blue"),
       0.25
    );
    scene.add(hemisphereLight);
    const hemisHelper = new THREE.HemisphereLightHelper(hemisphereLight)
    scene.add(hemisHelper)
   

    render();
}

function render() {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
    controls.update();
}

init();

 

조명 적용한 3D 구 렌더링 결과

 

그림자 생성하기

1. 선명한 그림자를 먼저 만든 다음 부드러운 그림자로 변환하는 방법

 -> Shadow Map 방식 - 그림자 넣기, 그림자를 먼저 이미지로 만든 다음에 3D Scene에 입히는 과정

  • plane geometry(그림자가 생길 바닥) 생성하기
  • renderer, light, mesh에 대해서 shadow 설정켜기
 renderer = new THREE.WebGLRenderer({canvas:canvas, antialias:true}); //canvas와 renderer 연결
 renderer.shadowMap.enabled = true;
 directionalLight.castShadow = true;
 
const planeGeo = new THREE.PlaneGeometry(10,10);
    const plane = new THREE.Mesh(planeGeo, material);
    plane.position.set(0, -1, 0)
    plane.rotation.set(Math.PI* -0.5, 0, 0)
    scene.add(plane);
 
 mesh.castShadow = true;
    mesh.receiveShadow = true;

    plane.castShadow = true;
    plane.receiveShadow = true;

Three.js Scene에서 배경화면 + 환경조명 설정하기

import {RGBELoader} from "three/examples/jsm/loaders/RGBELoader" //HDR 같은 이미지 포맷을 사용하기 위해서 꼭 필요한 모듈
 
 //RGBELoader 적용
 const loader = new RGBELoader();
    //3D Scnen에 적용할 이미지 가져오기
    loader.load("/sky.hdr", (texture) => {
        texture.mapping = THREE.EquirectangularReflectionMapping;
        scene.background = texture;
        scene.environment = texture;
    });
 
//material 적
 const material = new THREE.MeshStandardMaterial({
        color: new THREE.Color("#ffffff"),
        roughness: 0, //난반사가 되는 정도, 0이면 거울에 비친거처럼 주변 환경을 반사함
        metalness: 1, //주변 환경의 색을 따와서 금속 표면과 같이 작용
        // emissive: 0xffffff
    });

 

결과