第一天
学习了Three.js的相机,材质,灯光,可视区域,几何体的基础知识级应用。
可视锥形区域
理解为第一个面板到第二个面板之间的距离为可视距离超出则会被裁剪不显示,再次出现在可视可视区域才可以才看,代入到现实中,当人站立正对着一面墙,人眼到墙的距离为可视距离
// 使用透视相机
// PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
// fov — 摄像机视锥体垂直视野角度
// aspect — 摄像机视锥体长宽比
// near — 摄像机视锥体近端面 人眼
// far — 摄像机视锥体远端面 远处墙面
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 3000);
材质
基础网格材质
这种材质不受光源影响,不会随着环境光或光源影响
Lambert网格材质
这种材质受光源影响,但没有镜面反射效果
Phong网格材质
这种材质受光源影响,有镜面反射效果
光源
点光源
点光源类似现实中灯泡,会根据设置不同的光照强度和光照衰减呈现不同的光照反应
// 创建光源(点光源)
const Pointerlight = new THREE.PointLight( 0xffffff,1.0 );
Pointerlight.intensity = 1.0; // 光照强度
Pointerlight.decay = 0.0; // 衰减距离
Pointerlight.position.set( 0, 200, 200 );
平行光
光照方向是平行的,距离无限远
const Directionallight = new THREE.DirectionalLight( 0xffffff,1.0 );
Directionallight.position.set( 0, 200, 200 );
环境光
环境光会均匀的照亮场景中的所有物体
const Ambientlight = new THREE.AmbientLight( 0x404040 ,1.0);
光照辅助
点光源,平行光,会生成一个光照起点几何体
几何体
Three.js 中内置许多的几何体,立方体,锥形,圆形等,都可以根据不同的参数呈现出不同几何体的效果,
单面几何体 只可以看到正面,three.js 会根据绘制的顺序的不同来决定正反面,顺时针绘制为反面,设置参数side:THREE.DoubleSide可以实现双面
渲染器
WebGLRenderer
WebGPURenderer
控制器
实现不同角度查看几何体
GUI/Stats
在官方文档示例中看到的帧数显示和参数控制都可以使用GUI/Stats库来实现
使用方法
const stats = new Stats();
document.body.appendChild(stats.dom);
const gui = new GUI();
const obj = {
color: 0xff0000,
shininess:30, // 高光部分的亮度,默认为30
specular:0xffffff,
x:0,y:0,z:0,
}
const matFolder = gui.addFolder('材质');
const position = gui.addFolder('位置');
// 设置收起
matFolder.close();
position.close();
matFolder.addColor(obj, 'color').onChange(function(value) {
material.color.set(value);
}).name('颜色');
matFolder.add(obj, 'shininess', 0, 100).onChange(function(value) {
material.shininess = value;
}).name('高光亮度');
// 第三个参数为数组时GUI会呈现下拉框
position.add(obj, 'x',[0,100,500,1000]).onChange(function(value) {
cube.position.x = value;
}).name('x轴').step(100);
position.add(obj, 'y',{
'center':0,
'top':100,
'bottom':-100,
}).onChange(function(value) {
cube.position.y = value;
}).name('y轴').step(100);
GUI add方法默认根据第二个参数为GUI的name的显示
利用requestAnimationFrame实时更新物体
网页宽高变化
window.onresize = function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
第二天
点绘制
一点的位置三个数据为一组(x,y,z),设置模型的attributes.postion 进行绘制
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
-100.0, -100.0, -100.0,
100.0, -100.0, -100.0,
100.0, 100.0, -100.0,
-100.0, 100.0, -100.0,
-100.0, -100.0, 100.0,
100.0, -100.0, 100.0,
100.0, 100.0, 100.0,
-100.0, 100.0, 100.0
]);
const attribue = new THREE.BufferAttribute(vertices,3);
geometry.attributes.position = attribue;
const mesh = new THREE.Points(geometry, new THREE.PointsMaterial({color:0xff0000,size:100}));
scene.add(mesh);
线绘制
我忘记了,不想看之前代码了,用时看文档
自定义绘制几何体
- 和点绘制基本一致,用的材质不一样,也分正反面
- 优化渲染可以使用顶点数据
- 使用反射材质需要设置法线朝面才可以看到
- 使用贴图不需要设置法线朝向
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
0,0,0,
100,0,0,
100,100,0,
0,100,0
]);
const indexs = new Uint16Array([
0,1,2,
0,2,3
]);
// 法线(用于光反射)
// x,y,z方向
const normals = new Float32Array([
0,0,1,
0,0,1,
0,0,1,
0,0,1
]);
geometry.index = new THREE.BufferAttribute(indexs,1);
const attribute = new THREE.BufferAttribute(vertices,3);
geometry.attributes.position = attribute;
// 法线,否则会看到面片没有被渲染
geometry.attributes.normal = new THREE.BufferAttribute(normals,3);
const mesh = new THREE.Mesh(geometry,new THREE.MeshLambertMaterial({
color:0xff0000,
}));
scene.add(mesh);
第三天
三维向量(Vector3)
有序的参数(x,y,z)需要的参数都需要三维向量,使用getWorldPosition等等方法参数都要求是三维定量,主要看文档参数类型
欧拉(Euler)
屌用太小先不记它
组
创建一个组可以将模型都添加一个组中然后添加到场景中,方便控制组里每个模型
坐标
坐标就是postion
自身坐标 = 自身position
世界坐标 = 自身坐标 + 父级坐标 + 父级的父级坐标 ....
贴图
注意看文档
uv坐标
uv坐标在正方形中分为四个点,为逆时针,可以用来裁切雪碧图
- 左下
- 右下
- 右上
- 坐上
好了三天就学这么一点,ok,√