Three.js Chapter 3 section 24 Environment map

황상진·2024년 4월 19일
0

Three.js

목록 보기
12/15
post-thumbnail

Environment map

background, reflection, lighting을 설정할 때 사용된다.

Cube Texture Environment map

Environment map Setup

/**
 * Loaders
 */
// ...
const cubeTextureLoader = new THREE.CubeTextureLoader()

const environmentMap = cubeTextureLoader.load([
    '/environmentMaps/0/px.png',
    '/environmentMaps/0/nx.png',
    '/environmentMaps/0/py.png',
    '/environmentMaps/0/ny.png',
    '/environmentMaps/0/pz.png',
    '/environmentMaps/0/nz.png'
])

scene.background = environmentMap

  • light를 설정하려면 scene의 environment를 위의 environmentMap을 적용한다.

scene.environment = environmentMap
scene.background = environmentMap

Environment map Intensity

  • 모든 material에 적용되어야한다.
  • traverse를 활용해서 모든 child를 순회할 것이다.
  • model이 update될 때 이 함수를 활용한다.
  • isMesh와 isMeshStandardMaterial을 활용해서 Mesh에만 적용되도록 한다.
// Global intensity
const global = {}
global.envMapIntensity = 1

const updateAllMaterials = () =>
    {
        scene.traverse((child) =>
        {
            if(child.isMesh && child.material.isMeshStandardMaterial)
            {
                child.material.envMapIntensity = global.envMapIntensity
            }
        })
    }
gui
    .add(global, 'envMapIntensity')
    .min(0)
    .max(10)
    .step(0.001)
    .onChange(updateAllMaterials)

/**
 * Models
 */
gltfLoader.load(
    '/models/FlightHelmet/glTF/FlightHelmet.gltf',
    (gltf) =>
    {
        gltf.scene.scale.set(10, 10, 10)
        scene.add(gltf.scene)

        updateAllMaterials()
    }
)

Background Blurriness & Intensity

  • scene.backgroundBlurriness 속성을 변경하면 blurr값이 변경된다.
  • environment map 해상도가 낮거나 object에만 집중하게 하고 싶을 때 사용
scene.backgroundBlurriness = 0.2

HDRI Equirectangular Environment Map

  • 이번에는 HDRI 파일을 활용해서 Environment Map setup 해보자
  • High Dynamic Range Image의 약자
  • RGBELoader를 활용해서 HDRI를 load한다.
  • scene에 적용하기 전에 load된 것이 equirectangular map인것을 설정하고 scene에 적용한다.
  • hdri는 너무 무겁기 때문에 lighting을 사용하는 것을 제외하면 비추한다.
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'

/**
 * Loaders
 */
// ...
const rgbeLoader = new RGBELoader()

// HDR (RGBE) equirectangular
rgbeLoader.load('/environmentMaps/0/2k.hdr', (environmentMap) =>
{
    environmentMap.mapping = THREE.EquirectangularReflectionMapping

    scene.background = environmentMap
    scene.environment = environmentMap
})

Blender를 활용한 Environment Map

  • Blender modeling
  • Camera Setting
    - Location, Rotation 설정
    • Object Data Properties에서 Lens - Type을 Panoramic으로 설정 - Equirectangular로 설정
  • 해당 카메라 설정 후 ctrl + 0 , ctrl + f12
  • alt + s로 저장
  • file format을 Radiance HDR로 설정

NVidia Canvas

  • AI로 HDRI를 만들 수 있는 서비스
  • 만들고 exr로 저장
  • EXRLoader를 활용해서 load한다.
import { EXRLoader } from 'three/addons/loaders/EXRLoader.js'

/**
 * Loaders
 */
// ...
const exrLoader = new EXRLoader()
// HDR (EXR) equirectangular
exrLoader.load('/environmentMaps/nvidiaCanvas-4k.exr', (environmentMap) =>
{
    environmentMap.mapping = THREE.EquirectangularReflectionMapping

    scene.background = environmentMap
    scene.environment = environmentMap
})

https://www.nvidia.com/en-us/studio/canvas/

Skybox Lab

  • AI로 HDRI 만드는 서비스
  • 돈 내야함

Ground projected environment map

  • HDRI의 특징 중에 땅에서 떠있기 때문에 부자연스러운 특징이 있다.

  • 이를 해결하기 위해서 Ground projected environment map를 사용한다.

  • HDR environment maps에서 environment만 설정하고 사용한다.

  • GroundProjectedSkybox를 import 한다.

  • GroundProjectedSkybox(environmentMap)한 skybox를 생성한다.

  • skybox의 크기를 키운다.

  • scene에 추가한다.

skybox의 projection radius, height를 변경할 수 있다.

import { GroundProjectedSkybox } from 'three/addons/objects/GroundProjectedSkybox.js'

global.envMapIntensity = 1
// Ground projected skybox
rgbeLoader.load('/environmentMaps/2/2k.hdr', (environmentMap) =>
{
    environmentMap.mapping = THREE.EquirectangularReflectionMapping
    scene.environment = environmentMap
  
  	const skybox = new GroundProjectedSkybox(environmentMap)
    skybox.scale.setScalar(50)
  	gui.add(skybox, 'radius', 1, 200, 0.1).name('skyboxRadius')
    gui.add(skybox, 'height', 1, 100, 0.1).name('skyboxHeight')
    scene.add(skybox)
})

Dynamic Environment map

  • 실시간으로 scene 안에 있는 환경을 environment map으로 사용할 거다.
  • cubeTexture를 사용해야한다.
  • WebGLCubeRenderTarget은 scene의 render를 저장하는 역할을 한다.
  • 매 tick마다 rendertarget을 저장해야하므로, CubeCamera를 활용해서 저장하고 update한다.
  • cuberendertarget에 영향 받아야하는 object들은 있으면 부자연스러우므로 layer를 생성해서 관리한다.
// Cube render target
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(
    256,
    {
        type: THREE.FloatType
    }
)

scene.environment = cubeRenderTarget.texture

// Cube camera
const cubeCamera = new THREE.CubeCamera(0.1, 100, cubeRenderTarget)
cubeCamera.layers.set(1)

const holyDonut = new THREE.Mesh(
    new THREE.TorusGeometry(8, 0.5),
    new THREE.MeshBasicMaterial({ color: new THREE.Color(10, 4, 2) })
)
holyDonut.layers.enable(1)

const tick = () =>
{
    // ...
        
    // Real time environment map
    if(holyDonut)
    {
        holyDonut.rotation.x = Math.sin(elapsedTime) * 2


        cubeCamera.update(renderer, scene)
    }

    // ...
}

https://24-environment-493xqd11t-hwangsangjins-projects.vercel.app/

profile
Web FrontEnd Developer

0개의 댓글

관련 채용 정보