Three.js源码阅读笔记

来源:互联网 发布:淘宝衣服关键词 编辑:程序博客网 时间:2024/06/05 00:47

Core::Ray

该类用来表示空间中的“射线”,主要用来进行碰撞检测。

THREE.Ray = function ( origin, direction ) {    this.origin = ( origin !== undefined ) ? origin : new THREE.Vector3();    this.direction = ( direction !== undefined ) ? direction : new THREE.Vector3();};

Ray类的构造函数颇为简单,只有两个参数origin和direction,顾名思义,也就是端点和方向。

Ray类的主要作用是进行碰撞检测。

THREE.Ray.prototype = {    constructor: THREE.Ray,    set: function ( origin, direction ) {...},    copy: function ( ray ) {...},    at: function( t, optionalTarget ) {        var result = optionalTarget || new THREE.Vector3();        return result.copy( this.direction ).multiplyScalar( t ).add( this.origin );    },    recast: function ( t ) {        this.origin.copy( this.at( t, THREE.Ray.__v1 ) );        return this;    },    closestPointToPoint: function ( point, optionalTarget ) {        var result = optionalTarget || new THREE.Vector3();        result.subVectors( point, this.origin );        var directionDistance = result.dot( this.direction );        return result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );    },    distanceToPoint: function ( point ) {        var directionDistance = THREE.Ray.__v1.subVectors( point, this.origin ).dot( this.direction );        THREE.Ray.__v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );        return THREE.Ray.__v1.distanceTo( point );    },    isIntersectionSphere: function( sphere ) {        return ( this.distanceToPoint( sphere.center ) <= sphere.radius );    },    isIntersectionPlane: function ( plane ) {        // check if the line and plane are non-perpendicular, if they        // eventually they will intersect.        var denominator = plane.normal.dot( this.direction );        if ( denominator != 0 ) {            return true;        }        // line is coplanar, return origin        if( plane.distanceToPoint( this.origin ) == 0 ) {            return true;        }        return false;    },    distanceToPlane: function ( plane ) {        var denominator = plane.normal.dot( this.direction );        if ( denominator == 0 ) {            // line is coplanar, return origin            if( plane.distanceToPoint( this.origin ) == 0 ) {                return 0;            }            // Unsure if this is the correct method to handle this case.            return undefined;        }        var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;        return t;    },    intersectPlane: function ( plane, optionalTarget ) {        var t = this.distanceToPlane( plane );        if( t === undefined ) {            return undefined;        }        return this.at( t, optionalTarget );    },    transform: function ( matrix4 ) {...},    equals: function ( ray ) {...},    clone: function () {...}};

 Ray类有这样一些方法:

  • at(t, optionalTarget):返回射线上与射线端点距离为t的点。如果传入了optionalTarget参数,那么就将该对象设置为返回的点(下同)。
  • closestPointToPoint: function ( point, optionalTarget ):传入一个点,返回由该点向射线引垂线得到的垂足。
  • distanceToPoint: function ( point ):传入一个点,返回该点到射线的距离。
  • distanceToPlane: function( plane ):传入一个平面,返回该平面到与射线的距离(如果射线与平面不平行,那么距离就为0)。
  • isIntersectionSphere:function( sphere ):判断射线是否与一个球体有交点,传入的参数sphere需要有radius和center属性(比如,传入sphereGeometry就是没用的)。
  • isIntersectionPlane:function( plane ):判断射线是否与一个平面有交点,传入的参数plane需要有normal属性。
  • recast(t):将Three.Ray.__v1(这个变量)设置为调用者的at(t)位置。(Three.Ray.__v1和Three.Ray.__v2是定义在Three.Ray而不是其peototype上的临时变量,类似于C++中的静态变量)。

Material::MeshBasicMaterial

之前我们分析过Material类和LineBasicMaterial类,现在我们来看剩下的几个材质类。MeshBasicMaterial是一种“光照无关”的材质,也就是说,在没有光照的情况下,材质依然能够要显示出来。

THREE.MeshBasicMaterial = function ( parameters ) {    THREE.Material.call( this );    this.color = new THREE.Color( 0xffffff ); // emissive    this.map = null;    this.lightMap = null;    this.specularMap = null;    this.envMap = null;    this.combine = THREE.MultiplyOperation;    this.reflectivity = 1;    this.refractionRatio = 0.98;    this.fog = true;    this.shading = THREE.SmoothShading;    this.wireframe = false;    this.wireframeLinewidth = 1;    this.wireframeLinecap = 'round';    this.wireframeLinejoin = 'round';    this.vertexColors = THREE.NoColors;    this.skinning = false;    this.morphTargets = false;    this.setValues( parameters );};

MeshBasicMaterial包括这样一些属性:

  • color:颜色,十六进制整数,如果设定了color属性,整个材质将全部使用这种颜色。
  • map:映射,可以指向Three.Texture的实例对象。实际上,纹理就是一种映射,从一个[0,1][0,1]范围的二维坐标到颜色值的映射,过程就是从纹理图片的响应位置上取颜色。当然也有不依赖于图片的纹理,比如一些简单的三角函数的组合,将而为坐标转化为颜色,也能够成为纹理。这种纹理可以在表面上绘制复杂的图案。
  • lightMap,envMap,specularMap:字面的意思是光照映射,光谱映射等,可能用来服务于Three中的某些类型的着色器。
  • wireframe:如果设定为true,那么整个几何形状就显示为网格状的(即只显示边,不显示面)。
  • wireframeLinecap,wireframeLinewidth,wireframeLinejoin:采用wireframe模式时,控制网格的线段端点,线段宽度,线段交点等。
  • fog:显示材质的颜色是否会被全局的fog设定影响。
  • vertexColors:数组,每个元素都是一个Three.Color变量。如果设定了这个变量,那么这个数组的前3个或4个元素(视面的类型),就是面的端点的颜色。而在默认的片元着色器中,面上的颜色是由端点颜色内插而来的。
  • morphTarget:如果设置为true,那么就可以使用morphTarget模式(一种利用着色器来计算顶点位置的方法,可以高效地产生类似于windows98形变屏保模式的方法,在我的前面一片demo源码阅读笔记中有详细叙述)。
  • MeshBasicMaterial本身只有一个clone方法(该方法调用Material的clone方法),其他方法都是继承自Material方法。

Material::MeshLambertMaterial

MeshLambertMaterial是一种朗伯面材质。朗伯面就是各向反射同性面,任何角度的光线照射上去,反射的亮度和反射角度无关。以下摘录了除掉与MeshBasicMaterial重复的属性剩下的若干个属性。

THREE.MeshLambertMaterial = function ( parameters ) {    THREE.Material.call( this );    this.color = new THREE.Color( 0xffffff ); // diffuse    this.ambient = new THREE.Color( 0xffffff );    this.emissive = new THREE.Color( 0x000000 );    this.wrapAround = false;    this.wrapRGB = new THREE.Vector3( 1, 1, 1 );    this.combine = THREE.MultiplyOperation;    this.reflectivity = 1;    this.refractionRatio = 0.98;    ...    this.setValues( parameters );};

 除了MeshBasicMaterial中的color,vertexColors等属性,MeshLambertMaterial类还具有几个跟光照相关的属性:

  • color:主颜色,当然如果设置了采用映射或者为每个端点赋值颜色,就没有用了。
  • ambient:环境色,默认为白色,如果改变的话,会整体影响材质看上去的的颜色。
  • emissive:发射光的颜色,默认为黑色,即其中与MeshBasicMaterial原理类似的部分。默认情况下,如果没有光照,而且render的clearColor设置为黑色(考虑光照,这是通常的情况)的话,一个使用MeshLambertMaterial的物体时看不到的,但是如果这里改成其他颜色,应当就能看到。
  • combine:光照与颜色混合的方式,默认为乘法。
  • reflectivity:反射率,默认为1,即全部反射。
  • refractionRatio:折射率(即穿透物体一个单位长度后衰减的比率),可能用于透明物体。 

Material::MeshPhongMaterial 

MeshPhongMaterial,旁氏反射面,表示有光泽的物体,在极端情况下就是镜面。

THREE.MeshPhongMaterial = function ( parameters ) {    THREE.Material.call( this );    this.color = new THREE.Color( 0xffffff ); // diffuse    this.ambient = new THREE.Color( 0xffffff );    this.emissive = new THREE.Color( 0x000000 );    this.specular = new THREE.Color( 0x111111 );    this.shininess = 30;    this.metal = false;    this.perPixel = true;

this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalScale = new THREE.Vector2( 1, 1 ); ...this.setValues( parameters );};

 暂时还没大弄明白。

Material::MeshFaceMaterial

允许为某个geometry的每个面单独指定材质,通常用于从三维模型中读取数据,然后构造mesh。

THREE.MeshFaceMaterial = function ( materials ) {    this.materials = materials instanceof Array ? materials : [];};

 只需要传入一个数组作为参数,其materials数组的每一个元素都是某种MeshXXXXMaterial,然后再geometry中创建表面时,为face指定materialIndex即可。 


<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* cnblogs 首页横幅 */google_ad_slot = "5419468456";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕后特别不爱吃水果怎么办 宝宝吃了无比滴怎么办 婴儿上火怎么办吃什么可以去火 肚子胀怎么办最快的方法 40天婴儿拉水怎么办 8个月宝宝坐不稳怎么办 宝宝段奶不吃奶粉怎么办 3个月宝宝头睡偏了怎么办 2个月婴儿抱着睡怎么办 两个半月的宝宝睡眠少怎么办 七个月宝宝不愿意坐怎么办 一个多月的宝宝老是哭闹怎么办 宝宝头老往后仰怎么办 8个月宝宝不会爬怎么办 孩子个头长得慢怎么办 宝宝个头长得慢怎么办 婴儿个头长得慢怎么办 11个月宝宝认生怎么办 3个月宝宝认人怎么办 3个月的宝宝认生怎么办 两个月的宝宝睡觉一惊一惊怎么办 六个月宝宝不喜欢喝水怎么办 三岁宝宝尿多怎么办 一岁的宝宝尿少怎么办 一岁宝宝尿黄怎么办 三岁宝宝尿黄怎么办 5个月宝宝认生怎么办 3岁宝宝怕生胆小怎么办 2岁宝宝怕生胆小怎么办 1岁半宝宝认生怎么办 宝宝认人一直哭怎么办 七个月宝宝认人怎么办 一个月宝宝认人怎么办 2个多月宝宝认人怎么办 婴儿认人一直哭怎么办 六个月宝宝认人怎么办 十一个月宝宝断奶后辅食怎么办 6个月宝宝不会坐怎么办 7个月宝宝坐不住怎么办 三个月宝宝白天闹觉怎么办 3个月宝宝不追声怎么办