three.js中材质的应用

一个场景的炫酷和视觉效果不仅取决于光照渲染,和动画渲染,在很大程度上也取决于场景中对象的材质属性。巧妙的应用材质属性,将会使场景锦上添花,美不胜收。接下来就对three.js中几种叫常用的材质非别做介绍:MeshBasicMaterial(网格基础材质)、MeshDepthMaterial(网格深度材质)、MeshLambertMaterial(网格朗伯特材质)、MeshPhoneMaterial(网格冯式材质)。当然,在three.js中不止这些材质,因为这四种材质的用法相似,故放在一起讲解,其他材质将放到后面的文章来单独讲解。

本节将结合一个示例讲解,交互界面如下图其运行效果如下:




材质的共同属性

这些材质都有一些共同的属性



融合属性



高级属性



MeshBasicMaterial(网格基础材质)

网格基础材质是一种比较简单的网格材质,其不考虑场景中光照的影响。这种材质的网格会被渲染成简单的平面多边形,而且也可显示几何线框,以本节例子为主,创建一个球,其代码的创建方式为:
 
  
var sphereMat = new THREE.MeshBasicMaterial({//创建基础材质
color: 0x990000 ,
    wireframe:false,
    opacity:0.5,
    transparent:false});

MeshDepthMaterial(网格深度材质)

使用这种材质的物体,其外光完全不受光照的或某个材质属性决定,而是由物体到相机的距离决定的。而这两种材质只有以下两个控制线框的属性:


这种材质的代码创建方式为:
 
  
var sphereMat = new THREE.MeshDepthMaterial({//创建深度材质
color: 0x990000 ,
    wireframe:false,
    opacity:0.5,
    transparent:false});

MeshLambertMaterial(网格朗伯特材质)

这种材质可以创建对光照有反应的表面,呈现暗淡且不光亮。 其代码创建方式如下:
 
  
 
  
var sphereMat = new THREE.MeshLambertMaterial({//创建朗伯特材质
color: 0x990000 ,
    wireframe:false,
    opacity:0.5,
    transparent:false});


MeshPhoneMaterial(网格冯式材质)

这是一种可以创建光亮表面的材质。其代码创建方式如下所示:
 
  
var sphereMat = new THREE.MeshPhongMaterial({//创建phong材质
color: 0x990000 ,
    wireframe:false,
    opacity:0.5, 
   transparent:false});

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>threejs-basic-material</title>
    <style>
        body{
            font-family: Monospace;
            background: #f0f0f0;
            margin: 0px;
            overflow: hidden;
        }
    </style>
</head>
<body>
<script type="text/javascript" src="build/three.js"></script>
<script type="text/javascript" src="js/Detector.js"></script>
<script type="text/javascript" src="js/libs/dat.gui.min.js"></script>
<script type="text/javascript">
    //检测webgl的支持情况
    if(!Detector.webgl) {Detector.addGetWebGLMessage();}
    var container;
    var scene, camera, renderer;
    var sphereMesh,sphereGeo,sphereMat;
    main();
    render();
    function main(){
        //添加一个div元素
        container = document.createElement('div');
        document.body.appendChild(container);
        scene = new THREE.Scene();//创建新场景
        //添加一个透视相机
        camera = new THREE.PerspectiveCamera(30,
            window.innerWidth/window.innerHeight, 1, 1000);
        camera.position.set(100, 300, 100);//设置相机位置
        camera.lookAt(new THREE.Vector3(0,0,0));//让相机指向原点
        //渲染
        //antialias:true增加抗锯齿效果
        renderer = new THREE.WebGLRenderer({antialias:true});
        renderer.setClearColor(new THREE.Color(0x3399CC));//设置窗口背景颜色为黑
        renderer.setSize(window.innerWidth, window.innerHeight);//设置窗口尺寸
        //将renderer关联到container,这个过程类似于获取canvas元素
        container.appendChild(renderer.domElement);
        //给场景添加光源
        //自然光
        var ambientLight = new THREE.AmbientLight( 0x606060 );
        scene.add( ambientLight );
        //平行光源
        var directionalLight = new THREE.DirectionalLight( 0xffffff );
        directionalLight.position.set( 1, 1.75, 0.5 ).normalize();
        scene.add( directionalLight );
        sphere();
    }
    var controls = new function (){//添加控制因素
        this.材质 = false;
        this.透明度 = sphereMat.opacity;
        this.是否透明 = sphereMat.transparent;
    };
     var gui = new dat.GUI();//创建右侧菜单栏
     gui.add(controls, '材质',["网格基础材质", "网格深度材质", "网格朗伯特材质",
             "网格phong式材质"]).onChange(function (e) {
         switch (e){
             case "网格基础材质":
                 scene.remove(sphereMesh);//移除之前创建的sphereMesh
                 sphereGeo = new THREE.SphereGeometry(40,60,60);
                 sphereMat = new THREE.MeshBasicMaterial({//创建基础材质
                     color:0x990000,
                     wireframe:false,
                     opacity:0.5,
                     transparent:false
                 });
                 sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
                 scene.add(sphereMesh);
                 break;
             case "网格深度材质":
                 scene.remove(sphereMesh);
                 sphereGeo = new THREE.SphereGeometry(40,60,60);
                 sphereMat = new THREE.MeshDepthMaterial({//创建深度材质
                     color:0x990000,
                     wireframe:false,
                     opacity:0.5,
                     transparent:false
                 });
                 sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
                 scene.add(sphereMesh);
                 break;
             case "网格朗伯特材质":
                 scene.remove(sphereMesh);
                 sphereGeo = new THREE.SphereGeometry(40,60,60);
                 sphereMat = new THREE.MeshLambertMaterial({//创建朗伯特材质
                     color:0x990000,
                     wireframe:false,
                     opacity:0.5,
                     transparent:false
                 });
                 sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
                 scene.add(sphereMesh);
                 break;
             case  "网格phong式材质":
                 scene.remove(sphereMesh);
                 sphereGeo = new THREE.SphereGeometry(40,60,60);
                 sphereMat = new THREE.MeshPhongMaterial({//创建phong材质
                     color:0x990000,
                     wireframe:false,
                     opacity:0.5,
                     transparent:false
                 });
                 sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
                 scene.add(sphereMesh);
                 break;
         }
     });
     gui.add(controls,'透明度', 0, 1).onChange(function (e) {
         sphereMat.opacity = e;
     });
     gui.add(controls, '是否透明').onChange(function (e) {
         sphereMat.transparent = e;
     });
    //创建一个球体
    function sphere(){
        sphereGeo = new THREE.SphereGeometry(40,60,60);//创建球体
        sphereMat = new THREE.MeshBasicMaterial({//创建材料
            color:0x660000,
            wireframe:false,
            opacity:0.5
        });
        sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);//创建球体网格模型
        sphereMesh.position.set(0, 0, 0);//设置球体的坐标
        scene.add(sphereMesh);//将球体添加到场景中
    }
    function render(){
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }
</script>
</body>
</html>








猜你喜欢

转载自blog.csdn.net/qq_37338983/article/details/78626338