Three.js源碼閱讀筆記-5

Core::Ray

該類用來表示空間中的「射線」,主要用來進行碰撞檢測。windows

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類有這樣一些方法:this

  • 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是一種「光照無關」的材質,也就是說,在沒有光照的狀況下,材質依然可以要顯示出來。spa

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包括這樣一些屬性:prototype

  • 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重複的屬性剩下的若干個屬性。code

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類還具備幾個跟光照相關的屬性:orm

  • 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 ); };

 暫時還沒大弄明白。blog

Material::MeshFaceMaterial

容許爲某個geometry的每一個面單獨指定材質,一般用於從三維模型中讀取數據,而後構造mesh。

THREE.MeshFaceMaterial = function ( materials ) {

    this.materials = materials instanceof Array ? materials : [];

};

 只須要傳入一個數組做爲參數,其materials數組的每個元素都是某種MeshXXXXMaterial,而後再geometry中建立表面時,爲face指定materialIndex便可。 

相關文章
相關標籤/搜索