3d
# 3d
# 1.优秀3d效果
# 2.simple-noise
问题1:simple-noise是什么?
- simplex-noise.js 是 Javascript 中的一种快速的单纯形噪声实现。它可以在浏览器和 nodejs 上运行。
- 一般需要配合canvas实现随机动画,如波浪翻滚,随机背景粒子变化等
问题2:simple-noise如何使用?
- 法1:直接引入,地址:simple-noise.js (opens new window)
- 法2:下载npm包,npm i simple-noise -s,生产环境需要用到
- canvas的引入和使用
// 创建canvas并获取绘制
<canvas id="canvas"></canvas>
this.canvas = document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
this.w = window.innerWidth;
this.h = window.innerHeight;
this.canvas.width = this.w;
this.canvas.height = this.h;
this.count = 80;
// 循环绘制图像
loop() {
var This = this;
function drawloop(){
window.requestAnimationFrame(drawloop);
This.ctx.clearRect(0,0,This.w,This.h);
This.speedX = 0;
// This.speedY += 0.001; //每次渲染需要更新波峰波谷值
This.speedY += 0.001; //每次渲染需要更新波峰波谷值
//连续绘制三次波浪线
This.draw('rgba(239,119,87,0.35)',-100);
This.draw('rgba(239,119,87,0.3)',20);
This.draw('rgba(239,119,87,0.2)',60);
This.draw('rgba(239,119,87,0.15)',100);
This.draw('rgba(239,119,87,0.1)',140);
}
drawloop();
}
draw(color,index) {
var amp = 100; //波浪幅度 可以通过函数传递参数更改不同的幅度
this.ctx.beginPath();
for(var i=0;i<=this.count;i++){
this.speedX += 0.05;
var x = i*(this.w/this.count);
var y = this.h/3.5 + this.simplex.noise2D(this.speedX,this.speedY)*amp + index;
this.ctx[i === 0 ? 'moveTo' : 'lineTo'](x,y);
// console.log(this.simplex.noise2D(this.speedX,this.speedY)*100)
}
this.ctx.lineTo(this.w,-this.h);
this.ctx.lineTo(0, -this.h);
this.ctx.closePath();
this.ctx.fillStyle = color;
this.ctx.fill();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
- simplex-noise的引入和使用
// 引入simplex-noise
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.3.0/simplex-noise.min.js"></script>
// 定义simplex-noise
this.simplex = new SimplexNoise();
// 使用simplex-noise,使用noise2D
var y = this.h/3.5 + this.simplex.noise2D(this.speedX,this.speedY)*amp + index;
1
2
3
4
5
6
2
3
4
5
6
问题3:simplex-noise如何在里面画波浪的?
- 通过遍历,形成曲线,速度由0,遍历80次,每次增加0.05,增加到4。
- x轴为每次的数据n,乘以视口宽度1920除以遍历总数80,x最大为视口宽度
- y轴为视口高度1080除以3.5,加上noise2D的x和y轴速度移动的波峰和波谷值,乘以100,波浪幅度,加上index起始偏移
- y类似于asin(x) + b
- 图像上的自然曲线是noise 生成的,随机生成,用到一种叫
Berlin Noise
的算法,Berlin Noise 是一个非常强大的算法,常用于生成随机内容
问题4:simplex-noise如何画粒子系统的?
# 3.3d max常用快捷键
- 顶视图:T
- 底势图:B
- 前视图:F
- 左视图:L
- 右视图:R
- 透视图:P
- 移动视图:鼠标中键
- 旋转视图:alt + 鼠标中键
- 缩放视图:ctrl + alt + 鼠标中键
- 视图切换:alt + w
# 4.常见keycode
- 前—w—87—上38,up
- 后—s—83—下40,down
- 左—a—65—左37,left
- 右—d—68—右,39,right
# 5.执法人员在道路上来回巡逻的动画,如何实现的?
- 参考案例代码地址:https://github.com/tweenjs/tween.js/blob/master/examples/00_hello_world.html
- to(点坐标,时间/毫秒)—多少毫秒内移动到点坐标位置
- start()—启动动画
- chain() —链式补间—上一个补间结束,立即启动另一个补间动画
- 无线来回核心代码—ween_zfr.chain(tween_zfr_back); tween_zfr_back.chain(tween_zfr);
# 6.环卫工人在道路上环圈打扫的动画,如何实现的?
- 起始和结束的点位相同,形成闭环
# 7.模型进行场景漫游,点击屏幕位置,模型走到该位置,我是如何实现的?
- 引入tween,
- 创建光线投影
var raycaster = new THREE.Raycaster();//光线投射,用于确定鼠标点击位置
1
- mousedown触发,点击屏幕坐标,二维转3d坐标三维
window.addEventListener("mousedown",mousedown);//页面绑定鼠标点击事件
mouse.x = e.clientX / renderer.domElement.clientWidth*2-1;
mouse.y = -(e.clientY / renderer.domElement.clientHeight*2)+1;
//以camera为z坐标,确定所点击物体的3D空间位置
raycaster.setFromCamera(mouse,camera);
1
2
3
4
5
2
3
4
5
- 获取点击的点,起始点位
//确定所点击位置上的物体数量
var intersects = raycaster.intersectObjects(scene.children);
//选中后进行的操作
if(intersects.length) {
// 获取点击的点位
// 起始点位
let points = intersects[0].point
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 获取加载的模型
// 获取场景中机器人模型
let rootModel = scene.children[5]
1
2
2
- 创建及开启动画
// 创建动画
var tween = new TWEEN.Tween(rootModel.position);
// 运动到选择的位置
tween.to({ x: points.point.x, y: points.point.y, z: points.point.z }, 10000).start()
.onComplete(()=> {
tween.stop() // 停止
rootModel.position.x = points.point.x
rootModel.position.y = points.point.y
rootModel.position.z = points.point.z
// 在加入的机器人模型中找到Running动画,将其停止
// 结束,使用Idle动画
// const animationClip2 = rootModel.animations.find(animationClip => animationClip.name === "Idle");
// console.log(rootModel, animationClip2, 'animationClip222')
// const action3 = animationMixer.clipAction(animationClip2);
// // 播放Idle动画
// action3.pause()
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
扩展:如何实现模型走动有跑起来动画,停止时处于停止动画的?
- 创建模型动画
// 动画
var animationMixer = new THREE.AnimationMixer(scene);
1
2
2
- 找到所有播放的动画事件
// 起始,使用Idle动画,Running
const animationClip = obj.animations.find(animationClip => animationClip.name === "Running");
1
2
2
- 播放绑定动画,进行播放
const action2 = animationMixer.clipAction(animationClip);
// 1.0倍速度播放
action2.timeScale = 7.5//24帧每秒变为30帧每秒,要慢放为0.8倍,做动画要做30帧/s的
//调用播放器的播放事件
action2.play();
1
2
3
4
5
2
3
4
5
# 8.模型贴合问题?
- fbx的模型贴合问题?--obj.children[0].material[i].depthWrite = false
- glb模型贴合问题?--glb.scene.children[0].children[2].children[i].material.depthWrite = false