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

news2024/11/17 19:44:37

 往期回顾:

《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.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)
})

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

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

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

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

相关文章

数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南

文章目录 📑引言一、Elasticsearch Pipeline的原理二、Elasticsearch Pipeline的使用2.1 创建 Pipeline2.2 使用 Pipeline 进行索引2.3 常用的 Processor 三、实际应用场景3.1 日志数据处理3.2 数据清洗和标准化3.3 数据增强 四、最佳实践4.1 性能优化4.2 错误处理4…

【CPP】类 -- class 使用思想

目录 3 类 -- class3.1 什么是类3.2 类的定义3.3 类内参数的使用3.4 类与结构体 -- class VS struct3.5 类的实操 -- log类(日志类)3.6 类定义 与 static 3 类 – class 3.1 什么是类 类是面向对象的一种设计,其中封装了我们对对象的"描述",或者说对象的"特征…

生命在于学习——Python人工智能原理(4.6)

在这里插一句话,我有两个好兄弟的github项目,感兴趣的可以去看一下,star一下,谢谢。 https://github.com/fliggyaa/fscanpoc https://github.com/R0A1NG/Botgate_bypass 四、Python的程序结构与函数 4.1 Python的分支结构 &…

C语言——链表专题

乐观学习,乐观生活,才能不断前进啊!!! 我的主页:optimistic_chen 我的专栏:c语言 点击主页:optimistic_chen和专栏:c语言, 创作不易,大佬们点赞鼓…

国产操作系统上多种压缩和解压命令详解 _ 统信 _ 麒麟 _ 中科方德

原文链接:国产操作系统上多种压缩和解压命令详解 | 统信 | 麒麟 | 中科方德 Hello,大家好啊!今天给大家带来一篇在国产操作系统上多种压缩和解压命令详解的文章。压缩和解压缩是我们在日常工作中经常需要进行的操作,尤其是在处理大…

49-2 内网渗透 - 使用UACME Bypass UAC

靶场准备: 1. 使用已有的 Windows 2012 虚拟机 确保你的虚拟机正在运行,并且可以正常访问。2. 添加 test 用户到管理员组(如上篇文件添加过了就跳过这一步) 具体命令如下: net localgroup administrators test /add 3. 切换用户登录 注销当前会话,并使用 test 用户登录。…

理解MySQL索引:提升查询性能的关键

一、前言 在众多数据库中,MySQL以其高效、稳定和跨平台的特点成为许多开发者的首选。然而,随着数据量的不断增加,查询性能可能会成为一个瓶颈。这时,索引(Index)便成为了提升查询速度的关键工具。本篇文章…

ajax请求接口不设置请求头可以请求成功,但是设置请求头之后就跨域,已解决

遇到这个问题我们不要着急找后端,先通过控制台看看有没有报错,控制台的列表是不会有这个红色报错的,所以我们要看下图: 点击这个红色,然后在下面会出现一些信息 很明显是这个请求头timestamp的请求头被屏蔽了&#xff…

网约车停运损失费:1、事故经过

目录 🍅点击这里查看所有博文 随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记…

IT入门知识第八部分《云计算》(8/10)

目录 云计算:现代技术的新篇章 1. 云计算基础 1.1 云计算的起源和发展 云计算的早期概念 云计算的发展历程 1.2 云计算的核心特点 按需自助服务 广泛的网络访问 资源池化 快速弹性 按使用量付费 1.3 云计算的优势和挑战 成本效益 灵活性和可扩展性 维…

Matlab进阶绘图第61期—滑珠散点图

滑珠散点图也是一种在《Nature》中常见的数据图。 其功能类似于柱状图,但更加简洁易读。 由于Matlab中没有现成的函数绘制滑珠散点图,因此需要大家自行解决。 本文利用自己制作的BubbleScatter工具,进行滑珠散点图的绘制,先来看…

验证码技术 easy-captcha

依赖 <!-- easy-captcha用来生成验证码&#xff0c;由于jdk9以后&#xff0c;内置JavaScript去掉了&#xff0c;所以需要导入这个org.openjdk.nashorn --> <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</arti…

Redis数据库(四):Redis数据库事务

经过前面的学习&#xff0c;我们就对于Redis数据库可以进行基本的操作&#xff0c;从这一节开始&#xff0c;我们就正式学习Redis数据库的相关知识&#xff0c;为以后工作打下坚实的基础。 目录 一、事务&#xff08;了解&#xff09; 1.1 Redis的事务概念 1.2 Redis事务…

黑马程序员——Spring框架——day09——linux初级

目录&#xff1a; 前言 什么是Linux&#xff1f;为什么要学Linux 企业用人要求个人发展需要学完Linux能干什么 1).环境搭建2).常用命令3).安装软件4).项目部署小结2.Linux简介 主流操作系统Linux发展历史Linux系统版本Linux安装 安装方式介绍安装VMware安装Linux网卡设置安装S…

我用过最好的GPT,NewspaceGPT使用心得

记住网址&#xff1a;https://newspace.ai0.cn 前言 只要你能表达明白&#xff0c;NewspaceGPT就不会让你失望。 Gpt4o预测GPT5 IT之家6月22日消息&#xff0c;在美国达特茅斯工程学院周四公布的采访中&#xff0c;OpenAI首席技术官米拉穆拉蒂被问及GPT-5是否会在明年发布&…

Beyond Compare不能比较Selinux te文件的解决方案

Beyond Compare不能比较Selinux te文件的解决方案 Beyond Compare默认不能比较te文件&#xff0c;现象如下&#xff1a; 问题原因&#xff1a; 是Beyond Compare将*.te文件识别为一个可执行文件&#xff0c;但是*.te不是一个可执行文件&#xff0c;所以打不开&#xff1b;即使…

微信群聊不见了?掌握这4个技巧轻松找回,简直太爽了

微信&#xff0c;作为国内最受欢迎的社交应用之一&#xff0c;其群聊功能极大地方便了人们的工作与生活。然而&#xff0c;随着加入的群聊数量日益增多&#xff0c;如何快速找到并管理这些群聊成为了一个难题。 幸运的是&#xff0c;微信提供了一些实用的技巧&#xff0c;帮助…

Vue原生写全选反选框

效果 场景&#xff1a;Vue全选框在头部&#xff0c;子框在v-for循环内部。 实现&#xff1a;点击全选框&#xff0c;所有子项选中&#xff0c;再次点击取消&#xff1b;子项全选中&#xff0c;全选框自动勾选&#xff0c;子项并未全选&#xff0c;全选框不勾选&#xff1b;已选…

2024全国大学生信息安全竞赛(ciscn)半决赛(华中赛区)Pwn题解

简介 前段时间赛前准备把ciscn东北赛区、华南赛区、西南赛区半决赛的题都复现完了。 可惜遇到了华东北赛区的离谱平台和离谱pwn出题人&#xff1a; 假的awdp&#xff08;直接传&#x1f40e;到靶机&#xff0c;然后连上去cat /flag.txt即可&#xff09;题型分布不合理&#…

fastadmin框架修改前端时间戳格式的时区

一、上传文件 将 moment-timezone-with-data.js 和 moment-timezone-with-data.min.js 文件上传到项目的 \public\assets\libs\moment\ 文件夹中。 二、配置中引入文件 在 \public\assets\js\require-backend.js 文件中增加所引入文件的配置: moment-timezone-with-data: …