
Three.js是一款基于原生WebGL的三维引擎框架(库),该框架在WebGL的API基础上以简单、直观的方式封装了三维图形的常用对象,因此大大减少了程序员在Web前端开发三维图形应用的工作量,Three.js还使用了很多图形引擎的高级技巧,极大地提高了应用性能。
随着WebGL技术和5G技术的持续推广,各种产品的在线三维展示将会变得越来越普遍,对于现在比较火爆的VR产品、AR产品,对WebGL技术的推广,也是一个好消息。VR与Web3D技术的结合自然就衍生出一个新的概念WebVR,也就是基于Web实现的VR内容,即通过三维照相机对室内空间进行拍摄,即可在Web端以全景图的方式预览室内效果。Three.js对此也进行了封装。
本文下面实例分别演示了绘制PointLight光源的辅助线和光线阴影。
绘制PointLight光源的辅助线

■ 图1
<body><div id="myContainer" ></div>
<script>
//创建渲染器
var myRenderer= new THREE.WebGLRenderer({antialias: true });
myRenderer.setSize(window.innerWidth, window.innerHeight);
$("#myContainer").append(myRenderer.domElement);
var myScene = new THREE.Scene();
myScene.background = new THREE.Color('white');
var myCamera = new THREE.PerspectiveCamera(75,
window.innerWidth window.innerHeight, 0.1, 1000);
myCamera.position.set(160.51,158.71,127.6);
myCamera.lookAt(new THREE.Vector3(0, 0, 0));
myCamera.updateProjectionMatrix();
//创建并添加THREE.PointLight光源
var myPointLight=new THREE.PointLight('lightgreen');
myPointLight.position.set(0,100,100);
myScene.add(myPointLight);
//绘制THREE.PointLight光源辅助线
var myPointLightHelper=new THREE.PointLightHelper(myPointLight,50,'green');
myScene.add(myPointLightHelper);
//创建立方体
var myBoxGeometry = new THREE.BoxGeometry(50,50,50);
var myMap = THREE.ImageUtils.loadTexture("images/img002.jpg");
var myMaterial = new THREE.MeshPhongMaterial({map: myMap});
var myMesh = new THREE.Mesh(myBoxGeometry, myMaterial);
myMesh.translateX(100);
myScene.add(myMesh);
//渲染立方体
animate();
function animate() {
requestAnimationFrame(animate);
myMesh.rotation.x += 0.01;
myMesh.rotation.y += 0.01;
myMesh.rotation.z += 0.01;
myRenderer.render(myScene, myCamera);
};
</script></body>
在上面这段代码中,myPointLightHelper=new THREE.PointLightHelper(myPointLight, 50,'green')语句表示根据myPointLight光源绘制指定尺寸(50)和指定颜色(green)的光源线框。THREE.PointLightHelper()方法的语法格式如下:
THREE.PointLightHelper(light,sphereSize,color)

绘制PointLight光源的光线阴影

■ 图2
■ 图3
<body><div id="myContainer" ></div>
<script>
//创建渲染器
var myRenderer =new THREE.WebGLRenderer({antialias: true});
myRenderer.setSize(window.innerWidth, window.innerHeight);
myRenderer.shadowMap.enabled = true;
$("#myContainer").append(myRenderer.domElement);
var myScene = new THREE.Scene();
var myCamera = new THREE.PerspectiveCamera(45,
window.innerWidth/window.innerHeight, 0.1, 100);
myCamera.position.x = -30;
myCamera.position.y = 40;
myCamera.position.z = 40;
myCamera.lookAt(myScene.position);
myScene.add(myCamera);
//创建THREE.PointLight光源
var myPointLight = new THREE.PointLight(0xffffff);
myPointLight.castShadow = true;
myPointLight.shadow.mapSize.set(2048, 2048);
myPointLight.decay = 0.1
myScene.add(myPointLight);
//添加光源图形(被圆球代替)
var myPointLightHelper = new THREE.PointLightHelper(myPointLight);
//var myPointLightHelper=new THREE.PointLightHelper(myPointLight,5,'green');
myScene.add(myPointLightHelper);
//绘制(拍摄)光线阴影
var myCameraHelper = new THREE.CameraHelper(myPointLight.shadow.camera)
myScene.add(myCameraHelper)
myScene.add(new THREE.AmbientLight(0x353535, 1));
//创建圆球模拟光源
var mySphereLight = new THREE.SphereGeometry(3,40,40);
var mySphereLightMaterial = new THREE.MeshBasicMaterial({color: 0xffff00});
var mySphereLightMesh = new THREE.Mesh(mySphereLight, mySphereLightMaterial);
mySphereLightMesh.position.set(0, 8, 2);
myScene.add(mySphereLightMesh);
//创建接收阴影的平面
var myPlaneGeomerty = new THREE.PlaneGeometry(60,40,1, 1);
var myPlaneMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
var myPlaneMesh = new THREE.Mesh(myPlaneGeomerty, myPlaneMaterial);
myPlaneMesh.rotation.x = -0.5 * Math.PI;
myPlaneMesh.receiveShadow = true;
myScene.add(myPlaneMesh);
//创建立方体
var myBoxGeometry = new THREE.BoxGeometry(6,6,6);
var myBoxMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff });
var myBoxMesh = new THREE.Mesh(myBoxGeometry, myBoxMaterial);
myBoxMesh.castShadow = true;
myBoxMesh.position.x = 2;
myBoxMesh.position.y = 2;
myBoxMesh.position.z = 2;
myScene.add(myBoxMesh);
//渲染所有图形
var step = 0;
animate();
function animate(){
myPointLightHelper.update();
myCameraHelper.update();
step += 0.01;
mySphereLightMesh.position.x = 20 + (10 * Math.cos(step));
mySphereLightMesh.position.y = 12 + (10* Math.abs(Math.sin(step)));
mySphereLightMesh.translateX(-22);
//使用圆球的位置作为光源位置
myPointLight.position.copy(mySphereLightMesh.position);
requestAnimationFrame(animate);
myRenderer.render(myScene, myCamera);
}
</script></body>
该实例源文件下载二维码为:

补充说明
本系列所有Three.js代码(版本号r119)在IntelliJ IDEA环境编写完成,在最新版的Firefox浏览器或Google Chrome浏览器测试成功。因此建议读者在上述环境或条件下使用源代码。所有源代码不需要下载Three.js的其他文件,在使用时保持网络畅通即可。此外需要注意:Three.js版本更新较快,因此在开发应用本书的源代码时特别需要注意版本问题。
参考书籍
《Three.js前端三维图形开发案例集锦》
ISBN:978-7-302-58956-3
罗帅 罗斌 编著
定价:128.00元


扫码优惠购书











