3d旋转相册代码源码_WebGL实现3d渲染

53d4466b4f171b3425940418ab6377ab.png

WebGL(Web图形库)是一个JavaScript API,可在任何兼容的Web浏览器中渲染高性能的交互式3D和2D图形,而无需使用插件。WebGL通过引入一个与OpenGL ES 2.0非常一致的API来做到这一点,该API可以在HTML5<canvas>元素中使用。 这种一致性使API可以利用用户设备提供的硬件图形加速。

WebGL本身相对比较繁琐,但一些优秀的js库简化了该流程,列如Three.js。随着5G的普及、从2维演变3维的展示必将成为趋势。

本文利用Three.js将一个桌子上面的电脑包装盒实现6个面的3d展示

a6d6648c63e47ab5d458bf5a10b1efb4.png

场景——相机——渲染器:立方体网格模型和光照组成了一个虚拟的三维场景,相机对象就像你生活中使用的相机一样可以拍照,只不过一个是拍摄真实的景物,一个是拍摄虚拟的景物,拍摄一个物体的时候相机的位置和角度需要设置,虚拟的相机还需要设置投影方式,当你创建好一个三维场景,相机也设置好,就差一个动作“咔”,通过渲染器就可以执行拍照动作。

9556ac80f098814dd230ad679ab17150.png

创建场景Scene

THREE.Scene 对象是所有不同对象的容器,也就是说该对象保存所有物体、光源、摄像机以及渲染所需的其他对象。

let scene = new THREE.Scene();

创建几何体Geometry

e9815a126e39b9cda6cdeaa7202c58b7.png

WebGL坐标系为上图所示

//创建一个立方体几何对象Geometry
let geometry = new THREE.BoxGeometry(3, 1.8, 0.8);//x、y、z

代码var box=new THREE.BoxGeometry(3, 1.8, 0.8);通过构造函数THREE.BoxGeometry()创建了一个长宽高都是100的立方体,通过构造函数名字BoxGeometry也能猜出这个构造函数的意义,利用new关键字操作构造函数可以创建一个对象, 这都是Javascript语言的基本知识,至于THREE.BoxGeometry()构造函数具体是什么可以不用关心,刷新浏览器查看数据更改后长方体的效果图,如果x,y,z相同为正方体,默认也是正方体。

题外如果需要渲染出来一个球体效果用SphereGeometry:

//创建一个球体几何对象
let geometry = new THREE.SphereGeometry();

创建材质Material:

let material=new THREE.MeshBasicMaterial({color:0xcccccc});

通过构造函数THREE.MeshLambertMaterial()创建了一个可以用于立方体的材质对象, 构造函数的参数是一个对象,对象包含了颜色、透明度等属性,本案例中只定义了颜色color,颜色属性值,这里使用的颜色值表示方法是16进制RGB三原色模型。

创建网格模型Mesh并加入场景Scene:

 let cube = new THREE.Mesh( geometry, material)//网格模型对象mesh
 scene.add( cube );网格模型添加到场景中

该例子暂不考虑光照;

创建相机Camera:

相机分为PerspectiveCamera(透视摄像机)或者OrthographicCamera(正交摄像机)两大类。

使用透视投影照相机获得的结果是类似人眼在真实世界中看到的有“近大远小”的效果(如下图中的(a));而使用正交投影照相机获得的结果就像我们在数学几何学课上老师教我们画的效果,对于在三维空间内平行的线,投影到二维空间中也一定是平行的(如下图中的(b))。

e436a32e3c0542b07baa76495f591112.png
let camera = new THREE.PerspectiveCamera( 40, window.innerWidth/window.innerHeight, 
0.1, 1000 );
camera.position.z = 5;

在这里,我们使用的是PerspectiveCamera(透视摄像机)。

第一个值是摄像机视锥体垂直视野角度 fov,从视图的底部到顶部,以角度来表示。默认值是50。

第二个值是摄像机视锥体的长宽比aspec,通常是使用画布的宽/画布的高。这样不会被感觉被压缩。默认值是1

接下来的两个值近端面距离near和远端面距离far 。摄像机的远端面,默认值是2000。摄像机的近端面,默认值是0.1。 也就是说当物体所在的位置比摄像机的远端面远或者所在位置比近端面近的时候,该物体超出的部分将不会被渲染到场景中。

816afba0fbfdbf7218831066c5f70ef9.png

camera.position为相机的位置

创建渲染器Renderer:

let renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.render( scene, camera );

创建一个WebGLRenderer,设置其区域宽高,得到domElement是一个canvas,将该canvas节点append到body子元素中;如果dom已有canvas元素可以在new THREE.WebGLRenderer构造时候传入{canvas:'已有domElement'};

renderer时候传入场景实例scene,和相机实例camera

˙这个时候看到如下图

c98570aa01fa9eb31aee186fc6634dc3.png

完全没有立体感,因为此时看到的只是正面,其他面被正面遮挡了,此时需要旋转一下角度

 cube.rotation.x =Math.PI/6;
 renderer.render( scene, camera );
 let animate = function () {
    requestAnimationFrame( animate );
    cube.rotation.y += 0.01;
    renderer.render( scene, camera );
 };
 animate();

立方体网格模型绕立方体的x轴旋转π/6,一周为2π。这样就可以看到顶面,绕立方体的y轴按帧进行旋转,当然可以监听mouse和touch相关事情进行滚滑控制旋转。

4f531fbb94ea788fd5c958743ec49d3c.png

将材质Material的color换成base64的图片,此图片需注意跨域问题。

 let materials=[];
 let skinArr=[base64Left,base64Left,base64Top,base64Top,base64,base64];左、右、顶、底、正、反
 for(let skinKey in skinArr){
   let texture=THREE.ImageUtils.loadTexture(skinArr[skinKey])
   materials.push(new THREE.MeshBasicMaterial( { map:texture}))
 }

duang duang duang ~ 大功告成

5f78093cfb8763baa115641cd5c16b7a.png

附:Three.js炫酷demo

Car Visualizer​carvisualizer.plus360degrees.com
961e38af20b76f44feb967a7c185cb52.png
Three.js心脏在线预览​www.yanhuangxueyuan.com

源码地址:

cheneywang/demo​github.com
07fa20445b8c2ccf1ef3c88acfc50bc0.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值