學習Three.js——紋理(Texture)
一般使用THREE.ImageUtils.loadTexture(img_path)
將影象載入為紋理,然後將紋理賦給材質的map屬性,
其中我們可以選擇紋理放大和縮小使用的插值演算法。
THREE.NearestFilter
、THREE.LinearFilter
、THREE.NearestMipMapNearestFilter
、THREE.NearestMipMapLinearFilter
、THREE.LinearMipMapNearestFilter
和THREE.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);
}