Three.js基礎探尋七——Lamber材質與Phong材質


  材質(Material)是獨立於物體頂點信息之外的與渲染效果相關的屬性。通過設置材質可以改變物體的顏色、紋理貼圖、光照模式等。

  本篇將介紹基本材質以及兩種基於光照模型的材質(Lamber與Phong)。

 

  MeshBasicMaterial:對光照無感,給幾何體一種簡單的顏色或顯示線框。

  MeshLambertMaterial:這種材質對光照有反應,用於創建暗淡的不發光的物體。

  MeshPhongMaterial:這種材質對光照也有反應,用於創建金屬類明亮的物體。

 

1.基本材質

  使用基本材質(BasicMaterial)的物體,渲染后物體的顏色始終為該材質的顏色,而不會由於光照產生明暗、陰影效果。如果沒有指定材質的顏色,則顏色是隨機的。其構造函數是:

THREE.MeshLambertMaterial(opt)

  其中,opt可以缺省,或者為包含各屬性的值。如新建一個不透明度為0.75的黃色材質:

new THREE.MeshBasicMaterial({

    color: 0xffff00,

    opacity: 0.75

});

  將其應用於一個正方體(方法參見3.js-4,效果為:

源碼:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>3.js測試7.1</title>
    </head>
    <body onload="init()">
        <canvas id="mainCanvas" width="400px" height="300px" ></canvas>
    </body>
    <script type="text/javascript" src="js/three.min.js"></script>
    <script type="text/javascript">
        function init() {
            var renderer = new THREE.WebGLRenderer({
                canvas: document.getElementById('mainCanvas')
            });
            renderer.setClearColor(0x000000);
            var scene = new THREE.Scene();
            
            // camera
            var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
            camera.position.set(25, 25, 25);
            camera.lookAt(new THREE.Vector3(0, 0, 0));
            scene.add(camera);
            
            // light
            var light = new THREE.PointLight(0xffffff, 1, 100);
            light.position.set(10, 15, 5);
            scene.add(light);
            
            var material = new THREE.MeshBasicMaterial({
                color: 0xffff00,
                opacity: 0.75
            });
            
            var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
            scene.add(cube);
            
            renderer.render(scene, camera);
        }
    </script>
</html>

 

  BasicMaterial的幾個較為常用的屬性:

  · visible:是否可見,默認為true

  · side:渲染面片正面或是反面,默認為正面THREE.FrontSide,可設置為反面THREE.BackSide,或雙面THREE.DoubleSide

  · wireframe:是否渲染線而非面,默認為false

  · color:十六進制RGB顏色,如紅色表示為0xff0000

  · map:使用紋理貼圖

 

  對於基本材質,即使改變場景中的光源,使用該材質的物體也始終為顏色處處相同的效果。當然,這不是很具有真實感,因此,接下來我們將介紹更為真實的光照模型:Lambert光照模型以及Phong光照模型。

 

2.Lamber材質與Phong材質 

  Lambert材質(MeshLambertMaterial)是符合Lambert光照模型的材質。Lambert光照模型的主要特點是只考慮漫反射而不考慮鏡面反射的效果,因而對於金屬、鏡子等需要鏡面反射效果的物體就不適應,對於其他大部分物體的漫反射效果都是適用的。

  其光照模型公式為:

Idiffuse = Kd * Id * cos(theta)

  其中,Idiffuse是漫反射光強,Kd是物體表面的漫反射屬性,Id是光強,theta是光的入射角弧度。

  當然,對於使用Three.js的Lambert材質,不需要了解以上公式就可以直接使用。創建一個黃色的Lambert材質的方法為:

new THREE.MeshLambertMaterial({

    color: 0xffff00

})

  在使用了光照之后,得到這樣的效果:

  color是用來表現材質對散射光的反射能力,也是最常用來設置材質顏色的屬性。除此之外,還可以用ambient和emissive控制材質的顏色。

  ambient表示對環境光的反射能力,只有當設置了AmbientLight后,該值才是有效的,材質對環境光的反射能力與環境光強相乘后得到材質實際表現的顏色。

  emissive是材質的自發光顏色,可以用來表現光源的顏色,並不是一種光源,而是一種不受光照影響的顏色。單獨使用紅色的自發光:

new THREE.MeshLambertMaterial({

    emissive: 0xff0000

})

  效果為:

  如果同時使用紅色的自發光與黃色的散射光:

new THREE.MeshLambertMaterial({

    color: 0xffff00,

    emissive: 0xff0000

})

  效果為:

  球體的效果:

 

  總結Lamber材質的特有屬性:

  ambient:設置材質的環境色,和AmbientLight光源一起使用,這個顏色會與環境光的顏色相乘。即是對光源作出反應。

  emissive:設置材質發射的顏色,不是一種光源,而是一種不受光照影響的顏色。默認為黑色。

 

  源碼:

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>3.js測試7.2</title>
    </head>
    <body onload="init()">
        <canvas id="mainCanvas" width="400px" height="300px" ></canvas>
    </body>
    <script type="text/javascript" src="js/three.min.js"></script> 
    <script type="text/javascript">
        function init() {
            var renderer = new THREE.WebGLRenderer({
                canvas: document.getElementById('mainCanvas')
            });
            renderer.setClearColor(0x000000);
            var scene = new THREE.Scene();
            
            // camera
            var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
            camera.position.set(25, 25, 25);
            camera.lookAt(new THREE.Vector3(0, 0, 0));
            scene.add(camera);
            
            // light
            var light = new THREE.PointLight(0xffffff, 1, 100);
            light.position.set(10, 15, 5);
            scene.add(light);
            
            var material = new THREE.MeshLambertMaterial({
                color: 0xffff00,
                emissive: 0xff0000
            });
            
            var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
            scene.add(cube);

//            var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);
//            scene.add(sphere);
            
            renderer.render(scene, camera);
        }
    </script>
</html>

 

3.phong材質

  Phong材質(MeshPhongMaterial)是符合Phong光照模型的材質。和Lambert不同的是,Phong模型考慮了鏡面反射的效果,因此對於金屬、鏡面的表現尤為適合。

  漫反射部分和Lambert光照模型是相同的,鏡面反射部分的模型為:

Ispecular = Ks * Is * (cos(alpha)) ^ n

  其中,Ispecular是鏡面反射的光強,Ks是材質表面鏡面反射系數,Is是光源強度,alpha是反射光與視線的夾角,n是高光指數,越大則高光光斑越小。

  由於漫反射部分與Lambert模型是一致的,因此,如果不指定鏡面反射系數,而只設定漫反射,其效果與Lambert是相同的:

new THREE.MeshPhongMaterial({

    color: 0xffff00

});

  同樣地,可以指定emissive和ambient值,這里不再說明。下面就specular值指定鏡面反射系數作說明。首先,我們只使用鏡面反射,將高光設為紅色,應用於一個球體:

var material = new THREE.MeshPhongMaterial({

    specular: 0xff0000

});

var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);

  效果為:

  可以通過shininess屬性控制光照模型中的n值,當shininess值越大時,高光的光斑越小,默認值為30。我們將其設置為1000時:

new THREE.MeshPhongMaterial({

    specular: 0xff0000,

    shininess: 1000

});

  效果為:

  使用黃色的鏡面光,紅色的散射光:

material = new THREE.MeshPhongMaterial({

    color: 0xff0000,

    specular: 0xffff00,
    
    shininess: 100

});

  總結Phong材質的特有屬性:

  ambient:設置材質的環境色,和AmbientLight光源一起使用,這個顏色會與環境光的顏色相乘。即是對光源作出反應。

  emissive:設置材質發射的顏色,不是一種光源,而是一種不受光照影響的顏色。默認為黑色

  specular:指定該材質的光亮程度及其高光部分的顏色,如果設置成和color屬性相同的顏色,則會得到另一個更加類似金屬的材質,如果設置成grey灰色,則看起來像塑料

  shininess:指定高光部分的亮度,默認值為30.

 

  源碼:

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>3.js測試7.3</title>
    </head>
    <body onload="init()">
        <canvas id="mainCanvas" width="400px" height="300px" ></canvas>
    </body>
    <script type="text/javascript" src="js/three.min.js"></script>
    <script type="text/javascript">
        function init() {
            var renderer = new THREE.WebGLRenderer({
                canvas: document.getElementById('mainCanvas')
            });
            renderer.setClearColor(0x000000);
            var scene = new THREE.Scene();
            
            // camera
            var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
            camera.position.set(25, 25, 25);
            camera.lookAt(new THREE.Vector3(0, 0, 0));
            scene.add(camera);
            
            // light
            var light = new THREE.PointLight(0xffffff, 1, 200);
            light.position.set(10, 15, 25);
            scene.add(light);
            
            var material = new THREE.MeshPhongMaterial({
//              specular: 0xff0000,
                color: 0xff0000,
                specular: 0xffff00,
                shininess: 100
            });
            
//          var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
//          scene.add(cube);
            
            var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);
            scene.add(sphere);
            
            renderer.render(scene, camera);
        }
    </script>
</html>

 

 

 

  整理自張雯莉《Three.js入門指南》

  其他參考:THREE.JS中常用的3種材質

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM