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)—右手坐标系

Image Text

  • 几何体: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

# 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

# 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: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

# 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