1 环境贴图

环境贴图(Environment Map)看起来像是从场景中对象的角度拍摄的环境全景照片,水平方向覆盖360度,垂直方向覆盖180度或360度。环境贴图的作用类似于对象周围一般照明环境的描述,通常用于以低成本渲染反射或者处理间接光照

2 HDR

HDR(High Dynamic Range Imaging),又称高动态范围成像,是用来实现比普通数位图像技术更大曝光动态范围的一组技术。HDR的目的是正确地表示真实世界中从太阳光直射到最暗的阴影的范围亮度,其可以提供更多的动态范围和图像细节。

在计算机图形学与电影摄影术中,HDR是用来实现比普通数位图像技术更大曝光动态范围(即更大的明暗差别)的一组技术。高动态范围成像的目的就是要正确地表示真实世界中从太阳光直射到最暗的阴影这样大的范围亮度。

3 基于three.js,将Hdr作为环境贴图实现对3D模型加载与渲染

3.1 three.js版本,3D模型与HDR下载地址

three.js版本

本次实验使用three.js r144版本,是写本文时目前最新的three.js版本

ThreeJS – 使用Hdr环境贴图作为间接光照对模型进行渲染-StubbornHuang Blog

3D模型

模型地址:https://sketchfab.com/3d-models/model-47a-loggerhead-sea-turtle-c438e81e796d41d9a6ae4cc147ef8d4f

ThreeJS – 使用Hdr环境贴图作为间接光照对模型进行渲染-StubbornHuang Blog

hdr

hdr地址:https://polyhaven.com/a/rainforest_trail

Tone mapping

本次实验使用的Tone mapping算法为Academy Color Encoding System(ACES),具体的Tone Mapping算法的介绍可参考:Tone mapping进化论

3.2 代码

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>three.js hdr envmap test</title>
    <style type="text/css">
        html,body {
            margin: 0;
            height: 100%;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <script src="js/three.js-r144/build/three.js"></script>
    <script src="js/three.js-r144/examples/js/loaders/GLTFLoader.js"></script>
    <script src="js/three.js-r144/examples/js/loaders/RGBELoader.js"></script>
    <script src="js/three.js-r144/examples/js/controls/OrbitControls.js"></script>
    <script>
        let scene,camera,renderer,controls

        function init() {
            // 创建绘制上下文
            renderer = new THREE.WebGLRenderer({
                antialias:true,
                //alpha:true
            });
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize(window.innerWidth,window.innerHeight);
            renderer.gammaOutput = true;
            renderer.shadowMap.enabled = true;
            renderer.toneMapping = THREE.ACESFilmicToneMapping;
            renderer.outputEncoding = THREE.sRGBEncoding
            renderer.toneMappingExposure = 2.2;
            document.body.appendChild(renderer.domElement)

            // 创建场景
            scene = new THREE.Scene();
            //scene.background = new THREE.Color(0xFFdddd);

            // 加载hdr
            const hdrUrl = './res/hdr/rainforest_trail_4k.hdr'
            new THREE.RGBELoader().load(hdrUrl, texture => {
                 const gen = new THREE.PMREMGenerator(renderer)
                 const envMap = gen.fromEquirectangular(texture).texture
                 scene.environment = envMap
                 scene.background = envMap

                 texture.dispose()
                 gen.dispose()
            })


            // 创建摄像头
            camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.1,5000);
            camera.position.set(0,30,30);
            controls = new THREE.OrbitControls(camera,renderer.domElement);


            // 加载3D模型
            new THREE.GLTFLoader().load('./res/3dmodel/scene.gltf', result => {
                model = result.scene.children[0];
                model.position.set(0,-5,-5);
                model.traverse(n => {
                    if ( n.isMesh ) {
                        n.castShadow = true;
                        n.receiveShadow = true;
                        if(n.material.map)
                            n.material.map.anisotropy = 1;
                    }
                });
                scene.add(model);
            });

            window.addEventListener( 'resize', onWindowResize, false );
        }

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

        }

        init();
        animate()


        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize( window.innerWidth, window.innerHeight );

        }

    </script>
</body>
</html>

3.3 效果

ThreeJS – 使用Hdr环境贴图作为间接光照对模型进行渲染-StubbornHuang Blog
ThreeJS – 使用Hdr环境贴图作为间接光照对模型进行渲染-StubbornHuang Blog