利用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 form action动态修改方法
Nov 04 Javascript
jquery 3D球状导航的文章分类
Jul 06 Javascript
基于JavaScript实现一定时间后去执行一个函数
Dec 14 Javascript
jQuery插件支持同一页面被多次调用
Feb 14 Javascript
微信小程序 网络API 上传、下载详解
Nov 09 Javascript
Bootstrap模态框案例解析
Mar 05 Javascript
Vue指令的钩子函数使用方法
Mar 20 Javascript
bootstrap suggest下拉框使用详解
Apr 10 Javascript
JS弹窗 JS弹出DIV并使整个页面背景变暗功能的实现代码
Apr 21 Javascript
如何利用Node.js与JSON搭建简单的动态服务器
Jun 16 Javascript
详解js中的几种常用设计模式
Jul 16 Javascript
jQuery+ThinkPHP实现图片上传
Jul 23 jQuery
使用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
jq的get传参数在utf-8中乱码问题的解决php版
2008/07/23 PHP
PHP rawurlencode与urlencode函数的深入分析
2013/06/08 PHP
ThinkPHP3.1新特性之内容解析输出详解
2014/06/19 PHP
PHP将URL转换成短网址的算法分享
2016/09/13 PHP
php preg_match的匹配不同国家语言实例
2016/12/29 PHP
Javascript this 的一些学习总结
2012/08/02 Javascript
js屏蔽鼠标键盘(右键/Ctrl+N/Shift+F10/F11/F5刷新/退格键)
2013/01/24 Javascript
jQuery操作checkbox选择(list/table)
2013/04/07 Javascript
js控制表单奇偶行样式的简单方法
2013/07/31 Javascript
js实现连续英文字符自动换行兼容ie6 ie7和firefox
2013/09/06 Javascript
javascript设计模式之解释器模式详解
2014/06/05 Javascript
有关easyui-layout中的收缩层无法显示标题的解决办法
2016/05/10 Javascript
Bootstrap学习笔记之css组件(3)
2016/06/07 Javascript
Bootstrap实现弹性搜索框
2016/07/11 Javascript
JavaScript设计模式之单体模式全面解析
2016/09/09 Javascript
深入浅析Node环境和浏览器的区别
2018/08/14 Javascript
vue webpack开发访问后台接口全局配置的方法
2018/09/18 Javascript
微信小程序实现多选删除列表数据功能示例
2019/01/15 Javascript
JS数组方法push()、pop()用法实例分析
2020/01/18 Javascript
python自动化工具日志查询分析脚本代码实现
2013/11/26 Python
python实现类的静态变量用法实例
2015/05/08 Python
python二分查找算法的递归实现方法
2016/05/12 Python
对sklearn的使用之数据集的拆分与训练详解(python3.6)
2018/12/14 Python
Python使用psutil获取进程信息的例子
2019/12/17 Python
pytorch::Dataloader中的迭代器和生成器应用详解
2020/01/03 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
CSS Houdini实现动态波浪纹效果
2019/07/30 HTML / CSS
Html5游戏开发之乒乓Ping Pong游戏示例(一)
2013/01/21 HTML / CSS
菲律宾酒店预订网站:Hotels.com菲律宾
2017/07/12 全球购物
意大利一家专营包包和配饰的网上商店:Borse Last Minute
2019/08/26 全球购物
纠纷协议书
2014/04/16 职场文书
爱的奉献演讲稿
2014/09/10 职场文书
纪念九一八爱国演讲稿600字
2014/09/14 职场文书
描述鲁迅的名言整理,一生受用
2019/08/08 职场文书
Golang 实现WebSockets
2022/04/24 Golang
PyCharm 配置SSH和SFTP连接远程服务器
2022/05/11 Python