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展示
场景——相机——渲染器:立方体网格模型和光照组成了一个虚拟的三维场景,相机对象就像你生活中使用的相机一样可以拍照,只不过一个是拍摄真实的景物,一个是拍摄虚拟的景物,拍摄一个物体的时候相机的位置和角度需要设置,虚拟的相机还需要设置投影方式,当你创建好一个三维场景,相机也设置好,就差一个动作“咔”,通过渲染器就可以执行拍照动作。
创建场景Scene
THREE.Scene 对象是所有不同对象的容器,也就是说该对象保存所有物体、光源、摄像机以及渲染所需的其他对象。
let scene = new THREE.Scene();
创建几何体Geometry
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))。
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。 也就是说当物体所在的位置比摄像机的远端面远或者所在位置比近端面近的时候,该物体超出的部分将不会被渲染到场景中。
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
˙这个时候看到如下图
完全没有立体感,因为此时看到的只是正面,其他面被正面遮挡了,此时需要旋转一下角度
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相关事情进行滚滑控制旋转。
将材质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 ~ 大功告成
附:Three.js炫酷demo
Car Visualizercarvisualizer.plus360degrees.com源码地址:
cheneywang/demogithub.com