【Threejs学习】创建Threejs页面

news2024/11/13 16:07:12

学习文档地址:
threejs官网:https://threejs.org/
Threejs官网中文文档:https://threejs.org/docs/index.html#manual/zh/
threejs中文网:http://www.webgl3d.cn/
threejs基础教程:http://www.webgl3d.cn/pages/aac9ab/
webgl基础教程:http://www.webgl3d.cn/pages/9bc0db/
threejs数学几何计算:http://www.webgl3d.cn/pages/001888/
threejs shader:http://www.webgl3d.cn/pages/d30795/
blender基础:http://www.webgl3d.cn/pages/00cfc0/
学习文档下载:
https://gitee.com/xin_hu199/threejs-code-public

git clone https://gitee.com/xin_hu199/threejs-code-public.git

结构图:
image.png
threejs中有三个对象:

  1. 场景
  2. 相机
  3. 渲染器

一、场景 Scene

1.创建场景

  const scene = new THREE.Scene();

2.创建网络模型

2.1 几何体

立方体、球……

1.立方体-BoxGeometry(x, y, z)
const geometry = new THREE.BoxGeometry(5, 5, 5)

image.png
x:左右 const geometry = new THREE.BoxGeometry(10, 5, 5)
y:上下 const geometry = new THREE.BoxGeometry(5, 10, 5)
z:前后 const geometry = new THREE.BoxGeometry(5, 5, 10)
在这里插入图片描述

2 球-SphereGeometry(5, 32, 16)
2.2 材质

创建几何体之后需要给它一个材质,让它有颜色。
Threejs自带了几种材质,每种材质都有相应的属性,如MeshBasicMaterial

1.MeshBasicMaterial

color:十六进制(hex colors)颜色格式
wireframe:是否将几何体渲染为线框,默认值为false(即渲染为平面多边形)

 const materialBasic = new THREE.MeshBasicMaterial({
    color: '#4d72a9',
    wireframe: true
  })
2. MeshPhongMaterial

高光反射材质,可以结合灯光使用,打造更真实立体的效果
材质结合灯光设置阴影效果

2.3 网格 Mesh

网格包含一个几何体以及作用在此几何体上的材质,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。

const geometry = new THREE.BoxGeometry( 1, 1, 1 ); // 几何体
const materialBasic = new THREE.MeshBasicMaterial( { color: '#4d72a9' } ); // 材质
const cube = new THREE.Mesh( geometry, materialBasic ); // 网格
scene.add( cube );

注: 默认在调用 scene.add()时,物体会被添加到(0,0,0)坐标,使得摄像机和立方体在一起。为了防止这种情况的发生,我们需移动摄像机位置,如:camera.position.z = 5。

二、相机 Camera

1.相机类型

three.js 里有几种不同的相机:

  • 透视相机:PerspectiveCamera (透视投影)

模拟人眼视觉效果的相机,进大远小

  • 正交相机:OrthographicCamera(正射投影)

用于渲染2D场景的相机,无论物体距离相机有多远,相机看到的物体大小都会一致
这里使用 PerspectiveCamera(透视摄像机)

  const camera = new THREE.PerspectiveCamera(
    70, // 视野角度:在显示器上能看到的场景范围,单位是角度
    threeRef.value.clientWidth / threeRef.value.clientHeight, // 长宽比:宽 除以 高
    0.1, // 近截面
    1000 // 远截面,某些部分比摄像机的远截面或近截面近的时候,该部分不会被渲染到场景中
  )

构造器: new THREE.PerspectiveCamera( fov: Number, aspect: Number, near: Number, far: Number)
属性:

  • 视野角度 (FOV): 无论在什么时候,你所能在显示器上看到的场景的范围,它的单位是角度(与弧度区分开)。默认值是50
  • 长宽比 (aspect ratio): 物体的宽除以它的高的值。通常是使用画布的宽/画布的高。默认值是1(正方形画布)
  • 近截面 (near)/远截面 (far): 当物体某些部分比摄像机的远截面远或者比近截面近的时候,该这些部分将不会被渲染到场景中。

远截面:默认2000,该值必须大于近截面
近截面:默认0.1,该值在0—far之间,0对于透视摄像机来说不是有效值

  • 其他属性查看文档: filmGauge(胶片尺寸) 、filmOffset(偏移量)、zoom(缩放倍数)……

2.相机位置

语法: camera.position.set(x,y,z);

// 设置相机位置
camera.position.set(10, 10, 10)

注: 如果不设置相机位置,相机会默认在(0,0,0),需要调整相机位置防止摄像机和立方体彼此在一起,如:camera.position.z =5

3.相机视线方向

设置相机看向物体的方向(默认指向三维坐标系的原点)
语法: camera.lookAt(x,y,z);

//相机-视线方向:设置相机看向物体的方向(默认指向三维坐标系的原点)
camera.lookAt(0, 0, 0)

三、使用渲染器渲染场景

three.js 里提供了几种不同的渲染器:

  • WebGLRenderer

这里使用 WebGLRenderer 渲染器

  // 1 创建WebGLRenderer渲染器
  const renderer = new THREE.WebGLRenderer()
  // 2 通过setSize()方法设置渲染的长宽
  renderer.setSize(
    threeRef.value.clientWidth,
    threeRef.value.clientHeight,
    false
  )
  // 3 将渲染器renderer的dom元素(renderer.domElement)添加到页面中
  threeRef.value.appendChild(renderer.domElement)
  // 4 渲染
  renderer.render(scene, camera)

1.创建渲染器

语法: const renderer = new THREE.WebGLRenderer()

2.设置渲染器的尺寸

使用 setSize 传入渲染器的宽高,

 renderer.setSize(
    threeRef.value.clientWidth,
    threeRef.value.clientHeight,
    false
  )

3.渲染场景

添加“渲染循环”(render loop)或者“动画循环”(animate loop)

function animate() {
	requestAnimationFrame( animate );
  // 使立方体动起来
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
	renderer.render( scene, camera );
}
animate();

四、总结

1.步骤

1.创建场景: const scene = new THREE.Scene();
2.创建相机:const camera = new THREE.PerspectiveCamera();
注1: 相机默认位置会和几何体重叠,需要调整相机位置
3.创建立方体: const geometry = new THREE.BoxGeometry(2, 2, 2);
4.添加材质: const materialBasic = new THREE.MeshBasicMaterial({ color: ‘#4d72a9’, wireframe: true });
5.创建网格,将立方体与材质放入: const cube = new THREE.Mesh(geometry, materialBasic);
注2: 创建网格地面,添加到场景中
6.将内容添加到场景中:scene.add(cube);
7.创建渲染器: const renderer = new THREE.WebGLRenderer();
8.将渲染器添加到页面中:document.body.appendChild(renderer.domElement);
9.渲染场景,将场景及摄像机传入: renderer.render(scene, camera);
注3: 第一个参数是场景,第二个参数是摄像机
10.添加动画循环,让立方体动起来

2.示例

示例一:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
		<script type="module">
			import * as THREE from 'https://unpkg.com/three/build/three.module.js';
			
      // 1.创建场景
      const scene = new THREE.Scene();
      // 2.创建相机
      const camera = new THREE.PerspectiveCamera();
      camera.position.z = 10;
      camera.position.y = 2;
      // 3.创建立方体
      const geometry = new THREE.BoxGeometry();
      // 4.添加材质
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
      // 5.创建网格,将立方体和材质放入
      const cube = new THREE.Mesh(geometry, material);
      cube.position.set(0, 3, 0 )
      // 6.将内容添加到场景中
      scene.add(cube);
      // 7.创建渲染器
      const renderer = new THREE.WebGLRenderer();
      // 8.将渲染器添加到页面中
      document.body.appendChild(renderer.domElement);
      // 调整渲染器窗口大小
      renderer.setSize(window.innerWidth, window.innerHeight);
      
      // 添加网格地面
      const gridHelper = new THREE.GridHelper(10, 10);
      // 将网格地面添加到场景中
      scene.add(gridHelper);

      // 9.渲染场景,将场景和摄像机传入
      // renderer.render(scene, camera)

      // 10.让立方体动起来
      function animate() {
        requestAnimationFrame(animate); // 动画循环
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        renderer.render(scene, camera); 
      }
      animate();

		// 双击全屏显示
		window.addEventListener('dblclick', () => {
		  const fullScreenElement = document.fullscreenElement
		  if (!fullScreenElement) {
		    //让画布对象全屏
		    renderer.domElement.requestFullscreen()
		  } else {
		    //退出全屏,使用document对象
		    document.exitFullscreen()
		  }
		})

		</script>
	</body>
</html>

image.png
示例二:

<template>
  <div class="w-100% h-100%">
    <div ref="threeRef" class="w-100% h-100%"></div>
  </div>
</template>

<script setup>
// 引入three.js
import * as THREE from 'three'
import { onMounted, ref, reactive } from 'vue'

let threeRef = ref(null)
// 一、场景:创建场景(scene)
const scene = new THREE.Scene()
let camera = reactive()
const renderer = new THREE.WebGLRenderer()

onMounted(() => {
  initThree()
})

function initThree() {
  // 1.1 创建网络模型-几何体: 立方体-BoxGeometry(x, y, z)
  // const geometry = new THREE.SphereGeometry(5, 32, 16)
  const geometry = new THREE.BoxGeometry(2, 2, 2)
  // 1.2 创建网络模型-材质: Basic
  const materialBasic = new THREE.MeshBasicMaterial({
    color: '#4d72a9',
    wireframe: true, //是否将几何体渲染为线框,默认值为false(即渲染为平面多边形)
  })

  // 1.3 创建一个网格模型对象:Mesh
  const cube = new THREE.Mesh(geometry, materialBasic) //网络模型对象Mesh
  // 1.4 把网格模型添加到三维场景
  scene.add(cube)

  // 1.4.3 修改几何体位置
  cube.position.set(0, 0, 0)
  camera = new THREE.PerspectiveCamera(
    70, // 视野角度:在显示器上能看到的场景范围,单位是角度
    threeRef.value.clientHeight / threeRef.value.clientWidth, // 摄像机视锥体长宽比(aspect)
    0.1, // 近截面
    1000 // 远截面,某些部分比摄像机的远截面或近截面近的时候,该部分不会被渲染到场景中
  )
  // 2.1 相机-位置:设置相机位置
  camera.position.set(10, 10, 10)
  // 2.2 相机-视线方向:设置相机看向物体的方向(默认指向三维坐标系的原点)
  camera.lookAt(0, 0, 0)
  //  防止摄像机和立方体彼此在一起
  // camera.position.z =5;

  // 三、渲染器
  // 3.1 创建WebGLRenderer渲染器

  // 3.2 通过setSize()方法设置渲染的长宽
  renderer.setSize(
    threeRef.value.clientWidth,
    threeRef.value.clientHeight,
    false
  )
  // 3.3 将渲染器renderer的dom元素(renderer.domElement)添加到页面中
  threeRef.value.appendChild(renderer.domElement)

  // 创建光源
  const spotLight1 = new THREE.SpotLight(0xffffff, 1) //(光照颜色, 光照强度)
  // 设置光源位置
  spotLight1.position.set(10, 10, 10)
  const spotLight2 = new THREE.SpotLight(0xffffff, 1) //(光照颜色, 光照强度)
  // 设置光源位置
  spotLight2.position.set(-10, -10, -10)
  // 将光源添加到场景中
  scene.add(spotLight1, spotLight2)
  // 为了方便观察3D图像,添加三维坐标系对象
  // const axes = new THREE.AxesHelper(8) // 坐标系轴长设置为8
  // 把三维坐标系 添加到场景中
  // scene.add(axes)

  // 五、渲染场景
  function animate() {
    //循环调用: 切换到其他页面时会暂停
    requestAnimationFrame(animate)
    // 让立方体动起来
    cube.rotation.x += 0.01
    cube.rotation.y += 0.01
    //渲染
    renderer.render(scene, camera)
  }
  animate()
}
</script>

<style lang="scss" scoped>
.my-three {
  width: 100%;
  height: 100%;
}
</style>

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

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

相关文章

《软件工程导论》(第6版)第6章 详细设计 复习笔记

第6章 详细设计 一、详细设计概述 1&#xff0e;目标 &#xff08;1&#xff09;详细设计阶段的根本目标是确定应该怎样具体地实现所要求的系统&#xff0c;即经过这个阶段的设计工作&#xff0c;应该得出对目标系统的精确描述&#xff0c;从而在编码阶段可以把这个描述直接…

四足机器人控制算法——建模、控制与实践(unitree_guide配置)

目录 官方文档 unitree_guide 1. 快捷指令 2. ROS安装 3. LCM库安装 3.1. 安装步骤 4. pthread库 5. 工程文件下载 6. 编译 报错&#xff1a; 报错1 报错2&#xff1a; 报错3 其他报错 7. 运行 7.1. 运行 Gazebo 仿真环境 7.2. 启动控制器 8. 简单使用 官方文…

贪心(临项交换)

前言&#xff1a;对待这个问题&#xff0c;我想到就是一定是贪心&#xff0c;但是我不知道怎么排序 对待这种问题&#xff0c;肯定是要先假设只有两个&#xff0c;我们要怎么排序呢 class Solution { public:long long minDamage(int power, vector<int>& damage, v…

分布式主键

目录 1.分布式主键的基本需求 2.常见的分布式主键生成策略 2.1UUID&#xff08;128位&#xff09; 2.2MySQL 2.2.1自增主键 2.2.2区间号段 2.3Redis 2.4SnowFlake雪花算法&#xff08;64位&#xff09; 1.分布式主键的基本需求 全局唯一&#xff1a;不管什么主键&…

Linux驱动(二):模块化编程的基本操作

目录 前言一、模块化编程1.模块化驱动代码框架2.printk详解3.应用操作 二、多模块编程三、多文件编程四、函数传参 前言 没多少东西&#xff0c;就是最基础的一些Linux驱动编写操作。 一、模块化编程 驱动加载到内核中的两种方法&#xff1a; 1.静态编译&#xff1a;就是将模…

【Python百日进阶-Web开发-Feffery】Day500 - dash使用秘籍

文章目录 前言:fac是什么?“人生苦短,我用Python;Web开发,首选Feffery!”↓↓↓ 今日笔记 ↓↓↓1 dash应用使用cdn加载静态资源1.1 页面效果1.2 项目源码2 suppress_callback_exceptions=True3 阻止首次回调3.1 阻止所有回调函数的首次回调3.2 阻止单个回调函数的首次回…

《JavaEE进阶》----5.<SpringMVC②剩余基本操作(CookieSessionHeader响应)>

Cookie和Session简介。 Spring MVC的 2.请求 Cookie的设置和两种获取方式 Session的设置和三种获取方式。 3.响应 1.返回静态页面 2.返回数据 3.返回HTML片段 4.返回JSON 5.设置状态码 6.设置header 三、&#xff08;接上文&#xff09;SpringMVC剩余基本操作 3.2postman请求 …

CSAPP Data Lab

CSAPP 的第一个 Lab&#xff0c;对应知识点为书中的第 2 章&#xff08;信息的表示与处理&#xff09;&#xff0c;要求使用受限制的运算符和表达式实现一些位操作。主要分为两个部分&#xff1a;整数部分和浮点数部分。其中整数部分限制较多&#xff0c;比较偏重技巧性&#x…

Red Hat Enterprise Linux 9—Red Hat 9.4Linux系统 Mac电脑虚拟机安装【保姆级教程】

Mac分享吧 文章目录 效果一、下载软件二、安装软件与配置1、安装2、配置 三、查看基本信息安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件 地址&#xff1a;www.macfxb.cn 二、安装软件与配置 1、安装 2、配置 三、查看基本信息 安装完成&#xf…

【国考】特值法

特值法 题干中存在乘除关系&#xff0c;且对应量未知。 例3&#xff1a;甲、乙、丙三个工程队的效率比为6&#xff1a;5&#xff1a;4,现将A、B两项工作量相同的工程交给这三个工程队,甲队负责A工程,乙队负责B工程,丙队参与A工程若干天后转而参与B工程.两项工程同时开工,耗时16…

【PyQt6 应用程序】视频百叶窗效果一键生成模块

在现代的多媒体创作中,音频和视频的结合是提升作品感染力的关键因素之一。尤其是短视频的制作,往往需要根据音频的节奏进行精细的剪辑和特效添加。PyQt6 作为一个功能强大的 Python GUI 库,为我们提供了极大的便利,使得我们可以轻松地创建功能丰富的应用程序。 本教程将一…

J.U.C并发工具集实战及原理分析

​在J.U.C里提供了很多的并发控制工具类&#xff0c;这些工具类可以使得线程按照业务的某种约束来执行。本节包含CountDownLatch、Semaphore、CyclicBarrier等工具类。目的是了解他们基本使用、原理及实际应用。 1. CountDownLatch主题 1.1 CountDownLatch简介 CountDownLat…

ShardingSphere-JDBC实现数据加解密

一、什么是ShardingSphere&#xff1f; ShardingSphere定位为轻量级 Java 框架&#xff0c;在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库&#xff0c;以 jar 包形式提供服务&#xff0c;无需额外部署和依赖&#xff0c;可理解为增强版的 JDBC 驱动&#xff0c;完…

最优化理论(一)

什么是最优化问题 最优化问题是决策问题&#xff0c;选择一下可以执行的策略来使得目标最优。 一个最优化问题包括&#xff1a; 决策变量一个或多个目标函数一个由科兴策略组成的集合&#xff0c;可由等式或者不等式刻画 最优化问题的基本形式&#xff1a; 最优化问题的分类…

upload-labs通关攻略

Pass-1 这里上传php文件说不允许上传 然后咱们开启抓包将png文件改为php文件 放包回去成功上传 Pass-2 进来查看提示说对mime进行检查 抓包把这里改为image/jpg; 放包回去就上传成功了 Pass-3 这里上传php文件它说不允许上传这些后缀的文件 那咱们就可以改它的后缀名来绕过…

Guitar Pro 8.2.1 Build 32+Soundbanks Win/Mac音色库 开心激活版 音乐软件Guitar Pro 8中文破解版

音乐软件Guitar Pro 8中文破解版是一个受吉他手喜爱的吉他和弦、六线谱、BASS 四线谱绘制、打印、查看、试听软件&#xff0c;它也是一款优秀的 MIDI 音序器&#xff0c;MIDI 制作辅助工具&#xff0c;可以输出标准格式的 MIDI。GP 的过人之处就在于它可以直接用鼠标和键盘按标…

过滤器 与 拦截器

文章目录 过滤器 与 拦截器一、过滤器&#xff08;Filter&#xff09;1、特点2、生命周期3、实现4、过滤器链1&#xff09;配置 order2&#xff09;执行顺序 二、拦截器 Inteceptor1、特点2、生命周期3、实现4、拦截器链1&#xff09;配置 order2&#xff09;执行顺序&#xff…

【Linux】保姆级 Linux 常见命令使用

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. Linux 是什么1.1 Linux 是什么1.2 关于 Linux 我们需要学什么 2. 需提前准备的东西2.1 环境 —— 如何获取…

关于PowerDesigner的使用

1.PowerDesigner概述&#xff1a; 1.PowerDesigner是一款开发人员常用的数据库建模工具&#xff0c;用户利用该软件可以方便地制作 数据流程图、概念数据模型 、 物理数据模型 &#xff0c;它几乎包括了数据库模型设计的全过程&#xff0c;是Sybase公司为企业建模和设计提供的…

蓝色炫酷碎粒子HTML5导航源码

源码介绍 蓝色炫酷碎粒子HTML5导航源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 效果预览 源码获取 蓝色炫酷碎粒…