暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

带你入门Three.js|绘制DirectionalLight光源产生的阴影

710

Three.js是一款基于原生WebGL的三维引擎框架(库),该框架在WebGL的API基础上以简单、直观的方式封装了三维图形的常用对象,因此大大减少了程序员在Web前端开发三维图形应用的工作量,Three.js还使用了很多图形引擎的高级技巧,极大地提高了应用性能。

随着WebGL技术和5G技术的持续推广,各种产品的在线三维展示将会变得越来越普遍,对于现在比较火爆的VR产品、AR产品,对WebGL技术的推广,也是一个好消息。VR与Web3D技术的结合自然就衍生出一个新的概念WebVR,也就是基于Web实现的VR内容,即通过三维照相机对室内空间进行拍摄,即可在Web端以全景图的方式预览室内效果。Three.js对此也进行了封装。

本文下面实例分别演示了绘制和模糊DirectionalLight光源产生的阴影


01

绘制DirectionalLight光源产生的阴影


此实例主要通过设置渲染器、三维图形、光源、投射平面等与阴影相关的属性为true,实现在场景中绘制使用THREE.DirectionalLight光源照射球体产生的阴影。THREE. DirectionalLight可以看作模拟太阳发出的光源,这个光源所发出的光都是相互平行的,因此也称为平行光;它不像THREE.SpotLight光源和THREE.PointLight光源那样距离物体越远,光的强度就越弱,THREE.DirectionalLight所发射出来的光,所照射的整个区域内光的强度都是一样的。当浏览器显示页面时,将在网格状的球体下面显示一个黑色的网格阴影,如图1所示。

■ 图1


主要代码如下:
<body><div id="myContainer" ></div>
<script>
 //创建渲染器
 var myRenderer = new THREE.WebGLRenderer();
 myRenderer.setPixelRatio( window.devicePixelRatio );
 myRenderer.setSize(480,320);
 myRenderer.setClearColor('white', 1);
 //设置为true才能看到阴影
 myRenderer.shadowMap.enabled = true;
 $("#myContainer").append(myRenderer.domElement);
 var myScene = new THREE.Scene();
 var myCamera=new THREE.PerspectiveCamera(45,480/320, 0.1, 1000);
 myCamera.position.set(4, 4, 2);
 myCamera.position.multiplyScalar(2);
 myCamera.lookAt(new THREE.Vector3(0, 0, 0));
 //创建DirectionalLight光源
 var myLight = new THREE.DirectionalLight('white', 1 );
 //设置为true才能看到阴影
 myLight.castShadow = true;
 myLight.position.set( 0, 14, 0 );
 myScene.add( myLight );
 //创建用于投射阴影的球体
 var mySphereGeometry=new THREE.SphereBufferGeometry( 2,36,36 );
 var mySphereMaterial=new THREE.MeshNormalMaterial({wireframe: true,
  transparent: true} );
 var mySphereMesh=new THREE.Mesh(mySphereGeometry,mySphereMaterial);
 mySphereMesh.position.set(0, 2.5, 0);
 //设置为true才能看到阴影
 mySphereMesh.castShadow = true;
 myScene.add( mySphereMesh );
 //创建(白色不可见)平面
 var myPlaneGeometry=new THREE.PlaneGeometry( 120, 120, 1, 1 );
 var myPlaneMaterial=new THREE.MeshStandardMaterial({color:'white'});
 var myPlaneMesh=new THREE.Mesh(myPlaneGeometry, myPlaneMaterial );
 myPlaneMesh.rotateX(-Math.PI/2 );
 myPlaneMesh.rotateZ(-Math.PI/7 );
 myPlaneMesh.position.set(0, -4.5, 0)
 //表示平面支持投射阴影
 myPlaneMesh.receiveShadow = true;
 myScene.add(myPlaneMesh );
 //渲染球体和阴影
 myRenderer.render(myScene, myCamera);
</script></body>


在上面这段代码中,myRenderer.shadowMap.enabled=true语句表示渲染器支持阴影。myLight.castShadow=true语句表示光源支持阴影。mySphereMesh.castShadow=true语句表示三维图形(球体)支持阴影。myPlaneMesh.receiveShadow=true语句表示投射平面支持阴影。
该实例源文件下载二维码为:



02

模糊DirectionalLight光源产生的阴影


此实例主要通过设置THREE.DirectionalLight的shadow属性的子属性radius,实现自定义THREE.DirectionalLight光源照射球体产生阴影的模糊程度。当浏览器显示页面时,将在网格状的球体下面显示一个黑色的模糊的网格阴影,如图2所示。


■ 图2

主要代码如下:
<body><div id="myContainer" ></div>
<script>
 //创建渲染器
 var myRenderer = new THREE.WebGLRenderer();
 myRenderer.setPixelRatio( window.devicePixelRatio );
 myRenderer.setSize(480,320);
 myRenderer.setClearColor('white', 1);
 //设置为true才能看到阴影
 myRenderer.shadowMap.enabled = true;
 $("#myContainer").append(myRenderer.domElement);
 var myScene = new THREE.Scene();
 var myCamera=new THREE.PerspectiveCamera(45,480/320, 0.1, 1000);
 myCamera.position.set(4, 4, 2);
 myCamera.position.multiplyScalar(2);
 myCamera.lookAt(new THREE.Vector3(0, 0, 0));
 //创建DirectionalLight光源
 var myLight = new THREE.DirectionalLight('white', 1 );
 //设置为true才能看到阴影
 myLight.castShadow = true;
 myLight.position.set( 0, 14, 0 );
 //设置阴影半径以产生模糊效果
 myLight.shadow.radius = 16;
 myScene.add( myLight );
 //创建用于投射阴影的球体
 var mySphereGeometry=new THREE.SphereBufferGeometry( 2,36,36 );
 var mySphereMaterial=new THREE.MeshNormalMaterial({wireframe: true,
  transparent: true} );
 var mySphereMesh=new THREE.Mesh(mySphereGeometry,mySphereMaterial);
 mySphereMesh.position.set(0, 2.5, 0);
 //设置为true才能看到阴影
 mySphereMesh.castShadow = true;
 myScene.add( mySphereMesh );
 //创建(白色不可见)平面
 var myPlaneGeometry=new THREE.PlaneGeometry( 120, 120, 1, 1 );
 var myPlaneMaterial=new THREE.MeshStandardMaterial({color:'white'});
 var myPlaneMesh=new THREE.Mesh(myPlaneGeometry, myPlaneMaterial );
 myPlaneMesh.rotateX(-Math.PI/2 );
 myPlaneMesh.rotateZ(-Math.PI/7 );
 myPlaneMesh.position.set(0, -4.5, 0)
 //表示平面支持投射阴影
 myPlaneMesh.receiveShadow = true;
 myScene.add(myPlaneMesh );
 //渲染球体和模糊阴影
 myRenderer.render(myScene, myCamera);
</script></body>


在上面这段代码中,myLight.shadow.radius=16语句用于设置阴影的模糊程度,radius属性值越大,阴影越模糊;radius属性值越小,阴影越清晰。
该实例源文件下载二维码为:


03

补充说明


本系列所有Three.js代码(版本号r119)在IntelliJ IDEA环境编写完成,在最新版的Firefox浏览器或Google Chrome浏览器测试成功。因此建议读者在上述环境或条件下使用源代码。所有源代码不需要下载Three.js的其他文件,在使用时保持网络畅通即可。此外需要注意:Three.js版本更新较快,因此在开发应用本书的源代码时特别需要注意版本问题。


04

参考书籍



《Three.js前端三维图形开发案例集锦》

ISBN:978-7-302-58956-3

罗帅 罗斌 编著

定价:128.00元


扫码优惠购书






    文章转载自清华计算机学堂,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论