利用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 相关文章推荐
JavaScript 学习笔记(九)call和apply方法
Jan 11 Javascript
Jquery 类网页微信二维码图块滚动效果具体实现
Oct 14 Javascript
浅谈Unicode与JavaScript的发展史
Jan 19 Javascript
JS仿Windows开机启动Loading进度条的方法
Feb 26 Javascript
JavaScript中解析JSON数据的三种方法
Jul 03 Javascript
AngularJs Managing Service Dependencies详解
Sep 02 Javascript
在js代码拼接dom对象到页面上去的模板总结(必看)
Feb 14 Javascript
JS表单数据验证的正则表达式(常用)
Feb 18 Javascript
react-native fetch的具体使用方法
Nov 01 Javascript
vue的全局变量和全局拦截请求器的示例代码
Sep 13 Javascript
Vue使用localStorage存储数据的方法
May 27 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
Nov 13 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日期处理函数 整型日期格式
2011/01/12 PHP
php实现有趣的人品测试程序实例
2015/06/08 PHP
利用onresize使得div可以随着屏幕大小而自适应的代码
2010/01/15 Javascript
jQuery的deferred对象使用详解
2011/08/20 Javascript
js获得网页背景色和字体色的方法
2014/03/21 Javascript
js生成动态表格并为每个单元格添加单击事件的方法
2014/04/14 Javascript
通过JQuery将DIV的滚动条滚动到指定的位置方便自动定位
2014/05/05 Javascript
点击标签切换和自动切换DIV选项卡
2014/08/10 Javascript
JavaScript实现的石头剪刀布游戏源码分享
2014/08/22 Javascript
javascript中Math.random()使用详解
2015/04/15 Javascript
基于jQuery实现的仿百度首页滑动选项卡效果代码
2015/11/16 Javascript
全面解析Bootstrap中tooltip、popover的使用方法
2016/06/13 Javascript
无阻塞加载js,防止因js加载不了影响页面显示的问题
2016/12/18 Javascript
Vue使用vue-area-linkage实现地址三级联动效果的示例
2018/06/27 Javascript
Vue2.0学习系列之项目上线的方法步骤(图文)
2018/09/25 Javascript
Vue 重置组件到初始状态的方法示例
2018/10/10 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
vue实现在v-html的html字符串中绑定事件
2019/10/28 Javascript
Vue中keep-alive组件作用详解
2020/02/04 Javascript
解决vue init webpack 下载依赖卡住不动的问题
2020/11/09 Javascript
JavaScript中arguments的使用方法详解
2020/12/20 Javascript
深入解答关于Python的11道基本面试题
2017/04/01 Python
python实现rsa加密实例详解
2017/07/19 Python
Python编程实现控制cmd命令行显示颜色的方法示例
2017/08/14 Python
Python数据集切分实例
2018/12/08 Python
python中的colorlog库使用详解
2019/07/05 Python
python可视化实现KNN算法
2019/10/16 Python
Python使用PyQt5/PySide2编写一个极简的音乐播放器功能
2020/02/07 Python
Django Serializer HiddenField隐藏字段实例
2020/03/31 Python
澳大利亚排名第一的狂热牛仔品牌:ONETEASPOON
2018/11/20 全球购物
俄罗斯在线服装店:STOLNIK
2021/03/07 全球购物
水电工岗位职责
2014/02/12 职场文书
婚前财产公证书
2014/04/10 职场文书
无传销社区工作方案
2014/05/13 职场文书
怎样写工作总结啊!
2019/06/18 职场文书
详解Mysql 函数调用优化
2021/04/07 MySQL