Three.js添加HDRI背景
最令人兴奋的项目之一是在 Three js 中添加HDRI背景。 HDRI图像是从房间内部或花园、丛林或山脉等开放环境等场景中以 360 度捕获的。 你可以自己创建任何这些图像,但这不是本教程的主题。 相反,我们将从网站获取这些图像之一,并使用轨道控件,让用户能够转动物体并以 360 度查看所有内容。 我们还可以将物体添加到场景中并赋予它们颜色或增加它们的金属度并降低它们的粗糙度以成为球形镜子。
1、在Three.js中添加背景
可能性是无限的,你可以做很多事情。 例如,可以通过添加不同家具、地毯、垫子等的 3D 模型来创建空房间的室内设计。 本教程是创建虚拟世界的开始,你可以虚拟地建造自己的梦想之家,并从各个不同的方面观看它。 正如我们在其他 Three js 教程中所说,一旦开始使用 Three js,天空才是极限。
我们将从three.js 场景的简单元素开始,包括相机、渲染器、场景、对象和光源(如果需要)。 在此之前,我们使用 Vite 插件来轻松创建运行 Three.js 代码所需的所有文件夹和文件。 首先,使用以下命令在项目目录中创建一个文件夹:
mkdir BackgroundScene
cd BackgroundScene
然后,在文件夹中,运行 Vite 插件命令即可创建必要的文件和文件夹:
npm create vite@latest
然后,输入项目名称。 可以用glowingSphere作为名字。 但是,该名称是任意的,你可以选择任何想要的名称。 然后,选择 vanilla 作为框架和变体。 之后,在终端中输入以下命令:
cd BackgroundScene
npm install
接下来,你可以在 main.js 文件中输入要编写的 JavaScript 代码。 因此,我们将输入基本或模板代码,用于运行带有动画对象(例如球体)的每个项目。 另外,每次创建项目时不要忘记安装three.js包:
npm install three
在 main.js 文件中输入以下代码:
import * as THREE from 'three';
import { Mesh } from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight , 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
antialias : true
})
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
//creating a sphere
const geometry = new THREE.SphereGeometry(5, 50, 50);
const material = new THREE.MeshBasicMaterial({
color:0x3268F8
})
const sphere = new THREE.Mesh(geometry,material);
scene.add(sphere);
camera.position.z = 15;
function animate(){
requestAnimationFrame(animate);
renderer.render(scene,camera);
sphere.rotation.y += 0.003;
}
animate();
上面的代码可以作为后续项目的样板。 此代码的输出将是蓝色球体,如下图所示。 但是,为了能够显示这一点,你应该在终端中编写以下命令:
pm run dev
2、在Three.js 中使用轨道控件设置背景
现在,我们想要创建一个要添加的背景场景,但在此之前,我们需要将渲染从动画更改为轨道控件,这样我们就可以控制从动画更改场景,而不是旋转对象。 相机视角。 这样做使我们能够从各个角度查看 HDRI 图像。 首先,我们需要导入以下 2 个库:
import {OrbitControls} from "/node_modules/three/examples/jsm/controls/OrbitControls.js";
import Stats from "/node_modules/three/examples/jsm/libs/stats.module.js";
然后,我们要做的就是修改下面的渲染代码:
function animate(){
requestAnimationFrame(animate);
renderer.render(scene,camera);
sphere.rotation.y += 0.003;
}
Animate();
修改后的代码如下所示:
const controls = new OrbitControls(camera, renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}
const stats = Stats();
document.body.appendChild(stats.dom);
function animate() {
requestAnimationFrame(animate);
render();
stats.update();
}
function render() {
renderer.render(scene, camera);
}
animate();
现在我们应该能够围绕该物体运行。 接下来我们应该做的是将基础材质更改为标准材质并创建镜面效果:
const geometry = new THREE.SphereGeometry();
const material = new THREE.MeshStandardMaterial({
color: 0xffffff,
})
material.roughness = 0;
material.metalness = 1;
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
3、添加HDRI环境贴图
最后,我们到达最令人兴奋的部分,即将 HDRI 图像添加到背景中。
为此,我们需要首先从BimAnt HDRI等网站找到这些图像,BimAnt HDRI提供超过600张HDRI环境贴图,优点是无需登录即可直接预览和下载:
之后,我们应该创建一个名为 images 的文件夹并将 HDRI 图像粘贴到其中。 最后,添加以下代码以便能够渲染场景中的背景:
import {RGBELoader} from "/node_modules/three/examples/jsm/loaders/RGBELoader.js";
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 0.6;
renderer.outputEncoding = THREE.sRGBEncoding;
new RGBELoader().load("/images/solitude_4k.hdr", function(texture){
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = texture;
scene.environment = texture;
})
现在,如果我们保存代码,结果将如下所示:
用鼠标左键单击页面并将其向左、向右、向上或向下移动时,你会发现可以从所有不同的角度看到场景。 另外,由于我们将球体材质的金属度定义为 1,粗糙度定义为 0,我们可以看到球体上的镜面效果,以真实的方式反映背景场景。
可以说我们不需要任何光源,但请注意,如果物体靠近地面或在任何其他需要看到球的阴影的情况下,那么必须向场景添加光源并将其放置在光源光线与太阳光线方向相同的位置。
4、结束语
在本教程中,我们已成功将HDRI环境贴图添加到场景中。
我们首先使用 Vite 插件和我们在大多数 Three js 项目中使用的样板代码。 然后,我们删除旋转动画,取而代之的是轨道控件,以便用户能够使用鼠标查看他们想要的场景的任何角度。
接下来我们要做的是将物体的材质从基本材质更改为标准材质,以便我们可以在球体表面添加镜面效果。为了实现这一点,我们将金属度设置为 1,粗糙度设置为 0
然后我们从BimAnt HDRI下载 HDRI 图像并将其添加到我们的目录中。 最终,我们编写了与添加背景场景相关的脚本,结果令人惊讶!
当然,你可以对房间的室内设计进行相同的过程,并在房间背景场景中添加一些逼真的家具和其他元素,并创建自己的虚拟现实版本。
原文链接:How to Add Background Using Orbit Controls in Three JS
BimAnt翻译整理,转载请标明出处