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

 往期回顾:

《Three.JS零基础入门教程》第一篇:搭建开发环境

《Three.JS零基础入门教程》第二篇:起步案例

《Three.JS零基础入门教程》第三篇:开发辅助

《Three.JS零基础入门教程》第四篇:基础变换

《Three.JS零基础入门教程》第五篇:项目规划

《Three.JS零基础入门教程》第六篇:物体详解

《Three.JS零基础入门教程》第七篇:材质详解

《Three.JS零基础入门教程》第八篇:纹理详解

上一期我们介绍了threejs中的物体的材质、纹理,本期主要介绍环境。

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.innerHeightcamera.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.innerHeightcamera.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.innerHeightcamera.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.EquirectangularReflectionMappingscene.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.innerHeightcamera.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.innerHeightcamera.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() * 3const 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 - 10cube.position.y = Math.random() * 20 - 10cube.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.innerHeightcamera.updateProjectionMatrix()renderer.setSize(window.innerWidth, window.innerHeight)
})

请持续关注我,以免错过推送,免费学习threejs。

需要视频教程的宝子加:whx☺zdjy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/861342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【小学期】静态页面设计——以学生管理系统为例

使用Swing设计学生管理系统的静态页面 我们将学习如何使用Java Swing来设计一个学生管理系统的静态页面。我们将创建一个主窗口,其中包含一些基本的组件,如标签、文本框、按钮和表格。 项目结构 首先,假设我们的项目目录结构如下&#xff…

linux下I/O模型并发的epoll多进程池协程实现

方法1 主要思路: 定义了一个EventData结构体,用于存储事件相关的数据,如文件描述符、epoll 文件描述符、协程 ID 等。EchoDeal函数用于处理请求消息,并生成响应消息。handlerClient函数是协程的执行函数,用于处理客户…

gc.log中 CMS-concurrent-abortable-preclean

问题 在gc日志中看到 2024-06-26T16:16:07.5040800: 64690272.666: [CMS-concurrent-abortable-preclean-start]CMS: abort preclean due to time 2024-06-26T16:16:12.5530800: 64690277.716: [CMS-concurrent-abortable-preclean: 1.052/5.049 secs] [Times: user1.33 sys0…

Ubuntu系统安装软件---以安装QQ为例

以安装QQ为例,首先你的Ubuntu系统需要连上网,连上网的网络状态如下图所示。 在ubuntu系统的网页中搜索QQ,如下图所示。 进入QQ官网,点击Linux,如下图所示。 随后会让你选择什么架构的版本,如何查看自己的是…

【Python机器学习】分类向量——One-Hot编码(虚拟变量)

为了学习分类特征,以某国成年人收入数据集(adult)为例,adult数据集的任务是预测一名工人的收入是高于50k还是低于50k,这个数据集的特征包括工人的年龄、雇佣方式、教育水平、性别、每周工作时长、职业等。 这个任务属于…

【LinuxC语言】pthread_join与pthread_detach函数

文章目录 前言线程分离pthread_join函数作用函数原型参数含义返回值示例代码易混pthread_detach函数详解函数作用函数原型参数含义返回值示例代码总结前言 在并发编程中,线程的管理是一个重要的主题。特别是当我们需要处理线程的生命周期和资源管理时,这就变得尤为重要。在L…

代码随想录算法训练营第50天(py)| 动态规划 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列

1143.最长公共子序列 力扣链接 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列(未必连续) 的长度。如果不存在 公共子序列 ,返回 0 。 思路 确定dp含义 dp[i][j]:长度为[0,i-1]和[0,j-1]的最长公…

ONLYOFFICE 桌面编辑器 8.1使用体验分享

目录 编辑器市场现状与用户选择 ONLYOFFICE桌面编辑器概览和功能 ONLYOFFICE桌面编辑器概览 功能丰富的PDF编辑器 演示文稿编辑器的创新 文档编辑的灵活性 电子表格的高级功能 语言和本地化 用户界面和体验 媒体播放 云服务和本地处理 跨平台支持 总结 在线亲身体…

mapstruct实现各个实体间的类型转换(DTO转BO、BO转Entity)的实践

一、引入 在没有遇见mapstruct的时候,实现各个实体之间的转换,都是手动转换实现的,属性少一带你还好,当属性一多,代码就会变得很冗余,没必要的非逻辑的代码就会加多。。。。 比如: public cl…

vue封装原生table表格方法

适用场景:有若干个表格,前面几列格式不一致,但是后面几列格式皆为占一个单元格,所以需要封装表格,表格元素自动根据数据结构生成即可;并且用户可新增列数据。 分类: 固定数据部分 就是根据数据…

React--两种常见的组件嵌套方式

组件嵌套 简介在父组件外部直接使用子组在父组件的实现内部引入并使用子组件区别总结灵活性:可配置性:使用场景: 选择 简介 在 React 中,有两种常见的组件嵌套方式: 在父组件中直接使用子组件。在父组件的实现内部引…

openlayers性能优化——开启图层预加载、减少空白等待时间

使用切片图层时、地图拖拽会有空白图片,为了减少空白等待时间,我们可以开始图层预加载。 const map_top new Map({layers: [new TileLayer({preload:Infinity, //预加载source: new StadiaMaps({layer: "outdoors",}),}),],target: "ma…

LINKAI工作流的建立与调试,用到COW项目的微信机器人上

连接时需要把右边的号连到下一个框的输入,开始与结束是默认的。 可以单独调试模块 可以对模块进行个性化定义 最后进行总流程调试 将这里的code放到config.json文件中 接着又做了一个较复杂的工作流DgPz9wJaoh   QlCc34a8bP 原项目网址: https:/…

小程序中UnionID,AppID,AppSecret,OpenID怎么理解?

小程序中UnionID,AppID,AppSecret,OpenID怎么理解? 个人理解 UnionID:同一用户,对同一个微信开放平台下的不同应用,UnionID 是相同的。 AppID:小程序的身份证号码,是微信公众平台上的小程序 I…

【学习笔记-机器学习】感知机模型

Author:赵志乾 Date:2024-06-26 Declaration:All Right Reserved!!! 1. 基本概念 数据集的线性可分性:给定一个数据集 其中,,,,如果存在某个超平面S 能够将数…

Python的100道练习题目,每日一练,必成大神!!!

整理了100道Python的题目,如果你是一位初学者,这一百多道题可以 帮助你轻松的使用Python。初学 者每天可以尝试3-5个问题,经过这一百道题的练习,要把练习昨晚并且完全懂了,基本上Python就已 经入门了。如果你不是初学者…

Day 34:2368. 受限条件下可到达节点的数目

Leetcode 2368. 受限条件下可到达节点的数目 现有一棵由 n 个节点组成的无向树,节点编号从 0 到 n - 1 ,共有 n - 1 条边。 给你一个二维整数数组 edges ,长度为 n - 1 ,其中 edges[i] [ai, bi] 表示树中节点 ai 和 bi 之间存在一…

OpenCV 车道检测

OpenCV 车道检测 前言模型分析车道检测相关链接 前言 如果要检测道路图像中的车道,方法之一是利用深度学习的语义分割技术。而在 OpenCV 中解决此问题可以使用边缘检测器。在本节中,我们将了解如何使用边缘检测和直线检测识别道路图像中的车道。 模型分…

测试用例的基本要素与设计方法

测试用例的基本要素 测试用例(Test Case)是为了实施测试而向被测试的系统提供的一组集合,这组集合包含:测试环境、操作步骤、测试数据、预期结果等要素。 好的测试用例是一个不熟悉业务的人也能依据用例来很快的进行测试评价测试用…

RT-Thread使用HAL库实现双线程控制LED交替闪烁

如何创建工程我的其他文中你面有可以进去查看 1创建线程(以动态方式实现) 1-2创建函数入口 1-2启动函数 main.c文件源码 /** Copyright (c) 2006-2024, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date …