利用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 相关文章推荐
script标签的 charset 属性使用说明
Dec 04 Javascript
淘宝搜索框效果实现分析
Mar 05 Javascript
js取两个数组的交集|差集|并集|补集|去重示例代码
Aug 07 Javascript
html的DOM中document对象forms集合用法实例
Jan 21 Javascript
JS中的二叉树遍历详解
Mar 18 Javascript
jquery Deferred 快速解决异步回调的问题
Apr 05 Javascript
js实现的在线调色板功能完整实例
Dec 21 Javascript
Vue 项目中遇到的跨域问题及解决方法(后台php)
Mar 28 Javascript
微信小程序实现分享朋友圈的图片功能示例
Jan 18 Javascript
bootstrap datepicker的基本使用教程
Jul 09 Javascript
layui上传图片到服务器的非项目目录下的方法
Sep 26 Javascript
JavaScript利用键盘码控制div移动
Mar 19 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
千呼万唤始出来,DOTA2勇士令状不朽宝藏Ⅱ现已推出
2020/08/25 DOTA
php用户注册时常用的检验函数实例总结
2014/12/22 PHP
ThinkPHP框架表单验证操作方法
2017/07/19 PHP
thinkphp框架使用JWTtoken的方法详解
2019/10/10 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
EXTJS内使用ACTIVEX控件引起崩溃问题的解决方法
2010/03/31 Javascript
JS实现仿中关村论坛评分后弹出提示效果的方法
2015/02/23 Javascript
javascript操作select元素实例分析
2015/03/27 Javascript
js实现touch移动触屏滑动事件
2015/04/17 Javascript
基于chosen插件实现人员选择树搜索自动筛选功能
2016/09/24 Javascript
微信小程序之小豆瓣图书实例
2016/11/30 Javascript
Express与NodeJs创建服务器的两种方法
2017/02/06 NodeJs
vue如何引用其他组件(css和js)
2017/04/13 Javascript
Node.js中的require.resolve方法使用简介
2017/04/23 Javascript
react-native ListView下拉刷新上拉加载实现代码
2017/08/03 Javascript
js中bool值的转换及“&amp;&amp;”、“||”、 “!!”详解
2017/12/21 Javascript
详解VueJs中的V-bind指令
2018/05/03 Javascript
解决Layui中templet中a的onclick参数传递的问题
2019/09/20 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
2020/06/16 Javascript
NestJs使用Mongoose对MongoDB操作的方法
2021/02/22 Javascript
python处理图片之PIL模块简单使用方法
2015/05/11 Python
Python和JavaScript间代码转换的4个工具
2016/02/22 Python
python用模块zlib压缩与解压字符串和文件的方法
2016/12/16 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
Python 实现数据库(SQL)更新脚本的生成方法
2017/07/09 Python
Python模块的加载讲解
2019/01/15 Python
Python提取支付宝和微信支付二维码的示例代码
2019/02/15 Python
pyqt5使用按钮进行界面的跳转方法
2019/06/19 Python
python中使用while循环的实例
2019/08/05 Python
Python (Win)readline和tab补全的安装方法
2019/08/27 Python
python ftplib模块使用代码实例
2019/12/31 Python
python 装饰器重要在哪
2021/02/14 Python
深入剖析HTML5 内联框架iFrame
2016/05/04 HTML / CSS
绝对经典成功的大学生推荐信
2013/11/08 职场文书
培训班开班主持词
2015/07/02 职场文书
Golang全局变量加锁的问题解决
2021/05/08 Golang