欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 【Threejs学习】创建Threejs页面

【Threejs学习】创建Threejs页面

2024/10/24 16:17:18 来源:https://blog.csdn.net/cpsxn/article/details/141646432  浏览:    关键词:【Threejs学习】创建Threejs页面

学习文档地址:
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.fullscreenElementif (!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 创建网络模型-材质: Basicconst materialBasic = new THREE.MeshBasicMaterial({color: '#4d72a9',wireframe: true, //是否将几何体渲染为线框,默认值为false(即渲染为平面多边形)})// 1.3 创建一个网格模型对象:Meshconst 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.01cube.rotation.y += 0.01//渲染renderer.render(scene, camera)}animate()
}
</script><style lang="scss" scoped>
.my-three {width: 100%;height: 100%;
}
</style>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com