前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]写在前面先说好,今天所说的3D并不是大家惯性思维说3D就想到了WebGL,那么接下来的文章都是基于Canvas2d来模拟3D空间~那么要模拟3维

欢迎来到【畅哥聊技术】前端图形学相关技术文章,更多精彩内容持续更新中,敬请关注。

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

写在前面

先说好,今天所说的3D并不是大家惯性思维说3D就想到了WebGL,那么接下来的文章都是基于Canvas2d来模拟3D空间~

那么要模拟3维世界,那么我们不得不提到一个新的名词:第三维度~

第三维度

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

这个不难理解,我们在Canvas2d中有两个坐标轴,X,Y,那么要模拟3D效果,那么我们就得抽象一个Z 轴出来 ,如上图,这个Z轴是垂直于我们的屏幕。

我们接下来规定,Z轴的正方向是向垂直屏幕向里为,相反则为负方向。

透视图

什么是透视图?一句话概括:近大远小!!!

物体远离视线,那么就会越来越小,直到消失在屏幕上,消失的时候的那一个点我们称之为 消失点

那么怎么在2维空间去模拟3D世界的呢?也就是说我们要把3空间的坐标转换到2d屏幕上来。

原理:

  1. 放大或缩小物体
  2. 让它靠近或者远离消失点
前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

透视图公式如上图

scale = f1 / (f1 + z)

其中f1可以理解为我们的眼睛距离屏幕的距离

z为物体离屏幕的距离。

怎么理解这个公式呢?再来看张图:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

假如我们的Z轴为0,小球此时应该在(400,300)的位置,这时候,我们刚好可以看到小球的全部。scale = 200 / (200+0) = 1;

此时,如果我们把小球向Z轴的正方向移动200的时候,那么此时的scale = 200 / (200 + 200) = 0.5; 也就是说,小球的scaleX和scaleY都将变成.5 ,还有小球的xy坐标也将是之前的一半~从图中可以看出来,移动后的小球的坐标是(200,150)

有了上面的基础,接下我们的示例就好展开了。请看~

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

效果分析:

  • 默认情况下,小球Z轴为0,那么可正常随着鼠标移动
  • 注册键盘事件,按下上方向键的时候,我们不断的放大Z值,那么小球对应的缩小,按方向下键的时候,Z值不断缩小 ,小球变大
  • 当鼠标Z轴不断增大,再去移动鼠标,发现小球和鼠标之间就形成了视差的效果了。

实现过程:

  1. 定义x,yz,默认分别为0,f1 = 200以及消失点坐标(width>>1,height>>1)
  2. 实例化小球。
  3. 注册鼠标事件和键盘事件,并且在键盘事件中处理Z轴的大小来控制小球的位置。

核心代码:

let x =0,y = 0,z = 0;

var hideX = width >> 1,

hideY = height >> 1;

var f1 = 200;

var mouse = {x:0,y:0}

window.addEventListener(‘keydown’,e=>{

if(e.keyCode === 38){

z+=5;

}

if(e.keyCode === 40){

z -=5;

}

});

canvas.onmousemove = e =>{

mouse.x = e.pageX – canvas.offsetLeft;

mouse.y = e.pageY – canvas.offsetTop;

}

在事件循环函数中不停的去计算当前缩放比例scale,将三维坐标映射到二维画布上。

//因为f1+z作了除数,这里记得要作下判断
if(f1+z>0){
	var scale = f1 / (f1 + z);
	
	ball.scaleX = ball.scaleY = scale;
	x = mouse.x - hideX;
	y = mouse.y - hideY;
	ball.x = hideX + x * scale;
	ball.y = hideY + y * scale;
	ball.render(context);
}
//将缩放比例分别作用在x.y和缩放小球的属性上~

完整代码:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

应用

示例:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

在实现这个示例之前,我们还需要对小球类进行一次改造才行。我们依次给小球添加3个属性

小球在3维空间的中xyz坐标
this.x3d = 0;
this.y3d = 0;
this.z3d = 0;
//小球z轴的速度
this.vz = 0;

接下来我们依然采用了之前的老套路,随机生成200个小球,给他们随机的x和z的位置,y3d为同一值,因为这些小球在同一点落下。

为了更加符合视觉感观,小球的Z轴越大,我们应该要优先绘制,这时候,我们就要对小球依据z3d来进行排序了。

balls.sort((a,b)=>{//这
		return b.z3d - a.z3d;
})

循环函数中不断的计算scale值,这是核心;

var scale = f1 / (f1 + ball.z3d);

核心代码截图:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

完整代码请私信我

总结:

小球在三维空间的中缩放比例的计算公式为:

var scale = f1 / (f1 + z);

其中f1为景深,z为小球的z轴大小。

三维空间的坐标如何映射为2维平面上

ball.x = hideX + x * scale;
ball.y = hideY + y * scale;

最后就是一些之前的物理公式的运用了。

以上是今天所有的分享内容。喜欢的请点赞关注,不喜欢的解散~~

这里是【畅哥聊技术】前端图形学相关技术文章,更多精彩内容持续更新中。。。

未完待续。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/12006.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注