1. 程式人生 > >學習Three.js——紋理(Texture)

學習Three.js——紋理(Texture)

一般使用THREE.ImageUtils.loadTexture(img_path)將影象載入為紋理,然後將紋理賦給材質的map屬性,

其中我們可以選擇紋理放大和縮小使用的插值演算法。

THREE.NearestFilterTHREE.LinearFilterTHREE.NearestMipMapNearestFilterTHREE.NearestMipMapLinearFilterTHREE.LinearMipMapNearestFilterTHREE.LinearMipMapLinearFilter

詳細說明自行百度。

使用凹凸貼圖建立皺褶

使用凹凸貼圖建立一種新的紋理,將其賦給材質的bumpMap屬性,並調整bumpScale即可獲得凹凸的效果

function createMesh(geom, imageFile, bump) {
            var texture = THREE.ImageUtils.loadTexture("../assets/textures/general/" + imageFile);
            geom.computeVertexNormals();
            var mat = new THREE.MeshPhongMaterial();
            mat.map = texture;

            if (bump) {
                var
bump = THREE.ImageUtils.loadTexture("../assets/textures/general/" + bump); mat.bumpMap = bump; mat.bumpScale = 0.2; console.log('d'); } // create a multimaterial var mesh = new THREE.Mesh(geom, mat); return mesh;
}

使用法向貼圖建立更加細緻的凹凸和皺褶

凹凸貼圖只有高度資訊而沒有斜角的資訊,使用法向貼圖,當光照從側面照過來,可以看到陰影效果

和上面類似,將法向貼圖紋理賦給材質的normalMap屬性即可

function createMesh(geom, imageFile, normal) {

                var t = THREE.ImageUtils.loadTexture("../assets/textures/general/" + imageFile);
                var m = THREE.ImageUtils.loadTexture("../assets/textures/general/" + normal);
                var mat2 = new THREE.MeshPhongMaterial();
                mat2.map = t;
                mat2.normalMap = m;

                var mesh = new THREE.Mesh(geom, mat2);
                return mesh;
            
        }

使用光照貼圖建立陰影效果

簡單地說就是當沒有光線照射的情況下,當物體放置在該網格上時,會產生陰影效果

只需要設定材質的lightMap屬性即可


        var groundMaterial = new THREE.MeshBasicMaterial(
                {
                    color: 0x777777,
                    lightMap: lm,
                    map: wood
                });
		//這個要設定好,暫不知道有什麼用
        groundGeom.faceVertexUvs[1] = groundGeom.faceVertexUvs[0];

使用環境貼圖產生反光效果

使用高光貼圖增強某部分的高光效果,只需要將紋理賦給材質的specularMap屬性並設定specular高光部分的顏色和shininess設定高光的強度即可

function createMesh(geom) {
            var planetTexture = THREE.ImageUtils.loadTexture("../assets/textures/planets/Earth.png");
            var specularTexture = THREE.ImageUtils.loadTexture("../assets/textures/planets/EarthSpec.png");
            var normalTexture = THREE.ImageUtils.loadTexture("../assets/textures/planets/EarthNormal.png");


            var planetMaterial = new THREE.MeshPhongMaterial();
            planetMaterial.specularMap = specularTexture;
            planetMaterial.specular = new THREE.Color(0xff0000);
            planetMaterial.shininess = 2;

            planetMaterial.normalMap = normalTexture;
//            planetMaterial.map = planetTexture;
            //   planetMaterial.shininess = 150;


            // create a multimaterial
            var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [planetMaterial]);

            return mesh;
        }

自定義UV對映

重複紋理

通過設定geometry.material.map.wrapS和geometry.material.map.wrapT來改變x,y軸方向的重複狀態,可以選擇兩種屬性:

THREE.RepeatWrapping:允許紋理重複

THREE.ClampToEdgeWrapping:不允許紋理重複,使用紋理的邊緣填充剩餘部分

可以通過geometry.material.map.repeat.set(repeatX,repeatY)來設定在x,y軸的重複頻率

使用畫布作為紋理

	var canvas = document.createElement("canvas");//建立畫布
    document.getElementById('canvas-output').appendChild(canvas);//新增到html中
    $('#canvas-output').literallycanvas({imageURLPrefix: '../libs/literally/img'});//建立一個可以畫畫的畫布

	function createMesh(geom) {
			//將畫布直接傳入材質的建構函式即可
            var canvasMap = new THREE.Texture(canvas);
            var mat = new THREE.MeshPhongMaterial();
            mat.map = canvasMap;
            var mesh = new THREE.Mesh(geom, mat);

            return mesh;
        }

使用視訊作為紋理

和畫布同理

		//建立視訊紋理並進行一些初始化
		var video = document.getElementById('video');
        texture = new THREE.Texture(video);
        texture.minFilter = THREE.LinearFilter;
        texture.magFilter = THREE.LinearFilter;
        texture.format = THREE.RGBFormat;
        texture.generateMipmaps = false;
		//要對紋理進行更新
		function render() {
            stats.update();


            if (video.readyState === video.HAVE_ENOUGH_DATA) {
                if (texture) texture.needsUpdate = true;
            }

            if (controls.rotate) {
                cube.rotation.x += -0.01;
                cube.rotation.y += -0.01;
                cube.rotation.z += -0.01;
            }


            // render using requestAnimationFrame
            requestAnimationFrame(render);
            webGLRenderer.render(scene, camera);
        }