《Three.JS零基础入门教程》-----之环境详解

1 简介

通过前面的学习, 我们了解到场景就是对一个3D世界的模拟

threejs中, Scene是一个对象. 主要属性

  • background: 背景(颜色, 纹理)

  • environment: 环境

  • fog: 雾化

图片

2 背景颜色

通过scenebackground属性, 可以设置一个纯色作为背景

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

// 导入封装的MeshGui
import { MeshGui } from '../gui'

// 一. 创建场景
const scene = new THREE.Scene()
scene.background = new THREE.Color(0x0000ff)

// 二. 创建相机
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight
)
camera.position.set(0, 0, 5)

// 三. 创建物体
const sphereGeometry = new THREE.SphereGeometry(1, 32, 32)
const sphereMaterial = new THREE.MeshNormalMaterial()
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
scene.add(sphere)

new MeshGui({
  target: sphere,
})

// 四. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setAnimationLoop(animation)
// 将渲染的canvas添加到body元素中
document.body.appendChild(renderer.domElement)

// 五. 辅助工具
const control = new OrbitControls(camera, renderer.domElement)

const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)

const gridHelper = new THREE.GridHelper(20, 20, 0xffffff, 0xffffff)
gridHelper.material.transparent = true
gridHelper.material.opacity = 0.5
scene.add(gridHelper)

function animation() {
  renderer.render(scene, camera)
}

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
})

3 背景图片

1) 单一图片

background属性也可以接收一个texture纹理对象作为参数

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

// 导入封装的MeshGui
import { MeshGui } from '../gui'

// 一. 创建场景
const scene = new THREE.Scene()
// 创建一个纹理加载器, 加载纹理图片
const texture = new THREE.TextureLoader().load('/src/assets/texture/bg.jpeg')
scene.background = texture

// 二. 创建相机
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight
)
camera.position.set(0, 0, 5)

// 三. 创建物体
const sphereGeometry = new THREE.SphereGeometry(1, 32, 32)
const sphereMaterial = new THREE.MeshNormalMaterial()
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
scene.add(sphere)

new MeshGui({
  target: sphere,
})

// 四. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setAnimationLoop(animation)
// 将渲染的canvas添加到body元素中
document.body.appendChild(renderer.domElement)

// 五. 辅助工具
const control = new OrbitControls(camera, renderer.domElement)

const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)

const gridHelper = new THREE.GridHelper(20, 20, 0xffffff, 0xffffff)
gridHelper.material.transparent = true
gridHelper.material.opacity = 0.5
scene.add(gridHelper)

function animation() {
  renderer.render(scene, camera)
}

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
})

提示: 如果图片不显示

  1. 检查路径是否正解

  2. 是否开启了动画循环

2) 全景图

为了模拟更加逼真的3D场景, 我们可以使用全景图, 就是由6张图拼接

  • px: x轴正方向

  • nx: x轴负方向

  • py: y轴正方向

  • ny: y轴负方向

  • pz: z轴正方向

  • nz: z轴负方向

基础原理

在上面我们模拟过全景图, 就是设置一个足够大的立方体, 给每个面都贴上图, 这里我们给场景设置

示例:

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

// 一. 创建场景
const scene = new THREE.Scene()
// 创建一个纹理加载器, 加载纹理图片

const texture = new THREE.CubeTextureLoader()
  .setPath('/src/assets/texture/park/')
  .load([
    'posx.jpg',
    'negx.jpg',
    'posy.jpg',
    'negy.jpg',
    'posz.jpg',
    'negz.jpg',
  ])

scene.background = texture

// 二. 创建相机
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight
)
camera.position.set(0, 0, 5)

// 四. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setAnimationLoop(animation)
// 将渲染的canvas添加到body元素中
document.body.appendChild(renderer.domElement)

// 五. 辅助工具
const control = new OrbitControls(camera, renderer.domElement)

function animation() {
  renderer.render(scene, camera)
}

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
})

3) HDR图

什么是HDR图

HDR 是高动态范围 (High Dynamic Range) 的缩写。它是一种通过在数字图像中捕捉比传统图像技术更广泛的亮度范围来提高图像质量的技术。HDR 图像可以展现更多的颜色和阴影细节,使图像看起来更接近真实世界的视觉效果。

一句话解释

HDR图有更好的显示效果, 高清无码

示例

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'

// 一. 创建场景
const scene = new THREE.Scene()
// 创建一个纹理加载器, 加载纹理图片
const texture = new RGBELoader().load('/src/assets/hdr/city.hdr', () => {
  texture.mapping = THREE.EquirectangularReflectionMapping
  scene.background = texture
})

// 二. 创建相机
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight
)
camera.position.set(0, 0, 5)

// 四. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setAnimationLoop(animation)
// 将渲染的canvas添加到body元素中
document.body.appendChild(renderer.domElement)

// 五. 辅助工具
const control = new OrbitControls(camera, renderer.domElement)

function animation() {
  renderer.render(scene, camera)
}

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
})

效果

4 环境属性

统一设置场景中所有物理材质环境贴图

如果给每一个物体都单独设置环境纹理贴图比较麻烦. 可以在场景中统一设置

设置后, 场景中所有物理材质都会使用该环境纹理贴图

背景与环境的区别

  • 场景的背景设置的是整个3D世界的背景, 作用于场景

  • 场景的环境设置的是3D世界中所有PBR材质的默认环境纹理贴图, 作用于物体

完整示例

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

// 一. 创建场景
const scene = new THREE.Scene()
// 创建一个纹理加载器, 加载纹理图片

const texture = new THREE.CubeTextureLoader()
  .setPath('/src/assets/texture/Park3Med/')
  .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'])

scene.background = texture
scene.environment = texture

// 二. 创建相机
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight
)
camera.position.set(0, 0, 100)

const cubeGeometry = new THREE.BoxGeometry(10, 10, 10)
const cubeMaterial = new THREE.MeshStandardMaterial({
  roughness: 0,
  metalness: 1,
})

const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)

const sphereGeometry = new THREE.SphereGeometry(10, 32, 32)
const sphereMaterial = new THREE.MeshStandardMaterial({
  roughness: 0,
  metalness: 1,
})
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.position.set(20, 0, 0)

scene.add(cube)
scene.add(sphere)

// 四. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setAnimationLoop(animation)
// 将渲染的canvas添加到body元素中
document.body.appendChild(renderer.domElement)

// 五. 辅助工具
const control = new OrbitControls(camera, renderer.domElement)

function animation() {
  renderer.render(scene, camera)
}

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
})

效果

图片

5 雾化

雾化效果

场景中的物体距离相机的距离不同, 显示的颜色不同

  • 越近越清晰(接近物体本身的颜色)

  • 越远越模糊(接近雾的颜色)

scene.fog = new THREE.Fog(0x0000ff, 50, 100)
  • 第一个参数: 雾的颜色

  • 第二个参数: 雾化生效的近面距离. 小于该值显示物体本身的颜色

  • 第三个参数: 雾化生效的远面距离. 大于该值显示雾的颜色

完整示例

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

import * as dat from 'dat.gui'

// 一. 创建场景
const scene = new THREE.Scene()
scene.fog = new THREE.Fog(0x0000ff, 1, 100)

// 二. 创建相机
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight
)
camera.position.set(0, 0, 50)

// 三. 创建物体

const gui = new dat.GUI()
const data = {
  addCube: function () {
    const size = Math.random() * 3
    const cubeGeometry = new THREE.BoxGeometry(size, size, size)
    const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 })
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)

    cube.position.x = Math.random() * 20 - 10
    cube.position.y = Math.random() * 20 - 10
    cube.position.z = Math.random() * 20 - 10
    // console.log(cube)
    scene.add(cube)
  },
}
gui.add(data, 'addCube')

// 四. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setAnimationLoop(animation)
// 将渲染的canvas添加到body元素中
document.body.appendChild(renderer.domElement)

// 五. 辅助工具
const control = new OrbitControls(camera, renderer.domElement)

const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)

const gridHelper = new THREE.GridHelper(20, 20, 0xffffff, 0xffffff)
gridHelper.material.transparent = true
gridHelper.material.opacity = 0.5
scene.add(gridHelper)

function animation() {
  renderer.render(scene, camera)
}

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值