• Three.js源码阅读笔记-5


    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即可。 

    作者:一叶斋主人
    出处:www.cnblogs.com/yiyezhai
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    数组相关常见的三种错误
    JMeter连接MYSQL数据库并进行操作详解
    JMeter实现动态关联——两个接口在不同的线程组
    Android : kernel中添加虚拟文件节点
    Android O : 系统原生锁屏密码位数限制及自动检查
    Android O : DNS列表获取及IPv4/IPv6优先级修改
    Android 打印调用栈的方法
    Android TV : 系统分区配置及增加私有分区
    Android TV : Mstar平台Audio Path及声音曲线配置
    Android TV : Mstar平台 GPIO 调试
  • 原文地址:https://www.cnblogs.com/yiyezhai/p/3074129.html
Copyright © 2020-2023  润新知