河北网站建设费用,虚拟展馆官方网站建设,深圳住房和建设局网站预约放号,六安哪里有做推广网站文章目录 three.js 学习笔记基础概念透视相机 第一个three.js应用threejs画布尺寸和布局canvas画布宽高度动态变化 坐标辅助器 THREE.AxesHelper实现动画效果requestAnimationFrame时间相关属性和方法 THREE.Clock类 相机控件 轨道控制器OrbitControls 灯光点光源点光源辅助观察… 文章目录 three.js 学习笔记基础概念透视相机 第一个three.js应用threejs画布尺寸和布局canvas画布宽高度动态变化 坐标辅助器 THREE.AxesHelper实现动画效果requestAnimationFrame时间相关属性和方法 THREE.Clock类 相机控件 轨道控制器OrbitControls 灯光点光源点光源辅助观察 PointLightHelper 平行光平行光与mesh表面光线反射规律平行光辅助观察 DirectionalLightHelper 环境光AmbientLight stats性能监视器场景中的物体常见几何体材质 MaterialMeshLamberMaterial高光网格材质 MeshPhongMaterial WebGL渲染器 three.js 学习笔记
openGL是一个跨平台3D/2D的绘图标准WebGL是openGL在浏览器中的一个实现默认右手系。
编程人员可以直接用WebGL接口进行编程但需要一定的学习成本且代码量大。Three.js对WebGL进行了封装更为轻松地进行Web 3D开发降低使用门槛的同时提高了开发效率。 学习资源 three.js中文文档 three.js学习视频 three.js学习文档 24.1.10 目前是入门阶段学习内容很浅在后期学习中会不断重构笔记。 基础概念
属性名称描述场景(Scene)是一个三维空间所有物品的容器可以把场景想象成一个空房间接下来会往房间里放要呈现的物体、相机、光源等。可以配合 chrome 插件使用抛出 window.scene 即可实时调整 obj 的信息和材质信息。相机(Camera)必须要往场景中添加一个相机相机用来确定位置、方向、角度相机看到的内容就是我们屏幕中看到的内容。正交相机无论物体距离相机距离远或者近最终渲染的图片大小都保持不变适用于渲染2D场景或者UI元素透视相机近大远小类似人眼物体对象(Mesh)包括二维物体点、线、面、三维物体、模型等等。光源(Light)场景中的光照如果不添加光照场景将会是一片漆黑包括全局光、平行光、点光源等。渲染器(Renderer)相当于咔擦一下的拍照动作得到一张静态照片。取值代表渲染方式如 WebGL、canvas2D、css3D。控制器(Control)可通过键盘、鼠标控制相机的移动。
透视相机
视锥体是摄像机可见的空间超出视锥体界面的部分会倍剪裁掉。
语法new THREE.PerspectiveCamera(垂直视野角度 , width / height, 1, 1000 );
摄影机视锥体垂直视野角度角度越大可以看到渲染范围更大远小近大的视觉效果更明显。相机宽高比表示输出图像的宽和高之比摄像机视锥体近切面摄像机视锥体远切面 当远切面过小与当近切面过大模型在视锥体之外的情况
相机属性
position: 相机的位置默认(0,0,0)lookAt相机看向哪一个点默认看向Z轴负半轴方向up相机的朝向哪一根坐标向上默认(0,1,0)。up属性必须设置在lookAt之前
相机的拍摄方向由相机位置和观察物体的点共同构成
// 设置相机的位置
camera.position.set(x,y,z);
camera.position.x x;
camera.position.y y;
camera.position.z z;// 设置相机观察的点
camera.lookAt(0, 0, 0); 第一个three.js应用
1.创建一个项目
# 创建一个项目
pnpm create vite
pnpm install
pnpm run dev
# 安装依赖
pnpm install three2.在App.vue中创建第一个three.js应用
三维物体要渲染在二维屏幕上首先需要创建一个场景来放置物体然后将相机放在场景中某个位置进行拍摄最终
由渲染器将拍摄内容渲染出来
import * as THREE from three;
// 1.创建场景
const scene new THREE.Scene();// 2.创建透视相机 有几种不同的相机案例使用透视摄像机
const camera new THREE.PerspectiveCamera(45, // 视野角度 单位是角度window.innerWidth / window.innerHeight, // 相机宽高比 拍出图片的宽高比涉及到图片压缩// 当物体某些部分比摄像机的远截面远或者比近截面近的时候该部分将不会被渲染到场景中。0.1, // 近截面1000 // 远截面
);
// 设置相机位置 Z轴正方向从屏幕中穿出来
camera.position.z 5;
camera.lookAt(0, 0, 0); // 默认值相机看向原点// 3.初始化渲染器由渲染器将图片渲染在画布上
const renderer new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染的尺寸大小// 创建几何体
const geometry new THREE.BoxGeometry(1, 1, 1);
// 创建材质
const material new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 设置颜色 16进制
// 创建网格
const cube new THREE.Mesh(geometry, material);
// 将网格添加到场景中
scene.add(cube);// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);// 渲染
// renderer.render(scene, camera);// 设置渲染函数(可以将其称为渲染循环)方便观察
const animete () {requestAnimationFrame(animete);// 周期性旋转每次旋转0.01弧度cube.rotation.x 0.01; cube.rotation.y 0.01; // 使用渲染器通过相机将场景渲染进来renderer.render(scene, camera);
};
animete();threejs画布尺寸和布局
treejs渲染输出的结果就是一个Cavnas画布renderer.domElement属性获取该画布。
// 初始化渲染器由渲染器将图片渲染在画布上
const renderer new THREE.WebGLRenderer();
// 设置渲染的尺寸大小,全屏渲染
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera); 全屏布局注意CSS设置
stylebody{overflow: hidden; // 不使用滚动条margin: 0px;}
/stylecanvas画布宽高度动态变化
canvas画布宽高度动态变化需要更新相机和渲染的参数否则无法正常渲染。
如果canvas宽高比发生变化 1.更新相机的宽高比camera.aspect该参数与canvas画布高宽相关(初始化时设置为window.innerWidth / window.innerHeight) 2.如果相机的属性发生变化需要执行updateProjectionMatrix ()方法更新相机的投影矩阵。 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix但是不会每渲染一帧都通过相机的属性计算投影矩阵(节约计算资源)。所以如果相机的一些属性发生了变化需要执行updateProjectionMatrix ()方法更新相机的投影矩阵。 // onresize 事件会在窗口被调整大小时发生
window.onresize function () {// 重置渲染器输出画布canvas尺寸renderer.setSize(window.innerWidth, window.innerHeight);// 全屏情况下设置观察范围长宽比aspect为窗口宽高比camera.aspect window.innerWidth / window.innerHeight;// 更新相机的投影矩阵camera.updateProjectionMatrix();
};坐标辅助器 THREE.AxesHelper
坐标辅助器new THREE.AxesHelper( 坐标轴线的长度) 红色(R)代表 X 轴. 绿色(G)代表 Y 轴. 蓝色(B)代表 Z 轴。
const axesHelper new THREE.AxesHelper( 5 );
scene.add( axesHelper );实现动画效果
requestAnimationFrame
requestAnimationFrame学习笔记
// 渲染循环函数
const animete () {requestAnimationFrame(animete);// 周期性旋转每次旋转0.01弧度cube.rotation.x 0.01; cube.rotation.y 0.01; // 使用渲染器通过相机将场景渲染进来renderer.render(scene, camera);
};
animete();时间相关属性和方法 THREE.Clock类 中文文档Clock 语法: Clock( autoStart : Boolean )
autoStart 可选在第一次调用 .getDelta() 时自动开启时钟默认值是 true。
类实例的方法与属性
属性/方法描述autoStart boolean默认为true是否在第一次调用getDelta时开启时钟startTime Float默认为0时钟最后一次调用start方法的时间记录开启时钟的时间。oldTime Float默认为0记录上一次时间(老时间)start ()启动时钟①startTime和 oldTime设置为当前时间②elapsedTime 设置为 0③ running设置为truegetDelta ()获取自 oldTime设置后到当前的秒数①oldTime设置为当前时间②autoStarttrue 且时钟并未运行则该方法同时启动时钟(可能是调用start方法)
需求需要求解两次渲染的时间差
import * as THREE from three;
const clock new THREE.Clock
function render(){// 获取两次函数调用的时间差,返回值是秒const spt clock.getDelta()*1000; console.log(两次渲染时间间隔(毫秒),spt);mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度renderer.render(scene, camera);requestAnimationFrame(render);//请求再次执行渲染函数render渲染下一帧
}
render();相机控件 轨道控制器OrbitControls
语法new OrbitControls(相机, 渲染画布的dom对象)
相机:控制器改变哪一个相机渲染的画布dom对象监控哪一片区域的事件可以通过renderer.domElement获取画布。
本质是通过改变相机的属性从而改变拍照的结果 比如相机的位置属性改变相机位置也可以改变相机拍照场景中模型的角度实现模型的360度旋转预览效果改变透视投影相机距离模型的距离就可以改变相机能看到的视野范围。
相机空间轨道控制器的使用 给控制器添加change事件每当控制器修改相机参数就会触发change事件回调。
如果设置了渲染循环相机控件OrbitControls就不用设置change监听执行renderer.render(scene, camera);
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from three/addons/controls/OrbitControls.js;// 设置相机控件轨道控制器OrbitControls
const controls new OrbitControls(camera, renderer.domElement);// 如果OrbitControls改变了相机参数重新调用渲染器渲染三维场景
controls.addEventListener(change,(){renderer.render(scene, camera);
})相机控件 OrbitControls会导致相机lookAt失效需要手动设置OrbitControls的目标参数
// 设置相机控件轨道控制器OrbitControls
const controls new OrbitControls(camera, renderer.domElement);
// 相机控件.target属性在OrbitControls.js内部表示相机目标观察点默认0,0,0
// console.log(controls.target, controls.target);
controls.target.set(1000, 0, 1000);
controls.update();//update()函数内会执行
灯光
使用Light模拟光照对网格模型mesh(物体表面)的影响如果使用受光照影响的材质在不开灯的情况下是看不见的。
不受光照影响的材质 基础MeshBasicMaterial 受光照影响的材质 漫反射MeshLambertMaterial高光MeshPhongMaterial物理 MeshPhysicalMaterialMeshStandarMaterial
如果希望光源照在模型的外表面就需要将光源放在模型的外面
点光源 点光源构造器PointLight(color:Intege, intensity:Float, distance:Number, decay:Float)
color可选点光源照射出的光线颜色十六进制默认是0xffffff白色intensity可选光照的强度默认1distance从光源到光照强度为0的位置也就是说光源可以照射到的最大距离如果将其设置为0光永远不会消失(距离无穷大)默认0decay沿着光照距离的衰退量默认是2不想衰退可以设置为1 想象灯光越靠近光源光线越亮。光线会随距离的增而衰弱
创建一个点光源
const pointLight new THREE.PointLight( 0xffffff, 1, 0 );
scene.add( light ); // 添加到场景中构造器传参本质是修改点光源实例的对应属性
pointLight.color 0xffffff
pointLight.intensity 1
pointLight.distance 100
/*
等价于
pointLight.position.x ,pointLight.position.y ,pointLight.position.z
*/
pointLight.position.set(x,y,z)
// 设置光源是否可见
pointLight.visible:boolean点光源辅助观察 PointLightHelper
PointLightHelper点光源辅助观察对象可以可视化点光源
语法:PointLightHelper(light:PointLight,sphereSize:Float,color:Hex) 参数
light 模拟的光源,光源构造器返回值sphereSize 可选球形辅助对象的尺寸默认为1color 可选默认使用光源的颜色
const pointLight new THREE.PointLight( 0xffffff, 1, 0 );
const pointLightHelper new THREE.PointLightHelper(pointLight, 1);
scene.add(pointLightHelper);平行光 语法:DirectionalLight( color : Color, intensity : Float )
color 可选光源颜色默认白色intensity 可选光照的强度默认值为 1。
平行光的方向是一个矢量平行光的属性如下
directionalLight..isDirectionalLight 只读用于检查对象的类型是否为 DirectionalLight。directionalLight.position Vector3 设置光源的起始位置directionalLight.target Object3D 灯光从它的位置position指向目标位置,默认的目标位置为(0, 0, 0)。 对于目标的位置如果要改为除默认值之外的其他位置该位置必须被添加到场景scene中去。
// 平行光
const directionalLight new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// 方向光指向对象网格模型mesh可以不设置默认的位置是0,0,0
directionalLight.target mesh;
scene.add(directionalLight);平行光与mesh表面光线反射规律
平行光照射到网格模型Mesh表面光线和模型表面(每个平面)构成一个入射角度入射角度不同对光照的反射能力不同。
反射的光线越多光越亮反射的光线越少光越暗。
平行光辅助观察 DirectionalLightHelper
DirectionalLightHelper平行光辅助观察对象可以可视化平行光
语法:DirectionalLightHelper( light : DirectionalLight, size : Number, color : Hex )\
light 被模拟的平行光size 可选的平面的尺寸默认为 1color 可选的如果没有设置颜色将使用光源的颜色
// DirectionalLightHelper可视化平行光
const dirLightHelper new THREE.DirectionalLightHelper(directionalLight, 5,0xff0000);
scene.add(dirLightHelper);环境光AmbientLight
环境光AmbientLight没有特定方向整体改变场景的光照会均匀的照亮场景中的所有物体。因为没有方向所以不能用来投射阴影。
语法:AmbientLight( color : Color, intensity : Float )
color 可选光源颜色默认白色intensity 可选光照的轻度默认值为1
//环境光:没有特定方向整体改变场景的光照明暗
const ambient new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);stats性能监视器
three.js每执行WebGL渲染器.render()方法一次就在canvas画布上得到一帧图像不停地周期性执行.render()方法就可以更新canvs画布内容。
通过stats.js库可以查看three.js当前的渲染性能具体说就是计算three.js每秒钟完成的渲染次数。一般渲染达到每秒钟60次为最佳状态。
使用 Stats 需要做以下几步操作
实例化 Stats设置初始面板 stats.setMode(0) 。 参数是传入面板id(0: fps, 1: ms, 2: mb) 0是默认模式显示渲染帧数(一秒渲染次数)1显示渲染周期(渲染一帧需要多长时间ms)设置监视器的位置将监视器添加到页面中刷新帧数 stats.update()
在使用 npm install three 下载的依赖包中已经包含了 Stats.js 了
// 1. 引入性能监视器stats.js
import Stats from three/addons/libs/stats.module.js;// 1.创建stats对象
const stats new Stats();// 2.设置监视器面板传入面板id0: fps, 1: ms, 2: mb
stats.setMode(0)// 3.设置监视器位置 可以通过style修改样式
stats.domElement.style.position absolute
stats.domElement.style.left 0px
stats.domElement.style.top 0px// 4.stats.domElement:web页面上输出计算结果,一个div元素
document.body.appendChild(stats.domElement);// 渲染函数
function render() {// 5. 调用update刷新帧率stats.update();renderer.render(scene, camera); //执行渲染操作requestAnimationFrame(render); //请求再次执行渲染函数render渲染下一帧
}
render();场景中的物体
物体 几何体 材质
常见几何体
//BoxGeometry长方体 xyz
const geometry new THREE.BoxGeometry(100, 100, 100);
// SphereGeometry球体 半径
const geometry new THREE.SphereGeometry(50);
// CylinderGeometry圆柱圆台 顶部半径、底部半径、圆柱高度
const geometry new THREE.CylinderGeometry(50,50,100);
// PlaneGeometry矩形平面 xy
const geometry new THREE.PlaneGeometry(100,50);
// CircleGeometry圆形平面 半径
const geometry new THREE.CircleGeometry(50);对于平面图形材质默认正面可见反面不可见
// 平面图形默认只有正面可见
new THREE.MeshBasicMaterial({side: THREE.FrontSide, //默认只有正面可见
});
// 设置双面可见
new THREE.MeshBasicMaterial({side: THREE.DoubleSide, //两面可见
});材质 Material MeshLamberMaterial
对光照的反射为漫反射光线向四周反射。
高光网格材质 MeshPhongMaterial
语法:new MeshPhongMaterial( parameters : Object ) 参数对象的属性 自有属性 Material基类继承的属性对光照的反射为镜面反射想象一面镜子的反射如果刚好反射光对眼睛会非常刺眼某个局部区域高亮像擦了高光
注意AmbientLight环境光没有方向整体改变场景的光照。所以只有环境光的高光效果会失效。
MeshPhongMaterial高光网格材质配置参数的自有属性
属性名属性描述shininess高亮的程度越高的值越闪亮默认30specular高光颜色默认为0x111111灰色
WebGL渲染器
const renderer new THREE.WebGLRenderer();
// 设置渲染器输出的画布大小
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);语法:new WebGLRenderer( parameters : Object ) antialias: 是否执行抗锯齿默认为false。