WebGL基础知识
# WebGL基础知识
# 1.WebGL与three.js的基础、与opengl的关系
- WebGL是一项可以在浏览器中流畅展示3d模型和场景的一种技术
- three.js(c语言)是一个封装好的webgl库(汇编语言),它使WebGL的学习更加简单
- WebGL能做什么?游戏,家居,虚拟现实,城市地图,cad制图
扩展1:浏览器为什么能绘制3d技术?
- 因为浏览器实现了opengl es的规范,这套规范可以,直接使用指令操作显卡,使显卡渲染的3d世界,直接翻译到浏览器器上
# 2.四大组建
- 场景—舞台—任何要显示的东西 —可以放2个或多个场景
- 相机—透视相机(远小近大)和正投影相机(远近一样大
- 渲染器—计算的过程叫做渲染
- 几何体—场景中的对象—网格模型
扩展1:场景,相机,几何物体在坐标系中,默认的位置是什么?原点在近平面还是那个位置?
- 在世界坐标的(0,0,0),场景永远在000,没有坐标的概念,相机,几何物体在原点
- 原点不一定在近平面上
扩展2:setClearColorHex和setClearColor区别?
- 相同:设置背景颜色
- 不同:threejs版本问题—查看源码setClearColor为新版本,防止语意化,不一定就非要设置16进制的颜色
# 3.程序启动和执行顺序
- 启动入口:body里面的onload="threeStart()",script写threeStart函数调用
- 执行顺序:初始化获取div元素,初始化渲染器(antialias为true时,抗锯齿,线渲染更清晰,更好的算法渲染,更占用性能),数据量大设置为false, appendChild追加到页面,setClearColor刷新重新绘制,粉刷
- 初始化相机,第三个参数最佳能看到多少米Near,第四个参数最远能看到多少米Far(部分模型城市看不到时,可设置打一点,如40000),设置相机位置position.x,y,z,up和lookAt
- 初始化场景
- 初始化灯光—平行光
- 初始化对象/模型
- 渲染器清除—renderer.clear()
- 再次渲染—renderer.render(scene, camera)
# 4.点,几何体,线材质
- 点:THREE.Vector3(x,y,z)—右手坐标系
- 几何体:THREE.Geometry()—三维数据结构,包含vertices点数组,colors颜色数组,faces面数组
- geometry.vertices.push(new THREE.Vector3(-10,10,0),new THREE.Vector3(10,-10,0))
- geometry.colors.push(new THREE.Color(0xFF0000),new THREE.Color(0xFF0000))—设置线渐变颜色(颜色插值,颜色取决于插值函数)
- 线材质:THREE.LineBasicMaterial()—vertexColors: true,使用顶点颜色
- 材质:材料和质感的结合,各属性的集合
# 5.坐标系
- 世界坐标—公共的场景坐标
- 本地坐标—某个模型物体内的坐标系
- 查看坐标轴— THREE.AxisHelper(4)
扩展1:关于围绕某个轴旋转?
- rotation.y+: 右手大拇指朝上,四指弯曲的方向为+的正方形,rotation.y -:相反
扩展2:如何将模型和坐标系一起旋转?
- THREE.Object3D()
var objectTotal = new THREE.Object3D()
objectTotal.add(model)
objectTotal.add(AxisHelper)
scene.add(objectTotal)
objectTotal.rotation.y -= 0.01
1
2
3
4
5
2
3
4
5
# 6.常用可视化框架
- 百度的「echarts」 蚂蚁的「antv」
- 2d 就是「canvas、 svg」
- 2d游戏Phaser
- 3d 就是 「three.js 或者webgl」 或者 「babylon.js」,ue4,unity
- vue:sandi-ui
- react:lingo3d
- 蚂蚁金服开源3d web引擎Oasis Engine
# 7.常见的文件在线地址
- three.js:http://www.yanhuangxueyuan.com/threejs/build/three.js
- three.min.js:http://www.yanhuangxueyuan.com/threejs/build/three.min.js
- OrbitControls.js:http://www.yanhuangxueyuan.com/threejs/examples/js/controls/OrbitControls.js
- OBJLoader.js:http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/OBJLoader.js
- MTLLoader.js:http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/MTLLoader.js
# 8.常见物理引擎
碰撞检测物理引擎:cannon.js和ammo.js和oimo.js,bullet(opencl加速,不用局限于某个特定的显卡,学术,头发),physx(游戏,商业,unity自带的),havok(商业)
3D 物理引擎库有 Cannon.js(推荐)、Oimo.js(轻量)、Ammo.js、Energy.js(源码不可读)、Physijs(不能用)
cannon.js教程推荐:https://www.mrguo.link/home
# 9.场景建模软件
- c4d blender 3dmax
# 10.学shader用的网站
- thebookofshaders.com(shader入门必备)
- wgld.org(只有日文,直接啃生肉学的,也是偏基础)
- smoothstep.io(可以在线直接编辑shader)
- www.shadertoy.com(上面有很多酷炫的shader供学习用)
- iquilezles.org(学到raymarching必看,iq yyds)
# 11.天空盒
- 天空盒:一个包含场景所有元素的盒子
- 创建天空盒的三种方式:地址:https://blog.csdn.net/xyphf/article/details/121854384
1.创建一个盒子,然后将图片作为盒子6个面的[纹理](https://so.csdn.net/so/search?q=纹理&spm=1001.2101.3001.7020)贴上来创建—THREE.Mesh( skyGeometry, skyMaterial )—全景贴图
2.简单的将纹理作为场景的背景来创建—CubeTextureLoader—给盒子加背景
3.通过着色器的形式
skyBox = new THREE.Mesh(
new THREE.BoxGeometry(10000, 10000, 10000),
new THREE.ShaderMaterial({
fragmentShader: skyboxShader.fragmentShader,//片段着色器
vertexShader: skyboxShader.vertexShader,//顶点着色器
uniforms: skyboxShader.uniforms,//是所有顶点都具有相同的值的变量。 比如灯光,
// 雾,和阴影贴图就是被储存在uniforms中的数据。 uniforms可以通过顶点着色器和片元着色器来访问。
depthWrite: false,//深度测试
side: THREE.BackSide//正反面
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 12.动画分类
- 补间动画—tween—让动画更平滑:.easing(TWEEN.Easing.Quadratic.Out)
- 帧动画—frame 帧动画 AnimationDrawable 控制 animation-list xml布局
- 属性动画—animationClip
扩展1:关键帧动画具体参数
// 创建帧动画对象,使name为door几何体,在3秒内沿着y轴旋转顺时钟旋转90度
const rotationTrack = new THREE.KeyframeTrack(
'door.rotation[y]',
[0, 3],
[0, -Math.PI / 2]
); // 关键帧轨道
1
2
3
4
5
6
2
3
4
5
6
扩展2:tween动画和animationClip动画的区别?
- tween动画:通过view的matrix和alpha变量对view进行修改,但是并不会修改view自身属性—补间动画
- animationClip动画:会修改view的自身属性,动画结束后的效果会实实在在的反应在view上—属性动画
# 13.场景模型来源及学习网址
- gltf和glb格式模型下载网站:www.webvrmodel.com
- 免费模型下载:https://sketchfab.com/search?q=girl&type=models
- 制作动画,绑定骨骼:www.mixamo.com/
- cesium开发案例:http://www.zgeo.work/CesiumTx/examples/index.html#baseDemo-czmlDemo
- cesium学习:https://blog.csdn.net/weixin_45782925/article/details/123269490
- 游戏开发文章:https://zhuanlan.zhihu.com/p/430541328?utm_source=qq&utm_medium=social&utm_oi=896405010206834689
- 3d模型处理:https://3dviewer.net/
- webgl理论学习:https://webglfundamentals.org/webgl/lessons/zh_cn/
- xt3d:https://blog.csdn.net/xietao20?type=blog
# 14.帧动画和补间动画
- 帧动画—模型自身的位置,颜色发生变化,无法监听每帧的变化—toFixed(3)—保留小数点3位置,四舍五入 ,x值为:在1-3判断的,0.003
- 补间动画,2点之间,chain形成闭环连接,onUpdate做之间帧的更新,可以监听每帧的变化
- 不在2点上,2点的判断为1.999/2.000—2.003
# 15.精灵的聚合和分散,点位的拟合
- 三维点的创建方式:CSS2DObject和Sprite精灵
- CSS2DObject--dom元素包装为CSS2模型对象CSS2DObject
- Sprite精灵--THREE.Sprite,THREE.SpriteMaterial,THREE.TextureLoader
- 点跟着弹框一起,是如何实现的?—copy,position属性
法1:获取精灵图位置和摄像位置,控制精灵图显示与隐藏
获取两物体的世界坐标然后计算距离
同时判断世界坐标的方向向量,控制在可视化范围内
他们都是基于Object3D的父类,所以getWorldPosition获取世界坐标系,然后使用distanceTo计算2个的距离,判断就好了
法2:可以借鉴一些地图引擎,如mapbox
法3:高度不同,显示点位个数不同
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 16.支持格式
- OBJ:.obj文件+.mtl文件
- glTF:.gltf文件 / .gltf文件+.bin文件 / .glb文
- FBX:.fbx文件
- STL:.stl文件
- 图片:PNG / JPEG
- 暂不支持动画
# 17.点击模型和平面,无法获取到三维点坐标?
- 在模型加载时,创建平面,1000,1000.基础材质#f00,_Global.getPoint = mesh
- 点击时:let clickArr = raycaster.intersertObject(_Global.getPoint)[0].point
扩展:如何让模型可以点击?
- 在blender中设置模型intersectObject(object, recursive),加入射线属性
# 18.CubeTextureLoader几张图的位置
- 左,右,上,下,背面,正面
# 19.对模型的material修改,发现没有生效,为什么,解决方法?
- material只能是Group类型的才能修改
- filter筛选出Group类型,遍历修改color和opacity