调用模型加载器(Loader)时的透明效果

原先只是实现了用单张贴图的透明效果,但是在工作中,好多模型都是用三维建模软件制作的,导出obj后可以直接导入到我们的程序中去;

如果是使用OBJMTLLoader那么,模型中透明贴图效果要怎么实现呢?

我们已经知道,要想在程序中实现透明贴图的效果,就需要将模型的材质的透明属性设置为true;

下面我们就来寻找OBJMTLLoader中设置材质属性的关键点吧。

OBJMTLLoader.js的路径为:ThreeJS\examples\js\loaders\OBJMTLLoader.js;

设置模型材质的代码如下:

if ( object.material.name ) 
{

    var material = materialsCreator.create( object.material.name );

    if ( material )
    {
        object.material = material;
     }
}

我们要怎么判断是否要把材质的透明属性设置为true呢?通过贴图的文件名,如果贴图文件名包含png,那么我们就把材质的属性设置为true;

添加代码如下:

if ( object.material.name ) 
{

    var material = materialsCreator.create( object.material.name );

    if ( material )
    {
        object.material = material;
        if((undefined == material.map) || (null == material.map))
        {
            console.log('undefined == material.map');
        }
        else if((undefined == material.map.image) ||((null == material.map.image)))
        {
            console.log('undefined == material.map.image');
        }
        else if((undefined == material.map.image.src) || (null == material.map.image.src))
        {
            console.log('undefined == material.map.image.src');
        }
        else if(material.map.image.src.toLowerCase().contains('png'))
        {
            console.log('ObjMTLLoader:' + material.map.image.src.toLowerCase());
            material.transparent = true;
        }
     }
}

可是经过测试发现经常会出现“undefined == material.map.image”,这是什么原因呢,并且更奇怪的是,如果在前面加一个断点,就可以正常运行,真是让人困扰啊!经过重重困难,原因终于被发现了,原来是因为image是一个对象,可能在执行到这一句的时候该对象还没有构建完成,所以导致该问题,如何解决呢?断续跟踪;

这一次我们切入的关键代码是:

var material = materialsCreator.create( object.material.name );

这是创建材质的过程,直接杀进去应该可以解决问题,我们看代码:

    create: function ( materialName ) {

        if ( this.materials[ materialName ] === undefined ) {

            this.createMaterial_( materialName );

        }

        return this.materials[ materialName ];

    }

直接返回了一个“this.materials[ materialName ]”,这是个什么?断续跟踪!    

 

  1     createMaterial_: function ( materialName ) {
  2 
  3         // Create material
  4 
  5         var mat = this.materialsInfo[ materialName ];
  6         var params = {
  7 
  8             name: materialName,
  9             side: this.side
 10 
 11         };
 12         //增加一个变量,保存材质是否透明
 13         //默认为false
 14         var bTransparent = false;
 15         for ( var prop in mat ) {
 16 
 17             var value = mat[ prop ];
 18 
 19             switch ( prop.toLowerCase() ) {
 20 
 21                 // Ns is material specular exponent
 22 
 23                 case 'kd':
 24 
 25                     // Diffuse color (color under white light) using RGB values
 26 
 27                     params[ 'diffuse' ] = new THREE.Color().fromArray( value );
 28 
 29                     break;
 30 
 31                 case 'ka':
 32 
 33                     // Ambient color (color under shadow) using RGB values
 34 
 35                     break;
 36 
 37                 case 'ks':
 38 
 39                     // Specular color (color when light is reflected from shiny surface) using RGB values
 40                     params[ 'specular' ] = new THREE.Color().fromArray( value );
 41 
 42                     break;
 43 
 44                 case 'map_kd':
 45 
 46                     // Diffuse texture map
 47                     //哇,看,这就是我们要找的东西了
 48                     //贴图就是在这一步生成的
 49                     //我们直接在这一步做判断,应该万无一失了吧
 50                     params[ 'map' ] = this.loadTexture( this.baseUrl + value );
 51                     params[ 'map' ].wrapS = this.wrap;
 52                     params[ 'map' ].wrapT = this.wrap;
 53                     //添加是否透明判断
 54                     if (value.toLowerCase().contains('png'))
 55                         bTransparent = true;
 56                     break;
 57 
 58                 case 'ns':
 59 
 60                     // The specular exponent (defines the focus of the specular highlight)
 61                     // A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
 62 
 63                     params['shininess'] = value;
 64 
 65                     break;
 66 
 67                 case 'd':
 68 
 69                     // According to MTL format (http://paulbourke.net/dataformats/mtl/):
 70                     //   d is dissolve for current material
 71                     //   factor of 1.0 is fully opaque, a factor of 0 is fully dissolved (completely transparent)
 72 
 73                     if ( value < 1 ) {
 74 
 75                         params['transparent'] = true;
 76                         params['opacity'] = value;
 77 
 78                     }
 79 
 80                     break;
 81 
 82                 case 'map_bump':
 83                 case 'bump':
 84 
 85                     // Bump texture map
 86 
 87                     if ( params[ 'bumpMap' ] ) break; // Avoid loading twice.
 88 
 89                     params[ 'bumpMap' ] = this.loadTexture( this.baseUrl + value );
 90                     params[ 'bumpMap' ].wrapS = this.wrap;
 91                     params[ 'bumpMap' ].wrapT = this.wrap;
 92 
 93                     break;
 94 
 95                 default:
 96                     break;
 97 
 98             }
 99 
100         }
101 
102         if ( params[ 'diffuse' ] ) {
103 
104             params[ 'color' ] = params[ 'diffuse' ];
105 
106         }
107 
108         this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
109         //设置材质的透明属性
110         this.materials[ materialName ].transparent = bTransparent;
111         return this.materials[ materialName ];
112 
113     }

 

这样修改以后,经测试已基本满足正常使用!

 

转载于:https://www.cnblogs.com/cll131421/p/4479319.html

你可能感兴趣的:(调用模型加载器(Loader)时的透明效果)