ThreeJS中的纹理


参考:https://threejs.org/open in new window

纹理的使用

  • map:漫反射纹理,用于指定材质的baseColor,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • alphaMap:透明度纹理,用于指定材质的透明度,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • bumpMap:凹凸贴图,可以再次深化材质的表面,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • normalMap:法线贴图,可以为表面增加微妙的细节,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • specularMap:镜面反射贴图,用于指定材质的specular,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • displacementMap:高度图或位移贴图,用于模拟表面物体位移,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • roughnessMap:粗糙度贴图,可以模拟表面的粗糙程度,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • metalnessMap:金属度贴图,用于指定表面的金属部分,可以是THREE.Texture类型的实例对象。默认值为undefined。
  • envMap:环境贴图,用于模拟环境反射,可以是THREE.Texture类型的实例对象或CubeTexture类型的实例对象。默认值为undefined。
const loader = new THREE.TextureLoader();
 
const material = new THREE.MeshBasicMaterial({
  color: 0xFF8844,
  map: loader.load('resources/images/wall.jpg'),
});

// 创建一个基础材质对象
const basicMaterial = new THREE.MeshBasicMaterial({
  // 设置材质的颜色为黄色
  color: "#ffff00",
  // 设置映射纹理为门的颜色纹理
  map: doorColorTexture,
  // 设置门透明度的纹理贴图
  alphaMap: doorAplhaTexture,
  // 允许材质的透明度被纹理影响
  transparent: true,
  // 设置环境遮挡纹理为门的AO纹理
  aoMap: doorAoTexture,
  // 设置AO纹理影响的强度系数
  aoMapIntensity: 1,
  // 设置门的高度贴图纹理用于使门产生凸起效果
  displacementMap: doorHeightTexture,
  // 设置凸起效果的缩放系数,值越高凸起越明显
  displacementScale: 0.1,
  // 设置材质的粗糙度为1
  roughness: 1,
  // 设置粗糙度对应的纹理贴图
  roughnessMap: roughnessTexture,
  // 设置金属度为1
  metalness: 1,
  // 设置金属度对应的纹理贴图
  metalnessMap: metalnessTexture,
  // 设置法线贴图用于制作凹凸效果
  normalMap: normalTexture,
  // 设置材质的透明度,可以通过alphaMap实现这一效果
  // opacity: 0.3,
  // 设置材质的两侧都能被渲染
  side: THREE.DoubleSide,
});
/*
在 Three.js 中,当我们需要对平面几何体进行细分(Subdivision)或进行 Parallax Mapping(视差贴图)时,为了维持高质量的视觉效果,会用到 uv2 属性。
将 uv 属性的值复制给 uv2 属性,就能够在平面几何体进行细分或者 Parallax Mapping 操作时,避免贴图失真产生的模糊或锯齿效果。
这种做法的原理是:在进行细分或 Parallax Mapping 时,需要利用旧的UV映射坐标计算新的UV映射坐标,而复制了一遍的 uv2 属性就可以提供旧的UV映射坐标了。
*/
planeGeometry.setAttribute(
"uv2",
new THREE.BufferAttribute(planeGeometry.attributes.uv.array, 2)
);

doorColorTexture
doorAplhaTexture
doorAoTexture
doorHeightTexture
roughnessTexture
metalnessTexture
normalTexture

纹理的加载

const loader = new THREE.TextureLoader();
// 1
const texture = loader.load('resources/images/flower-1.jpg');
// 2
loader.load('resources/images/wall.jpg', (texture) => {
  const material = new THREE.MeshBasicMaterial({
    map: texture,
  });
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);
  cubes.push(cube);  // 添加到我们要旋转的立方体数组中
});

多个纹理的加载(LoadingManager)

const loadManager = new THREE.LoadingManager();
const loader = new THREE.TextureLoader(loadManager);
 
const materials = [
  new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-1.jpg')}),
  new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-2.jpg')}),
  new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-3.jpg')}),
  new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-4.jpg')}),
  new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-5.jpg')}),
  new THREE.MeshBasicMaterial({map: loader.load('resources/images/flower-6.jpg')}),
];
 
loadManager.onLoad = () => {
  const cube = new THREE.Mesh(geometry, materials);
  scene.add(cube);
  cubes.push(cube);  // 添加到我们要旋转的立方体数组中
};

设置纹理加载进度

let event = {};
event.onLoad = function () {
  console.log("图片加载完成");
};
event.onProgress = function (url, num, total) {
  console.log("图片加载完成:", url);
  console.log("图片加载进度:", num);
  console.log("图片总数:", total);
  let value = ((num / total) * 100).toFixed(2) + "%";
  console.log("加载进度的百分比:", value);
  div.innerHTML = value;
};
event.onError = function (e) {
  console.log("图片加载出现错误");
  console.log(e);
};
// 设置加载管理器
const loadingManager = new THREE.LoadingManager(
  event.onLoad,
  event.onProgress,
  event.onError
);

filtering过滤

mips

Mips 是纹理的副本,每一个都是前一个 mip 的一半宽和一半高,其中的像素已经被混合以制作下一个较小的 mip。Mips一直被创建,直到我们得到1x1像素的Mip。对于上面的图片,所有的Mip最终会变成这样的样子

当立方体被画得很小,只有1或2个像素大时,GPU可以选择只用最小或次小级别的mip来决定让小立方体变成什么颜色。

magFilter

当一个纹素覆盖大于一个像素时,贴图将如何采样。

  • 默认值为THREE.LinearFilter, 指从纹理中选择离我们应该选择颜色的地方最近的4个像素,并根据实际点与4个像素的距离,以适当的比例进行混合。
  • 另一个选项是THREE.NearestFilter,只需从原始纹理中选取最接近的一个像素。

minFilter

当一个纹素覆盖小于一个像素时,贴图将如何采样。默认值为THREE.LinearMipmapLinearFilter, 它将使用mipmapping以及三次线性滤镜。

  • THREE.NearestFilter在纹理中选择最近的像素。

  • THREE.LinearFilter从纹理中选择4个像素,然后混合它们

  • THREE.NearestMipmapNearestFilter选择合适的mip,然后选择一个像素。

  • THREE.NearestMipmapLinearFilter选择2个mips,从每个mips中选择一个像素,混合这2个像素。

  • THREE.LinearMipmapNearestFilter选择合适的mip,然后选择4个像素并将它们混合。

  • THREE.LinearMipmapLinearFilter选择2个mips,从每个mips中选择4个像素,然后将所有8个像素混合成1个像素。

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.13.0