由于自己在这个领域也是刚入门,所以我都是一边写一边改的,在探究聚光灯和阴影之前,想对上一章讲到的相机旋转功能进行扩展,通过鼠标滚轮支持物体放大缩小查看,代码如下,想用的可以复制粘贴到demo里。
//监听滚轮,放大缩小物体 document.body.onmousewheel = function(event) { var ev = event || window.event; if(ev.deltaY > 0){ if(cameraRound < 30) cameraRound = cameraRound + 1; }else{ if(cameraRound > 6) cameraRound = cameraRound - 1; } camera.position.z = cameraRound *(Math.cos(arf)); camera.position.x = cameraRound *(Math.sin(arf)); };
除了这个功能之外,还对nodejs搭建的本地服务器进行了优化,之前的那个有点脆弱,有兴趣的可以留言,在后面讲到纹理的时候我会把代码放上来,因为后面可能会遇到图片加载404的错误。
进入正题
聚光灯源(SpotLight)
官方文档:一种能投射锥形阴影区域的点光源。
附官方图
很明显可以看出,这种光是有方向的,跟“灯泡”是有本质区别的,pointLight会向周围发散,他不会。
SpotLight( color, intensity, distance, angle, penumbra, decay )
color — 颜色的RBG数值。
intensity — 光强的数值。
distance -- 光强为0处到光源的距离,0表示无穷大。
angle -- 光线散射角度,最大为Math.PI/2。
penumbra -- 聚光锥的半影衰减百分比。在0和1之间的值。默认为0。
decay -- 沿着光照距离的衰退量。
关于spotlight的参数请自己去上面的官网链接玩一下,文字描述不是很好懂(数学文盲不知道怎么描述)。
放个demo,先上代码,大家可以对着代码一边看一边改一边玩
//设置立方体能投射阴影 cube.castShadow = true; var ground = new THREE.Mesh(geometry2,new THREE.MeshLambertMaterial({color:0xffffff})); ground.position.set(0,-6,0); var wall = new THREE.Mesh(geometry3,new THREE.MeshLambertMaterial({color:0xffffff})); wall.position.set(0,0,-6); //设置墙既能接收阴影也能投射阴影 wall.receiveShadow = true; wall.castShadow = true; scene.add(wall); //设置地面能接受阴影 ground.receiveShadow = true; scene.add(ground); cube.rotation.x=45*Math.PI/180; cube.rotation.y=45*Math.PI/180; cube.rotation.z=45*Math.PI/180; scene.add(cube); //添加一个聚光灯 var light = new THREE.SpotLight(0xff00ff,1); //设置聚光灯可以投射阴影 light.castShadow = true; light.shadow.camera.near = 10; light.shadow.camera.far = 300; light.shadow.camera.fov = 20; light.shadow.mapSize.width = 2048; light.shadow.mapSize.height = 2048; light.position.set(0,24,17); scene.add(light);
为了观看效果更佳,我在renderLoop()函数里加了
cube.rotation.x += 0.02; wall.rotation.z += 0.02;这样你可以更明显的观察到阴影的渲染是动态的,因此渲染阴影会消耗大量的浏览器性能。
关于阴影的使用,请注意以下四个点:
1.请设置你的渲染器支持阴影渲染的功能(由于阴影很吃性能,所以three.js需要你手动打开这个参数)
renderer.shadowMapEnabled = true;在设置渲染器的阴影渲染的时候,three.js还提供了一个参数方便你设置阴影类型,你可以通过设置renderer.shadowMapType来获得更好阴影质量或更好的性能。大家可以试试以下三个参数,第一个和第三个参数有明显的不同,应该可以看得出来。
THREE.BasicShadowMap:普通阴影映射
THREE.PCFShadowMap:柔化边缘的阴影映射
THREE.PCFSoftShadowMap:柔化边缘的软阴影映射
2.请设置你的物体能够接收/投射阴影
cube.castShadow = true;//投射 ground.receiveShadow = true; //接收在demo中,我放了一wall,他即作为一个投射阴影的对象,他本身也可以接收阴影,可以从上面的截图看到,如果你想设置一个物体既能接收阴影,又可以投射阴影,只需要按照上面的代码将他的castShodow 和 receiveShadow值都设为true即可。
3.请设置你的聚光灯能投射阴影,并将它放在合适的位置
light.castShadow = true;个人感觉比较有用的一个参数设置
light.shadow.mapSize.width = 4096; light.shadow.mapSize.height = 4096;
//light.shadow.camera.near = 10; //light.shadow.camera.far = 100; //light.shadow.camera.fov = 80;
通过这个可以设置生成阴影的质量,默认值为512,512,如果觉得阴影过于马赛克可以增大这两个值,请不要将这两个值设置的过大,刚设置成1000 WebGL直接挂了。注释掉的几个参数有兴趣可以自己研究。
关于阴影的使用请参照上面三个注意点自己试验,本人目前也在实验阶段,下一期应该会将各种模型探究一遍,大概需要两期左右去探究。写到这儿。。。。(本期质量较差,因为在测试的过程中,发现有些个参数要么弃用,要么没什么用,有什么问题打我电话,110)