ThreeJs学习

1 基本使用

//1、创建场景
const scene = new THREE.Scene()
//2、创建网格模型
const geometry = new THREE.BoxGeometry(100,100,100)
const matrial = new THREE.MeshLambertMaterial({
	color: #0000ff
})
const mesh = new THREE.Mesh(geometry,matrial)
scene.add(mesh)
//3、添加光照
const point = new THREE.PointLight(0xffffff)
point.position.set(10,20,30)
scene.add(point)

const ambient = new THREE.ambient(0x444444)
scene.add(ambient)

//设置相机
const width = window.innerWidth
const height = window.innerHeight
const aspect = width/height
const s = 20

//参数为左右上下近远
const camera = new THREE.OrthographicCamera(-s*aspect,s*aspect,s,-s,1,1000)
camera.position.set(10,10,10)
camerta.lookAt(camera.position)

//设置渲染器对象
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width.height)
renderer.setClearcolor(0x,fffffff,1)
document.body.appendChild(renderer.domElement)

renderer.renderer(scene,camera)

2 相机轨道控制旋转缩放

const controls = new THREE.OrbitControls(camera,renderer.domElement)
controls.addEventListener('change',render)	//自动监听鼠标键盘事件,更新相机参数

//如果使用requestAnimationFrame调用render函数,则不需要添加监听事件

3 设置材质效果

  • color:材质颜色
  • wireframe:将几何图形渲染为线框
  • opacity:设置透明度
  • transparent:是否开启透明
new THREE.MeshlambertMatrial({
	color: 0xff0000,
	opacity: 0.7,
	transparent: true
})

//也可以以对象方式设置
material.opacity = 0.7

4 添加高光效果

  • ambient:环境色,于与AmbientLight光源一起使用颜色会相乘
  • emissive:材质发射的亚瑟,不受其他光照影响的颜色
  • specular:光亮程度及高光部分颜色
  • shininess:指定高光部分的亮度
new THREE.MeshPhongMaterial({
	color: #ffffff,
	specular: 0x4488ee,
	shininess: 12
})

5 材质类型

  • MeshLambertMaterial:lambert网格材质,与光照有反应,漫反射
  • MeshBasicMaterial:基础网格材质,不受光照影响
  • MeshPhongMaterial:高光phong材质,与光照有反应
  • MeshStandradMaterial:PBR物理材质,可以更好模拟玻璃、金属等效果

6 光照效果

光源类型:

  • AmbientLight:环境光
  • PointLight:点光源
  • DirectionlLight:平行光
  • SpotLight:聚光源

注:如果只使用环境光,整个立方体没有任何棱角感,必须设置具有方向性的点光源和平行光源

7 顶点位置数据解析渲染

//创建顶点数据缓冲区
const geometry= new THREE.BufferGeometry()
//创建顶点坐标
const vertices = new Float32Array([
	0, 0, 0, //顶点1坐标
  	50, 0, 0, //顶点2坐标
  	0, 100, 0, //顶点3坐标
])

const attribute = new THREE.BufferAttribute(vertices,3)
geometry.attributes.position = attribute

const material = new THREE.MeshBasicMaterial({
	color: 0x0000ff,
	side: ThREE.DoubleSide,
})

const mesh = new THREE.Mesh(geometry,material)

8 点模型

const material = new THREE.PointsMaterial({
	color: 0x0000ff,
	size: 10.0,
})
const points = new THREE.Points(geometry,material)

9 线模型

const material = new THREE.LineBasicMaterial({
	color: 0x0000ff,
})
const line = new THREE.Line(geometry,material)

10 顶点颜色数据插值计算

const colors = new Float32Array([
        1, 0, 0, //顶点1颜色
        0, 1, 0, //顶点2颜色
        0, 0, 1, //顶点3颜色

        1, 1, 0, //顶点4颜色
        0, 1, 1, //顶点5颜色
        1, 0, 1, //顶点6颜色
      ]);
geometry.attributes.color = new THREE.BufferAttribute(colors,3)

const material = new THREE.PointsMaterial({
	vertexColor: THREE.VertexColor,
	size: 10.0
})

const points =  new THREE.Points(geometry,material)
scene.add(points)

11 定义顶点法向量

定义顶点法向量后点光源和平行光源会起作用

var normals = new Float32Array([
  0, 0, 1, //顶点1法向量
  0, 0, 1, //顶点2法向量
  0, 0, 1, //顶点3法向量

  0, 1, 0, //顶点4法向量
  0, 1, 0, //顶点5法向量
  0, 1, 0, //顶点6法向量
]);

geometry.attributes.normal = new THREE.BufferAttribute(normals,3)

12 通过顶点索引复用顶点数据

当我们画一个长方形时,需要6个顶点数据,然而其中两个顶点可以复用,因此通过索引来实现复用

const index = new Uint16Array([
	0,1,2,
	0,2,3,
])
geometry.index = new THREE.BufferAttribute(index,1)

13 设置Geometry顶点位置、顶点颜色数据

const geometry = new THREE.Geometry()
const p1 = new THREE.Vector3(50,0,0)
const color1 = new THREE.Color(0x00ff00)
//将顶点数据添加到geometry对象中
geometry.vertices.push(p1)
geometry.colors.push(color1)	//设置顶点颜色属性对Mesh无效

//设置顶点颜色数据时,需要将vertexColor变为THREE.VertexColors
const material = new THREE.MeshLambertMaterial({
	vertexColor: THREE.VertexColors,
	side: DoubleSide,
})

14 Face3定义Geometry的三角形面

设置三角形Face3的颜色对于Mesh模型有效,对于Points、Line无效

var p1 = new THREE.Vector3(0, 0, 0); //顶点1坐标
var p2 = new THREE.Vector3(0, 100, 0); //顶点2坐标
var p3 = new THREE.Vector3(50, 0, 0); //顶点3坐标
var p4 = new THREE.Vector3(0, 0, 100); //顶点4坐标

geometry.vertices.push(p1,p2,p3,p4)

//构建一个三角面
const face1 = new THREE.Face3(0,1,2)
//每个顶点的法向量
var n1 = new THREE.Vector3(0, 0, -1); 
var n2 = new THREE.Vector3(0, 0, -1); 
var n3 = new THREE.Vector3(0, 0, -1); 

face1.vertexNormals.push(n1,n2,n3)

const face2 = new THREE.Face3(0,2,3)
face2.normal = new ThREE.Vector3(0,-1,0)

//设置颜色
face1.color = new THREE.Color(0x00f0f0f)
face1.vertexColors = [
	new THREE.Color(0x00f0f0f),
	new THREE.Color(0x00f0f0f),
	new THREE.Color(0x00f0f0f),
]

geometry.faces.push(face1,face2)

15 访问几何体的数据

BoxGeometryPlaneGeometrySphereGeometry的基类为Geometry

//获取几何体的顶点位置数据
const vertex_position = geometry.vertices
//获取几何体的面数据
const face_data = geometry.faces
//获取几何体的颜色数据
const colors = geometry.colors

BoxBufferGeometryPlaneBufferGeometrySphereBufferGeometry的基类为BufferGeometry

//获取顶点位置
const vertex = geometry.attributes.position
//顶点颜色
const colors = geometry.attributes.color
//顶点法向量
const normal = geometry.attributes.normal
//纹理贴图UV坐标
const uv = geometry.attributes.ub
//顶点索引数据
const index =  geometry.index

16 几何体旋转、缩放、平移

网格模型进行变换不会影响几何体的顶点位置坐标,网格模型旋转缩放平移改变的是模型的本地矩阵、世界矩阵

geometry.scale(2,2,2)
geometry.translate(50,0,0)
geometry.rotateX(Math.PI/4)
geometry.center()

17 常用材质

  • PointsMaterial:点材质
  • LineBasicMaterial:线材质
  • LineDashedMaterial:虚线材质
  • MeshBasicMaterial:基础网格材质,不受带有方向光源影响,没有棱角感
  • MeshLambertMaterial:可以实现网格表面与光源的漫反射光照计算,有棱角感
  • MeshPhongMaterial:高光效果
  • SpriteMaterial:精灵材质

18 材质对应模型对象

  • 点模型:Points
  • 线模型:Line、LineLoop、LineSegments
  • 网格模型:Mesh、SkinnedMesh
  • 精灵模型:Sprite

19 材质共有属性、私有属性

(1)side属性
定义面的渲染方式,可以是前面(THREE.FrontSide)、后面(THREE.BackSide)、双面(THREE.DoubleSide)
(2)材质透明度:opacity、transparent

20 对象克隆和复制

对网格模型的几何体进行缩放时,克隆的网格也会同时改变大小;几何体的克隆或复制为深拷贝

21 光源对象

ThreeJs学习_第1张图片

  • 环境光源AmbientLight:均匀改变整体物体表面的明暗效果
  • 点光源PointLight:同一平面不同区域呈现出不同的明暗效果
  • 平行光DirectionalLight:需要position和target确定光的方向,无论position在哪,平行光的强度一样
  • 聚光源SpotLight:angle设置发散角度,照射方向通过设置position和target实现

漫反射光的颜色=网格模型材质颜色 x 光线颜色 x 光线入射角余弦值

22 光照阴影计算

  • 模型.castShadow属性:设置一个模型对象是否在光照下产生投影效果
  • receiveShadow:设置一个模型对象是否在光照下接收其他模型的投影效果
  • 光源.castShadow属性:光源是否投射动态阴影
  • 光源.shadow:光源阴影对象
  • LightShadow属性.camera:观察光源的相机对象,设置投影的边界属性
  • LightShadow属性.mapSize:较高的值将提供更好的阴影质量,宽高的值必须为2的幂

23 层级模型

scene作为group的父级,group作为mesh1和mesh2的父级,这样对group做的任何操作都会同样作用在mesh1和mesh2上

const group = new THREE.Group()
group.add(mesh1)
group.add(mesh2)
scene.add(group)

//访问子对象
const child = scene.children || group.children

//移除子对象
group.remove(mesh1.mesh2)
  • 命名:group.name = ‘11’
  • 遍历:group.traverse((obj)=>{})
  • 查找:scene.getObjectById()、scene.getObjecctByName()

24 本地位置坐标、世界位置坐标

  • getWorldPosition:获得世界位置坐标
  • getWorldScale:获得世界缩放系数
  • matrix:本地矩阵
  • matrixWorld:世界矩阵

25 常见几何体和曲线

(1)几何体

  • BoxGeometry:长方体
  • CylinderGeometry:圆柱体
  • SphereGeometry:球体
  • ConeGeometry:圆锥、棱锥

(2)曲线

  • LineCurve:直线
  • ArcCurve:圆弧
  • EllipseCurve:椭圆
  • SplineCurve:样条曲线

26 圆弧线

(1)圆弧线

//参数分别为圆心坐标、圆弧半径、起始角度、是否顺时针绘制
const arc = new THREE.ArcCurve(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise)

const points = arc.getPoints(50)	//返回51个顶点

(2)setFromPoints方法
Geometry使用该方法可以把数组points中顶点数据提取出来赋值给几何体的顶点位置属性geometry.vertices,BufferGeometry和Geometry一样具有该方法,不过提取顶点后的数据赋值给geometry.attributes.position属性

const geometry = new THREE.Geometry()
const curve = new THREE.

27 轮廓填充

const points = [
	    new THREE.Vector2(-50, -50),
        new THREE.Vector2(-60, 0),
        new THREE.Vector2(0, 50),
        new THREE.Vector2(60, 0),
        new THREE.Vector2(50, -50),
        new THREE.Vector2(-50, -50),
]

const shape = new THREE.Shape(points)

const geometry = new THREE.ShapeGeometry(shape,20)

//生成外接圆
const shape = new THREE.Shape()
shape.absarc(0,0,100,0,2*Math.PI)
const geometry = new THREE.ShapeGeometry(shape,20)

//

28 二维路径的共有方法

//依靠点生成二维路径
const shape = new THREE.Shape()
const path = new THREE.Path(points)

//移动基点
path.moveTo()
//从currentPosition连线到改点
path.lineTo()
//绘制圆弧
path.arc(x,y,r,startAngle,endAngle,closewise)
//添加到形状的内轮廓中
shape.holes.push(path)

29 拉伸成型

const geometry = new THREE.ExtrudeGeometry(shape,{
	amount: 120,	//拉伸长度
	bevelEnabled: false	//无倒角
})
const material = new THREE.PointsMaterial({
	color: 0x0000ff,
	size: 5.0
})

const mesh = new THREE.Points(geometry,material)

30 扫描成型

扫描效果与拉伸一致,不过不需要设置拉伸距离,设置扫描路径即可

const curve = new THREE.SplineCurve3([
	new THREE.Vector3( -10, -50, -50 ),
   new THREE.Vector3( 10, 0, 0 ),
   new THREE.Vector3( 8, 50, 50 ),
   new THREE.Vector3( -5, 0, 100)
])

const geometry = new THREE.ExtrudeGeometry(shape,{
	bevelEnabled: false,
	extrudePath: curve,	//扫描轨迹
	steps:55//扫描方向细分数

})

31 纹理贴图

将图片作为geometry的贴图,需要设置material的map属性为相应的geometry

const geometry = new THREE.PlaneGeometry(204,102)
//设置纹理对象
const textureLoader = new THREE.TextureLoader()

textureLoader.load('./1.png',(texture)=>{
	const material = new THREE.MeshLambertMaterial({
		map: texture
	})
	const mesh = new THREE.Mesh(geometry,material)
})

也可以使用ImgLoader,内部使用FileLoader来加载文件,并被CubeTextureLoader、ObjectLoader、TextureLoader所使用

const loader = new THREE.ImageLoader()

loader.load('./1.png',(image)=>{
	const texture = new THREE.Texture(image)
	//下次使用纹理时触发更新
	texture.needsUpdate = true
})

32 几何体顶点纹理坐标UV

const geometry = new THREE.BufferGeometry()

const vertices = new Float32Array([
  0, 0, 0, //顶点1坐标
  80, 0, 0, //顶点2坐标
  80, 80, 0, //顶点3坐标
  0, 80, 0, //顶点4坐标
])

//创建缓冲区对象
const attribute = new THREE.BufferAttribute(vertices,3)

geometry.attributes.position = attribute

const normals = new Float32Array([
  0, 0, 1, //顶点1法向量
  0, 0, 1, //顶点2法向量
  0, 0, 1, //顶点3法向量
  0, 0, 1, //顶点4法向量
])

geometry.attributes.normal = new THREE.BufferAttribute(normals,3)

const index  = new Uint16Array([0,1,2,0,2,3])

geometry.index = new THREE.BufferAttribute(index,1)

const uvs = new Float32Array([
	0,0, //图片左下角
   1,0, //图片右下角
   1,1, //图片右上角
   0,1, //图片左上角
])

geometry.attributes,uv = new THREE.BufferAttribute(uvs,2)

33 数组材质、材质索引

(1)数组材质

const material_1 = new THREE.MeshPhongMaterial({
	color: 0xff0000
})
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.loader('./1.png')

const material_2 = new THREE.MeshLambertMaterial({
	map: texture
})

const materialArr = [material_2,material_1,material_1,material_1,material_1,material_2]
const mesh = new THREE.Mesh(geometry,materialArr)
scene.add(mesh)

(2)材质索引属性

geometry.faces[1].materialIndex = 1

34 纹理对象Texture阵列、偏移、旋转

(1)阵列

  • 默认:ClampToEdgeWrapping
  • 阵列:RepeatWrapping
  • 镜像阵列:MirrorRepeatWrapping

wrapS:纹理贴图在水平方向上将如何包裹
wrapT:纹理贴图在垂直方向上将如何包裹

texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.set(4,2)

(2)偏移
相对于原来位置进行偏移

texture.offset = new THREE.Vector2(0.5,0.5)

(3)旋转

texture.rotation = Math.PI/4
texture.center.set(0.5,0.5)

35 法线贴图

const textureLoader = new THREE.TextureLoader()
const textureNormal = textureLoader.load('./1.png')
const material = new THREE.MeshPhongMaterial({
	color: 0x0000ff,
	normalMap: textureNormal,
	normalScale: new THREE.Vector2(3,3)
})

36 凹凸贴图

设置material的bumpMap属性为纹理贴图,bumpScale为凹凸的高度

37 高光贴图

const material = new THREE.MeshPhongMaterial({
	shininess: 30
	map: texture,
	specular: textureSpecular,	//高光贴图
})

38 环境贴图

类似于租房的VR效果

const geometry = new THREE.BoxGrometry(100,100,100)

const loader = new THREE.CubeTextureLoader()

loader.setPath('./')

const cubeTexture = loader.load(['1.jpg','1.jpg','1.jpg','1.jpg','1.jpg','1.jpg'])

const material = new THREE.MeshPhongMaterial({
	envMap: cubeTexture
})

39 正射投影和透视投影

ThreeJs学习_第2张图片
(1)正射投影相机对象OrthographicCamera

ThreeJs学习_第3张图片

  • left:左边界
  • right:右边界
  • top
  • bottom
  • near
  • far
    注意:左右边界的距离与上下边界距离的比值要和画布渲染窗口比例一直,否则三维模型显示效果会被单方向不等比例拉伸

(2)透视投影相机对象PerspectiveCamera
ThreeJs学习_第4张图片

  • fov:视角角度
  • aspect:宽高比
  • near:近裁剪面
  • far:远裁剪面

(3)相机位置和拍摄方向

camera.position.set()
camera.lookAt(scene.position)

40 浏览器窗口尺寸变化(自适应渲染)

如果浏览器窗口尺寸发生变化,会出现局部空白区域

//相当于设置视图矩阵的matrixWorldInverse属性
camera.position.set()
camera.lookAt()

//相当于设置投影矩阵的projectionMatrix属性
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);

(1)正射投影相机自适应渲染
需要重新设置相机对象和渲染对象参数

window.onresize = ()=>{
	renderer.setSize(window.innerWidth,window.innerHeight)
	k = window.innerWidth/window.innerHeight
	camera.left = -s*k
	camera.right = s*k
	camera.top = s
	camera.bottom = -s
	//需要手动更新,这是用为每次执行渲染器方法render的时候不会读取相机相关参数重新计算一次投影矩阵
	//如果相机的一些属性发生了变化,需要执行updateProjectMatrix方法更新相机的投影矩阵
	camera.updateProjectionMatrix()
}

(2)透视相机自适应渲染

window.onresize = ()=>{
	renderer.setSize(window.innerWidth,window.innerHeight)
	camera.aspect =  window.innerWidth/window.innerHeight
	camera.updateProjectionMatrix()
}

你可能感兴趣的:(webgl,学习)