【Three.JS零基础入门教程】第九篇:环境详解

前期回顾:

【Three.JS零基础入门教程】第一课:搭建开发环境

【Three.JS零基础入门教程】第二课:起步案例

【Three.JS零基础入门教程】第三课:开发辅助

【Three.JS零基础入门教程】第四课:基础变换

【Three.JS零基础入门教程】第五课:项目规划

【Three.JS零基础入门教程】第六课:物体详解

【Three.JS零基础入门教程】第七课:材质详解

【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)
})

 GIS资料免费领icon-default.png?t=N7T8https://www.wjx.cn/vm/Qm8Ful2.aspx

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对整threeJS体系进行全面剖析。整理出全面的教学大纲,涵盖内容面非常广。此教学版本为threeJS107版本。关于版本不建议大家使用低于90的版本学习。以下是课程目录1-ThreeJS概览(基本图形简介,什么是点线面如何绘制点线面,什么是材质,什么是几何体,什么是相机,什么是渲染器,什么是场景)2-相机和渲染器(详解相机类型,渲染器如何使用,针对不同场景怎么用,怎么调效果,怎么渲染,怎么输出画布,如何解决透明问题等等)3-创建平面几何(常见的几何体如何使用,如何使用简单的几何体绘制出自定义自己想要的几何体,关于几何体的性能剖析,如何解决性能,几何体的渲染原理)4-高级图形算法常见库(求直线的斜率  计算线段与圆的交点 计算线段的长度 判断折线是否在多边形内 等等)5-sprite精灵(怎么让一个图标永远朝向屏幕,精灵的属性,精灵材质原理等,广告提示框必用)6-骨骼游戏动画(什么是模型动画,常见游戏案例,如何让人头进行各种攻击动作)7-3d模型加载(常见模型格式,如何渲染不同格式,不同格式的特点,什么格式性能优越,模型渲染异常,贴图不显示等问题详解)8-高阶动态纹理(你所不知道的纹理用法,我说你不知道,你肯定不知道)9-漫游轨迹以及其动画路径(怎么绘制贝塞尔曲线,如何使用曲线上的路径,跟随路径移动的原理,相机如何运动,物体如何运动)10-着色器(什么是着色器。初识着色器基础,着色器材质怎么用,怎么使用着色器库)11-常见渲染以及透明度问题12-对象拾取以及拖拽(3d世界里面如何拖拽物体,拖拽的原理,mousemove mouseon等的事件效果)13-世界坐标以及组的问题(什么是相对坐标,什么是世界坐标,什么是当前坐标,怎么转化父子坐标系,组的优化,为什么用组,组的优势)14-指定对象旋转中心(什么是物体的几何体中心,如何改变中心,如何绕轴转动)15-层级对象渲染(多个场景一键切换,切换的优势,针对大项目的用法)16-拓展了解系列(不定期不断更新案例,各种酷炫效果bloom,halo等,以及各种3d图表,粒子案例等,不断构建你的3d实践能力)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值