Three.js源码阅读笔记(光照部分)


Posted in Javascript onDecember 27, 2012

天气越来越冷了,人也越来越懒怠,越来越像呆在温暖的寝室里看小说或者打游戏,也好久没看Three.js源码了。今天天气不错,接着看!

这次从光照部分看起:光照模型,从光线本身角度来看包括环境光、平行光、点光源,从物体表面材质角度看又包括漫反射和镜面反射。

Lights:Light

THREE.Light = function ( hex ) { 
THREE.Object3D.call( this ); 
this.color = new THREE.Color( hex ); 
};

该对象是其他光照对象的原型/基类,本身继承自Object3D对象/类型。它自身只有一个THREE.Color类型的color属性,就是颜色,这很好理解。

在Three.js中,光照作为一种Object3D对象,是经过Scene.add()方法加入到场景中的,渲染器会自动渲染所加入的光照效果。
Light::AmbientLight

THREE.AmbientLight = function ( hex ) { 
THREE.Light.call( this, hex ); 
};

无方向的环境光,并没有比Light类型多一个属性或方法,而仅仅为了语义上的继承而继承自Light,它甚至没有必要是Object3D对象。

Light::DirectionalLight

THREE.DirectionalLight = function ( hex, intensity ) { 
THREE.Light.call( this, hex ); 
this.position = new THREE.Vector3( 0, 1, 0 ); 
this.target = new THREE.Object3D(); 
this.intensity = ( intensity !== undefined ) ? intensity : 1; 
this.castShadow = false; 
this.onlyShadow = false; 
// more settings about shadow ...... 
};

平行光(有方向的光),使用new运算符构造该函数时需传入颜色hex和光线的“密度”intensity。这个类有这样一些属性:
position:一个位置,以该位置为起点,原点为终点的方向是光线的方向。
intensity:光线的密度,默认为1。因为RGB的三个值均在0~255之间,不能反映出光照的强度变化,光照越强,物体表面就更明亮。
distance:衰减距离,默认值为0,光照无衰减;如果是非0值,光照会从position位置(实际上是position所处的那个平面)开始衰减,衰减到distance距离之后,光照强度intensity为0。
castShadow:布尔值,控制是否产生阴影,默认为false。如果设为true,对于所有表面都会逐像元地计算其在光照方向上是否被遮挡,这会消耗大量的计算。
onlyShadow:布尔值,控制是否只产生阴影而不“照亮”物体,默认为false。这种模式也许有什么特殊应用吧。
shadowCameraLeft,shadowCameraRight……系列,以position点为中心控制产生阴影的范围?
shadowBias:阴影偏心,默认为0。
shadowDarkness:阴影对物体亮度的影响,在0~1之间,默认为0.5。
还有不少属性暂时猜不出含义(真该去补补计算机图形学啊,硬着头皮继续看吧)。

Light::PointLight

THREE.PointLight = function ( hex, intensity, distance ) { 
THREE.Light.call( this, hex ); 
this.position = new THREE.Vector3( 0, 0, 0 ); 
this.intensity = ( intensity !== undefined ) ? intensity : 1; 
this.distance = ( distance !== undefined ) ? distance : 0; 
};

点光源,position那肯定就是光源点了。注意点光源的position和平行光的position的区别,前者默认在原点,而后者默认在点(0,1,1),这使得默认的平行光方向和相机的默认朝向一致。
其他两个属性和平行光中一样。PointLight点光源没有关于如何产生阴影的设定。

Light::SpotLight

THREE.SpotLight = function ( hex, intensity, distance, angle, exponent ) { 
THREE.Light.call( this, hex ); 
this.position = new THREE.Vector3( 0, 1, 0 ); 
this.target = new THREE.Object3D(); 
this.intensity = ( intensity !== undefined ) ? intensity : 1; 
this.distance = ( distance !== undefined ) ? distance : 0; 
this.angle = ( angle !== undefined ) ? angle : Math.PI / 2; 
this.exponent = ( exponent !== undefined ) ? exponent : 10; // more settings about shadow... 
};

一种可以在某个方向上产生阴影的点光源,影响MeshLamberMaterial和MeshPhongMaterial类型材质的表面。对阴影如何处理的设定和DirectionLight一致。
总之,光照对象并不承担渲染光照的任务,而仅仅是定义如何渲染光照。
Object::Partical
  
THREE.Particle = function ( material ) { 
THREE.Object3D.call( this ); 
this.material = material; 
};

粒子就是一个由材质的Object3D,这很好理解。Object3D对象提供一个坐标(就是粒子的坐标),负责粒子的运动,粒子只需要指定表现它的材质即可。

Object::ParticalSystem

THREE.ParticleSystem = function ( geometry, material ) { 
THREE.Object3D.call( this ); 
this.geometry = geometry; 
this.material = ( material !== undefined ) ? material : new THREE.ParticleBasicMaterial( { color: Math.random() * 0xffffff } ); 
this.sortParticles = false; 
if ( this.geometry ) { 
if( this.geometry.boundingSphere === null ) { 
this.geometry.computeBoundingSphere(); 
} 
this.boundRadius = geometry.boundingSphere.radius; 
} 
this.frustumCulled = false; 
};

粒子系统表现多个粒子的运动,粒子系统本身继承自是Object3D对象。有这样几个属性:
geometry属性,每一个节点都是一个粒子,这些共享一个材质。
material属性,即这些节点的材质。

frustumCulled属性,布尔值,如果设定为真,那么在相机视界之外的会被踢出,但还没弄清楚是粒子系统中心坐标在视界外就踢出整个粒子系统还是单个粒子出去了就剔除,猜测多半是后者。

其实这几篇都是涉及怎么定义场景的,至于怎么渲染场景很难有深入。我准备接下来去看Demo的代码,结合者看看WebGLRenderer类的源代码(几千行OMG)。

Javascript 相关文章推荐
一段非常简单的js判断浏览器的内核
Aug 17 Javascript
js实现双击图片放大单击缩小的方法
Feb 17 Javascript
关于延迟加载JavaScript
May 05 Javascript
原生JS实现拖拽图片效果
Aug 27 Javascript
jQuery事件委托之Safari
Jul 05 Javascript
Google 地图叠加层实例讲解
Aug 06 Javascript
jQuery实现动态生成表格并为行绑定单击变色动作的方法
Apr 17 jQuery
基于canvas粒子系统的构建详解
Aug 31 Javascript
JS实现520 表白简单代码
May 21 Javascript
vue实现双向绑定和依赖收集遇到的坑
Nov 29 Javascript
vue+elementUI实现简单日历功能
Sep 24 Javascript
JavaScript 中判断变量是否为数字的示例代码
Oct 22 Javascript
通过jQuery源码学习javascript(三)
Dec 27 #Javascript
JS原型对象通俗"唱法"
Dec 27 #Javascript
通过jQuery源码学习javascript(二)
Dec 27 #Javascript
js 判断一个元素是否在页面中存在
Dec 27 #Javascript
通过jQuery源码学习javascript(一)
Dec 27 #Javascript
Eval and new funciton not the same thing
Dec 27 #Javascript
Javascript图像处理—虚拟边缘介绍及使用方法
Dec 27 #Javascript
You might like
php ucwords() 函数将字符串中每个单词的首字符转换为大写(实现代码)
2016/05/12 PHP
微信利用PHP创建自定义菜单的方法
2016/08/01 PHP
javascript div 遮罩层封锁整个页面
2009/07/10 Javascript
滚动图片效果 jquery实现回旋滚动效果
2013/01/08 Javascript
ie下jquery.getJSON的缓存问题的处理方法
2013/03/29 Javascript
单击复制文字兼容各浏览器的完美解决方案
2013/07/04 Javascript
简单js代码实现selece二级联动(推荐)
2014/02/18 Javascript
Ext修改GridPanel数据和字体颜色、css属性等
2014/06/13 Javascript
5款JavaScript代码压缩工具推荐
2014/07/07 Javascript
jQuery实现跨域
2015/02/03 Javascript
微信小程序实现导航栏选项卡效果
2020/06/19 Javascript
原生js实现trigger方法示例代码
2019/05/22 Javascript
javascript function(函数类型)使用与注意事项小结
2019/06/10 Javascript
详解Vue中组件传值的多重实现方式
2019/08/16 Javascript
Nodejs libuv运行原理详解
2019/08/21 NodeJs
利用d3.js实现蜂巢图表带动画效果
2019/09/03 Javascript
react PropTypes校验传递的值操作示例
2020/04/28 Javascript
五句话帮你轻松搞定js原型链
2020/12/09 Javascript
Python编程实现二分法和牛顿迭代法求平方根代码
2017/12/04 Python
Python处理菜单消息操作示例【基于win32ui模块】
2018/05/09 Python
pygame游戏之旅 载入小车图片、更新窗口
2018/11/20 Python
将pandas.dataframe的数据写入到文件中的方法
2018/12/07 Python
解决python xx.py文件点击完之后一闪而过的问题
2019/06/24 Python
PyTorch中Tensor的拼接与拆分的实现
2019/08/18 Python
简单了解python filter、map、reduce的区别
2020/01/14 Python
工业设计毕业生自荐信
2014/04/13 职场文书
《晚上的太阳》教学反思
2014/04/23 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
高校群众路线教育实践活动剖析材料
2014/10/10 职场文书
党员个人整改方案及措施
2014/10/25 职场文书
具结保证书
2015/01/17 职场文书
仓库保管员岗位职责
2015/02/09 职场文书
建议书的格式及范文
2015/09/14 职场文书
2016年党员岗位承诺书
2016/03/24 职场文书
Vue Element UI自定义描述列表组件
2021/05/18 Vue.js
剧场版《转生恶役只好拔除破灭旗标》公开最新视觉图 2023年上映
2022/04/02 日漫