利用Three.js如何实现阴影效果实例代码


Posted in Javascript onSeptember 26, 2017

前言

众所周知作为webgl的插件,three.js肯定没有原生webgl那样,添加一个阴影这么费劲。所以,经过一小时的研究(笨人不聪明,已经是极限速度了)。终于将阴影效果做了出来,并且还发现一些容易犯错的地方。话不多说了,来一起看看详细的介绍吧。

先上效果图:

利用Three.js如何实现阴影效果实例代码

实现这个效果其实很简单,只需要设置几个属性就可以实现当前的效果。而上面的材质问题我将放到下一节:

(1)首先需要告诉渲染器我需要阴影,你给我生成阴影:

renderer.shadowMap.enabled = true;

(2)然后告诉灯光,我需要阴影:

light.castShadow = true;

(3)告诉模型哪些需要投射阴影:

//告诉球需要投射阴影 
 sphere.castShadow = true; 
//告诉立方体需要投射阴影 
 cube.castShadow = true;

(4)最后告诉最底下的平面长方形你要接受阴影:

plane.receiveShadow = true;

上面四步只要设置好了,就可以实现阴影的效果了。

注意事项:你的模型的材质一定要选择对灯光有反应的材质,要不然不会出现效果,就是因为这个问题导致好长时间没有整出来阴影。

案例全部代码:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
 <meta charset="UTF-8"> 
 <title>Title</title> 
 <style type="text/css"> 
 html, body { 
  margin: 0; 
  height: 100%; 
 } 
 
 canvas { 
  display: block; 
 } 
 
 </style> 
</head> 
<body onload="draw();"> 
 
</body> 
<script src="build/three.js"></script> 
<script src="examples/js/controls/TrackballControls.js"></script> 
<script src="examples/js/libs/stats.min.js"></script> 
<script> 
 var renderer; 
 function initRender() { 
 renderer = new THREE.WebGLRenderer({antialias:true}); 
 renderer.setSize(window.innerWidth, window.innerHeight); 
 //告诉渲染器需要阴影效果 
 renderer.shadowMap.enabled = true; 
 renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默认的是,没有设置的这个清晰 THREE.PCFShadowMap 
 document.body.appendChild(renderer.domElement); 
 } 
 
 var camera; 
 function initCamera() { 
 camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 
 camera.position.set(0, 40, 100); 
 camera.lookAt(new THREE.Vector3(0,0,0)); 
 } 
 
 var scene; 
 function initScene() { 
 scene = new THREE.Scene(); 
 } 
 
 var light; 
 function initLight() { 
 scene.add(new THREE.AmbientLight(0x444444)); 
 
 light = new THREE.SpotLight(0xffffff); 
 light.position.set(60,30,0); 
 
 //告诉平行光需要开启阴影投射 
 light.castShadow = true; 
 
 scene.add(light); 
 } 
 
 function initModel() { 
 //上面的球 
 var sphereGeometry = new THREE.SphereGeometry(5,20,20); 
 var sphereMaterial = new THREE.MeshStandardMaterial({color:0x7777ff}); 
 
 var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); 
 sphere.position.y = 5; 
 
 //告诉球需要投射阴影 
 sphere.castShadow = true; 
 
 scene.add(sphere); 
 
 //辅助工具 
 var helper = new THREE.AxisHelper(10); 
 scene.add(helper); 
 
 //立方体 
 var cubeGeometry = new THREE.CubeGeometry(10,10,8); 
 var cubeMaterial = new THREE.MeshLambertMaterial({color:0x00ffff}); 
 
 var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); 
 cube.position.x = 25; 
 cube.position.y = 5; 
 cube.position.z = -5; 
 
 //告诉立方体需要投射阴影 
 cube.castShadow = true; 
 
 scene.add(cube); 
 
 //底部平面 
 var planeGeometry = new THREE.PlaneGeometry(100,100); 
 var planeMaterial = new THREE.MeshStandardMaterial({color:0xaaaaaa}); 
 
 var plane = new THREE.Mesh(planeGeometry, planeMaterial); 
 plane.rotation.x = - 0.5 * Math.PI; 
 plane.position.y = -0; 
 
 //告诉底部平面需要接收阴影 
 plane.receiveShadow = true; 
 
 scene.add(plane); 
 
 } 
 
 //初始化性能插件 
 var stats; 
 function initStats() { 
 stats = new Stats(); 
 document.body.appendChild(stats.dom); 
 } 
 
 //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放 
 var controls; 
 function initControls() { 
 controls = new THREE.TrackballControls( camera ); 
 //旋转速度 
 controls.rotateSpeed = 5; 
 //变焦速度 
 controls.zoomSpeed = 3; 
 //平移速度 
 controls.panSpeed = 0.8; 
 //是否不变焦 
 controls.noZoom = false; 
 //是否不平移 
 controls.noPan = false; 
 //是否开启移动惯性 
 controls.staticMoving = false; 
 //动态阻尼系数 就是灵敏度 
 controls.dynamicDampingFactor = 0.3; 
 //未知,占时先保留 
 //controls.keys = [ 65, 83, 68 ]; 
 controls.addEventListener( 'change', render ); 
 } 
 
 function render() { 
 renderer.render( scene, camera ); 
 } 
 
 //窗口变动触发的函数 
 function onWindowResize() { 
 
 camera.aspect = window.innerWidth / window.innerHeight; 
 camera.updateProjectionMatrix(); 
 controls.handleResize(); 
 render(); 
 renderer.setSize( window.innerWidth, window.innerHeight ); 
 
 } 
 
 function animate() { 
 //更新控制器 
 render(); 
 
 //更新性能插件 
 stats.update(); 
 
 controls.update(); 
 
 requestAnimationFrame(animate); 
 } 
 
 function draw() { 
 initRender(); 
 initScene(); 
 initCamera(); 
 initLight(); 
 initModel(); 
 initControls(); 
 initStats(); 
 
 animate(); 
 window.onresize = onWindowResize; 
 } 
</script> 
</html>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用Three.js具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
几种延迟加载JS代码的方法加快网页的访问速度
Oct 12 Javascript
JavaScript中的标签语句用法分析
Feb 10 Javascript
基于cookie实现zTree树刷新后展开状态不变
Feb 28 Javascript
jQuery遮罩层实例讲解
May 11 jQuery
php 解压zip压缩包内容到指定目录的实例
Jan 23 Javascript
axios拦截设置和错误处理方法
Mar 05 Javascript
vue-cli基础配置及webpack配置修改的完整步骤
Oct 20 Javascript
vue 对axios get pust put delete封装的实例代码
Jan 05 Javascript
Node在Controller层进行数据校验的过程详解
Aug 28 Javascript
在实例中重学JavaScript事件循环
Dec 03 Javascript
JavaScript实现手风琴效果
Feb 18 Javascript
canvas实现贪食蛇的实践
Feb 15 Javascript
使用JavaScript实现在页面中显示距离2017年中秋节的天数
Sep 26 #Javascript
Three.js实现绘制字体模型示例代码
Sep 26 #Javascript
Three.js利用Detector.js插件如何实现兼容性检测详解
Sep 26 #Javascript
JS+jQuery实现注册信息的验证功能
Sep 26 #jQuery
详解vue-cli中的ESlint配置文件eslintrc.js
Sep 25 #Javascript
JavaScript 自定义事件之我见
Sep 25 #Javascript
详解在vue-cli中使用路由
Sep 25 #Javascript
You might like
PHP中图片等比缩放的实例
2013/03/24 PHP
深入PHP数据加密详解
2013/06/18 PHP
ThinkPHP中的关联模型注意点
2014/06/16 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
php静态文件返回304技巧分享
2015/01/06 PHP
PHP实现的曲线统计图表示例
2016/11/10 PHP
使用jQuery模板来展现json数据的代码
2010/10/22 Javascript
ExtJs使用总结(非常详细)
2012/03/22 Javascript
jQuery中的通配符选择器使用总结
2016/05/30 Javascript
JavaScript实现阿拉伯数字和中文数字互相转换
2016/06/12 Javascript
jQuery.Callbacks()回调函数队列用法详解
2016/06/14 Javascript
jQuery实现的自定义弹出层效果实例详解
2016/09/04 Javascript
jquery实现输入框实时输入触发事件代码
2016/12/21 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
2018/04/23 jQuery
Vue实现简单分页器
2018/12/29 Javascript
node中使用log4js4.x版本记录日志的方法
2019/08/20 Javascript
JavaScript异步操作的几种常见处理方法实例总结
2020/05/11 Javascript
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
python根据距离和时长计算配速示例
2014/02/16 Python
Windows8下安装Python的BeautifulSoup
2015/01/22 Python
Django实现一对多表模型的跨表查询方法
2018/12/18 Python
Python Selenium 之数据驱动测试的实现
2019/08/01 Python
python time.strptime格式化实例详解
2021/02/03 Python
Spartoo芬兰:欧洲最大的网上鞋店
2016/08/28 全球购物
韩国最大的购物网站:Gmarket
2019/06/20 全球购物
司机职责范本
2014/03/08 职场文书
桥梁工程专业求职信
2014/04/21 职场文书
大学生入党推荐书范文
2014/05/17 职场文书
助人为乐好少年事迹材料
2014/08/18 职场文书
竞选大学学委演讲稿
2014/09/13 职场文书
买房协议书范本
2014/10/23 职场文书
离婚答辩状范文
2015/05/22 职场文书
党小组评议意见
2015/06/02 职场文书
环境卫生整治简报
2015/07/20 职场文书
pycharm 如何查看某一函数源码的快捷键
2021/05/12 Python
mysql 获取时间方式
2022/03/20 MySQL