three.js 纹理贴图的使用

news2024/11/24 1:00:51

 刚刚入门的小伙伴请先查看 three.js 基础认识与简单应用

本文章中的两个注意点,下面也有提到,分别是:

1、  vue项目中使用的贴图路径-->需要把 static文件夹 放到 public文件夹下,并使用 static 开头绝对路径

2、使用环境遮挡贴图时,必须要给物体对象添加第二组uv,否则不起作用

        下面就用一个个例子来分析一下每张贴图的作用与效果,每个功能的讲解都在“主要代码”中的注释上展示,不要看着内容很多,很多代码都是重复的,为了便于大家和后期我查看笔记时理解。

一、使用方法与注意点(以颜色贴图为例):  

使用纹理贴图的第一步就是导入,three.js专门提供了纹理加载函数THREE.TextureLoader()

var texture = new THREE.TextureLoader().load (

        url : String,

        onLoad : Function,

        onProgress : Function,

        onError : Function

) 

代码示例(官方)

const texture = new THREE.TextureLoader().load(
    'textures/land_ocean_ice_cloud_2048.jpg'
);

// 立即使用纹理进行材质创建
const material = new THREE.MeshBasicMaterial( { map: texture } );

Code Example with Callbacks

// 初始化一个加载器
const loader = new THREE.TextureLoader();

// 加载一个资源
loader.load(
	// 资源URL
	'textures/land_ocean_ice_cloud_2048.jpg',

	// onLoad回调
	function ( texture ) {
		// in this example we create the material when the texture is loaded
		const material = new THREE.MeshBasicMaterial( {
			map: texture
		 } );
	},

	// 目前暂不支持onProgress的回调
	undefined,

	// onError回调
	function ( err ) {
		console.error( 'An error happened.' );
	}
);

 **PS**:vue项目中需要把 static文件夹 放到 public文件夹下,并使用 static 开头绝对路径。如下图:

二、颜色贴图

主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");

/*
 *  添加物体
 */
// 创建几何体对象
const cubeGeometry = new THREE.BoxBufferGeometry(2, 2, 2);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 映射到材质上的贴图--颜色贴图
});
// 添加到网格中 = 对象 + 材质
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);
scene.add(cube);

示例一:颜色贴图完整代码

/*
 * @Description: 导入纹理贴图-初始材质和纹理
 */

import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");

/*
 *  添加物体
 */
// 创建几何体对象
const cubeGeometry = new THREE.BoxBufferGeometry(2, 2, 2);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 映射到材质上的贴图--颜色贴图
});
// 添加到网格中 = 对象 + 材质
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);
scene.add(cube);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真实效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
controls.autoRotate = true; // 相机是否自动旋转
controls.autoRotateSpeed = 3; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

  这是一张静态图片,动态效果自己运行一下就能出现啦!

三、纹理贴图常用属性

主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");

/* 纹理-偏移 */
// doorColorTexture.offset.x = 0.5;
// doorColorTexture.offset.y = 0.5;
// 或者
// doorColorTexture.offset.set(0.5, 0.5);

/* 纹理-旋转 */
// 设置旋转的原点--(0.5, 0.5)对应纹理的正中心
// doorColorTexture.center.set(0.5, 0.5);
// // 旋转45deg
// doorColorTexture.rotation = Math.PI / 4;

/* 纹理-重复 */
doorColorTexture.repeat.set(2, 3);
// 设置纹理重复的模式
doorColorTexture.wrapS = THREE.MirroredRepeatWrapping; // 镜像重复
doorColorTexture.wrapT = THREE.RepeatWrapping;

示例:贴图常用属性完整代码:

/*
 * @Description: 纹理贴图常用属性
 */
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");

console.log(doorColorTexture);
/* 纹理-偏移 */
// doorColorTexture.offset.x = 0.5;
// doorColorTexture.offset.y = 0.5;
// 或者
// doorColorTexture.offset.set(0.5, 0.5);

/* 纹理-旋转 */
// 设置旋转的原点--(0.5, 0.5)对应纹理的正中心
// doorColorTexture.center.set(0.5, 0.5);
// // 旋转45deg
// doorColorTexture.rotation = Math.PI / 4;

/* 纹理-重复 */
doorColorTexture.repeat.set(2, 3);
// 设置纹理重复的模式
doorColorTexture.wrapS = THREE.MirroredRepeatWrapping; // 镜像重复
doorColorTexture.wrapT = THREE.RepeatWrapping;

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图到材质 --颜色贴图
});
// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);
scene.add(cube);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
// 相机是否自动旋转
controls.autoRotate = true;
controls.autoRotateSpeed = 3; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

这是一张静态图片,动态效果自己运行一下就能出现啦! 

四、透明(灰度)纹理 

主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 灰度(透明)贴图
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({

  color: "#ffff00",

  map: doorColorTexture, // 添加纹理贴图到材质 --颜色贴图

  // alpha贴图是一张灰度纹理
  // 用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)
  // 注意:配合transparent:true,一起使用
  alphaMap: doorAlphaTexture, 

  transparent: true, // 开启透明

  opacity: 0.6, // 注意:transparent: true,开启后可使用
  
  // 定义将要渲染哪一面(用于控制贴图贴的地方)
  // 正面(FrontSide),背面(BackSide)或两者(DoubleSide)
  // side: THREE.FrontSide, 
  side: THREE.DoubleSide, 
});

// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);
scene.add(cube);

 示例:透明纹理完整代码:

/*
 * @Description: 透明材质与透明纹理
 */
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图到材质 --颜色贴图
  // alpha贴图是一张灰度纹理,
  // 用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)  
  // 注意:配合transparent:true,一起使用
  alphaMap: doorAlphaTexture, 
  transparent: true, // 开启透明
  opacity: 0.6, // 注意:transparent: true,开启后可使用
  // 定义将要渲染哪一面(用于控制贴图贴的地方) 
  // 正面(FrontSide),背面(BackSide)或两者(DoubleSide)
  // side: THREE.FrontSide, 
  side: THREE.DoubleSide,
});
// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);
scene.add(cube);

// 添加平面
const plane = new THREE.Mesh(
  new THREE.PlaneBufferGeometry(3, 3),
  basicMaterial
);
plane.position.set(5, 0, 0);
scene.add(plane);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

  这是一张静态图片,动态效果自己运行一下就能出现啦! 

五、环境遮挡贴图与强度

 PS: 必须要给物体对象添加第二组uv,否则不起作用

主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  // alpha贴图是一张灰度纹理,
  // 用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)
  // 注意:配合transparent:true,一起使用
  alphaMap: doorAlphaTexture, 
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。
});

// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);

// 给立方体设置第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
scene.add(cube);

示例:环境遮挡贴图完整代码:

/*
 * @Description: 环境遮挡贴图与强度--要添加第二组uv
 */
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  // alpha贴图是一张灰度纹理,
  // 用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)
  // 注意:配合transparent:true,一起使用
  alphaMap: doorAlphaTexture, 
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。
});
// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);
// 给立方体设置第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
scene.add(cube);

// 添加平面
const planeGeometry = new THREE.PlaneBufferGeometry(3, 3);
const plane = new THREE.Mesh(planeGeometry, basicMaterial);
plane.position.set(5, 0, 0);
// 给平面设置第二组uv
planeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(planeGeometry.attributes.uv.array, 2)
);
scene.add(plane);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
// controls.autoRotate = true;
// controls.autoRotateSpeed = 2; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

六、displacementMap--置换(位移)贴图与顶点细分设置--要给几何体设置点数属性

主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 透明材质与透明纹理贴图--实现只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");

/*
 *  添加物体
 */
// 创建几何体--给几何体设置点数属性
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  // alpha贴图是一张灰度纹理
  // 用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)
  // 注意:配合transparent:true,一起使用
  alphaMap: doorAlphaTexture, 
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 置换(位移)贴图
  displacementScale: 0.25, // 设置最大突出5公分
});

 示例:置换(位移)贴图完整代码:

/*
 * @Description: displacementMap--置换(位移)贴图与顶点细分设置--要给几何体设置点数属性
 */
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 透明材质与透明纹理贴图--实现只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");

/*
 *  添加物体
 */
// 创建几何体--给几何体设置点数属性
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  alphaMap: doorAlphaTexture,
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 置换(位移)贴图
  displacementScale: 0.25, // 设置最大突出5公分
});
// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, material);
// 给立方体设置第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
scene.add(cube);

// 添加平面--给几何体设置点数属性
const planeGeometry = new THREE.PlaneBufferGeometry(3, 3, 200, 200);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(5, 0, 0);
// 给平面设置第二组uv
planeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(planeGeometry.attributes.uv.array, 2)
);
scene.add(plane);

/**
 * 灯光
 */
// 环境光
const light = new THREE.AmbientLight(0xffffff);
scene.add(light);
// 直线光源(平行光)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置平行光的位置
directionalLight.position.set(10, 10, 10);
scene.add(directionalLight);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
controls.autoRotate = true;
controls.autoRotateSpeed = 5; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

七、roughness--设置粗糙度与粗糙度 

 主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图--实现只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");
// 导入粗糙度贴图--实现金属反光,门是完全漫反射(不反光)
const roughnessTexture = textureLoader.load(
  "static/textures/door/roughness.jpg"
);

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  alphaMap: doorAlphaTexture, 
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 唯置换(位移)贴图
  displacementScale: 0.1, // 设置最大突出5公分

  // 材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。
  // 如果还提供roughnessMap,则两个值相乘。
  roughness: 1,
  roughnessMap: roughnessTexture,
});

 示例:粗糙贴图完整代码:

/*
 * @Description: .roughness--设置粗糙度与粗糙度贴图
 */
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图--实现只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");
// 导入粗糙度贴图--实现金属反光,门是完全漫反射(不反光)
const roughnessTexture = textureLoader.load(
  "static/textures/door/roughness.jpg"
);

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  alphaMap: doorAlphaTexture,
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 置换(位移)贴图
  displacementScale: 0.1, // 设置最大突出5公分

  // 材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。
  // 如果还提供roughnessMap,则两个值相乘。
  roughness: 1,
  roughnessMap: roughnessTexture,
});
// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, material);
// 给立方体设置第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
scene.add(cube);

// 添加平面
const planeGeometry = new THREE.PlaneBufferGeometry(3, 3, 200, 200);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(5, 0, 0);
// 给平面设置第二组uv
planeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(planeGeometry.attributes.uv.array, 2)
);
scene.add(plane);

/**
 * 灯光
 */
// 环境光
const light = new THREE.AmbientLight(0xffffff);
scene.add(light);
// 直线光源(平行光)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置平行光的位置
directionalLight.position.set(10, 10, 10);
scene.add(directionalLight);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
// controls.autoRotate = true;
// controls.autoRotateSpeed = 2; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

八、metalness--设置金属度与金属贴图

主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图--实现只只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");
// 导入粗糙度贴图--实现金属反光,门是完全漫反射(不反光)
const roughnessTexture = textureLoader.load(
  "static/textures/door/roughness.jpg"
);
// 导入金属贴图-实现金属贴图
const metalnessTexture = textureLoader.load(
  "static/textures/door/metalness.jpg"
);

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  alphaMap: doorAlphaTexture, 
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 唯置换(位移)贴图
  displacementScale: 0.1, // 设置最大突出5公分

  // 材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。如果还提供roughnessMap,则两个值相乘。
  roughness: 1,
  roughnessMap: roughnessTexture,

  // 金属度
  // 材质与金属的相似度。
  // 非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 
  // 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。
  // 如果还提供了metalnessMap,则两个值相乘。
  metalness: 1,
  metalnessMap: metalnessTexture,
});

 示例代码:金属贴图完整代码:

/*
 * @Description:    标准网格材质(MeshStandardMaterial)--.metalness--设置金属度与金属贴图
 */
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图--实现只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");
// 导入粗糙度贴图--实现金属反光,门是完全漫反射(不反光)
const roughnessTexture = textureLoader.load(
  "static/textures/door/roughness.jpg"
);
// 导入金属贴图-实现金属贴图
const metalnessTexture = textureLoader.load(
  "static/textures/door/metalness.jpg"
);

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  alphaMap: doorAlphaTexture,
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 置换(位移)贴图
  displacementScale: 0.1, // 设置最大突出5公分

  // 材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。
  //如果还提供roughnessMap,则两个值相乘。
  roughness: 1,
  roughnessMap: roughnessTexture,

  // 金属度
  // 材质与金属的相似度。
  // 非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 
  // 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。
  // 如果还提供了metalnessMap,则两个值相乘。
  metalness: 1,
  metalnessMap: metalnessTexture,
});
// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, material);
// 给立方体设置第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
scene.add(cube);

// 添加平面
const planeGeometry = new THREE.PlaneBufferGeometry(3, 3, 200, 200);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(5, 0, 0);
// 给平面设置第二组uv
planeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(planeGeometry.attributes.uv.array, 2)
);
scene.add(plane);

/**
 * 灯光
 */
// 环境光
const light = new THREE.AmbientLight(0xffffff);
scene.add(light);
// 直线光源(平行光)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置平行光的位置
directionalLight.position.set(10, 10, 10);
scene.add(directionalLight);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
// controls.autoRotate = true;
// controls.autoRotateSpeed = 2; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

九、normalMap--法线贴图的应用

主要代码:

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图--实现只只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");
// 导入粗糙度贴图--实现金属反光,门是完全漫反射(不反光)
const roughnessTexture = textureLoader.load(
  "static/textures/door/roughness.jpg"
);
// 导入金属贴图-实现金属贴图
const metalnessTexture = textureLoader.load(
  "static/textures/door/metalness.jpg"
);
// 导入法线贴图-改变光照-这里会发现光照照到门缝(凹凸不平的部分)有阴影效果
const normalTexture = textureLoader.load("static/textures/door/normal.jpg");

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  alphaMap: doorAlphaTexture,
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 置换(位移)贴图
  displacementScale: 0.1, // 设置最大突出5公分

  // 材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。
  // 如果还提供roughnessMap,则两个值相乘。
  roughness: 1,
  roughnessMap: roughnessTexture,

  // 材质与金属的相似度。
  // 非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 
  // 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。
  // 如果还提供了metalnessMap,则两个值相乘。
  metalness: 1,
  metalnessMap: metalnessTexture,

  // 用于创建法线贴图的纹理。
  // RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。
  // 法线贴图不会改变曲面的实际形状,只会改变光照。
  normalMap: normalTexture,
});

 示例:法线贴图完整代码:

/*
 * @Description: normalMap--法线贴图的应用
 */
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(5, 5, 5);
scene.add(camera); // 将相机添加到场景中

/**
 * 导入纹理贴图
 */
// 设置纹理加载器
const textureLoader = new THREE.TextureLoader();
// 注意:vue项目中需要把static文件夹放到public文件夹下,并使用static开头的绝对路径
// 颜色贴图
const doorColorTexture = textureLoader.load("static/textures/door/color.jpg");
// 实现透明材质与透明纹理贴图--实现只只显示门
const doorAlphaTexture = textureLoader.load("static/textures/door/alpha.jpg");
// AO环境贴图遮挡--环境光强度控制--实现门框线的颜色深度
const doorAoTexture = textureLoader.load(
  "static/textures/door/ambientOcclusion.jpg"
);
// 导入置换(位移)贴图-实现门体突出
const doorHeightTexture = textureLoader.load("static/textures/door/height.jpg");
// 导入粗糙度贴图--实现金属反光,门是完全漫反射(不反光)
const roughnessTexture = textureLoader.load(
  "static/textures/door/roughness.jpg"
);
// 导入金属贴图-实现金属贴图
const metalnessTexture = textureLoader.load(
  "static/textures/door/metalness.jpg"
);
// 导入法线贴图-改变光照-这里会发现光照照到门缝(凹凸不平的部分)有阴影效果
const normalTexture = textureLoader.load("static/textures/door/normal.jpg");

/*
 *  添加物体
 */
// 创建几何体
const cubeGeometry = new THREE.BoxBufferGeometry(3, 3, 3, 100, 100, 100);
// 材质--标准网络材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture, // 添加纹理贴图
  alphaMap: doorAlphaTexture,
  transparent: true, // 开始透明
  // opacity: 0.5, // 注意:transparent: true,开启后可使用
  side: THREE.DoubleSide, //定义将要渲染哪一面 - 正面,背面或两者

  aoMap: doorAoTexture, // 环境遮挡贴图,aoMap需要第二组UV。
  // aoMapIntensity: 3, // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。

  displacementMap: doorHeightTexture, // 置换(位移)贴图
  displacementScale: 0.1, // 设置最大突出5公分

  // 材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。
  // 如果还提供roughnessMap,则两个值相乘。
  roughness: 1,
  roughnessMap: roughnessTexture,

  // 材质与金属的相似度。
  // 非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 
  // 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。
  //如果还提供了metalnessMap,则两个值相乘。
  metalness: 1,
  metalnessMap: metalnessTexture,

  // 用于创建法线贴图的纹理。
  // RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。
  // 法线贴图不会改变曲面的实际形状,只会改变光照。
  normalMap: normalTexture,
});
// 添加到网格中
const cube = new THREE.Mesh(cubeGeometry, material);
// 给立方体设置第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
scene.add(cube);

// 添加平面
const planeGeometry = new THREE.PlaneBufferGeometry(3, 3, 200, 200);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(5, 0, 0);
// 给平面设置第二组uv
planeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(planeGeometry.attributes.uv.array, 2)
);
scene.add(plane);

/**
 * 灯光
 */
// 环境光
const light = new THREE.AmbientLight(0xffffff);
scene.add(light);
// 直线光源(平行光)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置平行光的位置
directionalLight.position.set(10, 10, 10);
scene.add(directionalLight);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
// controls.autoRotate = true;
// controls.autoRotateSpeed = 2; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/392845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Air780E|阿里云|AT命令|物联网|三元组|鉴权|算法|密钥生成-阿里云物联网手动接入步骤

基础资料基于Air780E开发板:Air780E文档中心简介:AT开发探讨重点本系列主要探讨MQTT手动接入腾讯云物理网平台的基本操作及手动鉴权步骤、信息订阅及发布的基本原理。参考阅读:物联网模组AT命令接入云平台(1)-MQTT基本…

移动硬盘怎么恢复数据?怎么恢复硬盘删除的数据

移动硬盘可以随时插上或拔下,小巧而便于携带的硬盘存储器,以较高的速度与系统进行数据传输。由于其存储空间较大,性价比较高,存储和传输数据快速简便,是很多职场人士必备的外置设备之一。移动硬盘怎么恢复数据&#xf…

cuda代码高效策略--b站看课的笔记

1.1 高效公式 要么增大数据量,要么减少每个线程的内存(每个线程读取的数据量变少,每个线程的读取数据的速度变快(转变存储方式,对读取慢的地方做优化–合并全局内存)) 1.2 合并全局内存 一个线…

电子台账:模板制作之二——行过滤(垂直过滤)

1 简介大部分情况下,企业数据源表格中,只有部分行的数据可用于电子台账。例如,一共100行数据,我们只要取得其中20行即可。如果所有数据一股脑全部导入到台账中,再手工删除不需要的行,太麻烦了,有…

js变量和函数提升

1、变量提升 变量提升是JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问 (仅存在于var声明变量) 注意: 1.变量在未声明即被访问时会报语法错误 2.变量在var声明之前即被访问,变量的值为 undefined 3.let/const声明的变量不存在变量提升…

sqli-labs通关lesson36-40

1.lesson36 union select判断注入:为单引号注入?id1%df-- 查数据库:?id-1%df union select 1,2,database()-- 2.lesson-37 报错注入判断注入:为单引号注入通过下方判断password为单引号注入unamez&passwdg%df -- &submitSubmit查数…

神经网络之反向传播算法(自适应梯度算法Adagrad)

文章目录自适应梯度算法(Adagrad)1、算法原理2、算法实现2.1 训练过程2.2 测试过程及结果3、参考源码及数据集自适应梯度算法(Adagrad) 自适应梯度算法(Adaptive gradient algorithm,Adagrad)与…

惊!初中生也来卷了……

大家好,我是良许。 前两天在抖音直播的时候,突然来了一位不速之客…… 他自称是初中生,一开始我还有点不太相信,直到跟他连麦,听到他还略带一些稚嫩的声音,我才知道,他没有骗我…… 他说他想学…

Dynamic Movement Primitives (DMP) 学习

Dynamic Movement Primitives (DMP) 学习 【知乎】Dynamic Movement Primitives介绍及Python实现与UR5机械臂仿真 1. DMP的建模过程 链接:Dynamic Movement Primitives介绍及Python实现与UR5机械臂仿真 - 知乎 (zhihu.com) 沙漏大佬!!&am…

转行软件测试需要学习哪些知识点?来来来,都给你汇总在这里啦!

都说IT互联网行业吃香,那么如何才能高效转行,习得一技之长换取心仪offer? 一般来说,0基础小白想转行到软件测试行业,按照如下学习逻辑肯定是错不了的: 1.零基础小白入门篇(学前扫盲&#xff09…

ThinkBook15电脑开机后马上蓝屏不能使用怎么办?

ThinkBook15电脑开机后马上蓝屏不能使用怎么办?最近有用户使用的ThinkBook15电脑出现了开机之后屏幕蓝屏的情况。出现这个问题,是系统底层的故障,一般用户很难找出问题进行彻底解决。但是我们可以通过以下重做系统的方法来恢复电脑系统的使用…

阶段二11_面向对象高级_学生管理系统案例3

主要功能: 完成学生信息添加,修改和删除功能。 一.查看学生 思路: 图片:5_查看学生思路图.png 代码: StudentController[客服类中] //查找学生 private void findAllStudent() {//1.方法内部创建StudentService业…

Nacos 使用Postgresql数据库制作镜像

构建前提在 Nacos 2.2.0支持postgresql数据库基础上进行构建github地址:个人仓库编译打包源码mvn -Prelease-nacos clean package install -Dmaven.test.skiptrue若想跳过pmd和checkstyle检查请使用mvn -Prelease-nacos clean package install -Dmaven.test.skiptru…

Vue 3.0 组合式API 介绍 【Vue3 从零开始】

提示 在阅读文档之前,你应该已经熟悉了这两个 Vue 基础和创建组件。 在 Vue Mastery 上观看关于组合式 API 的免费视频。 通过创建 Vue 组件,我们可以将接口的可重复部分及其功能提取到可重用的代码段中。仅此一项就可以使我们的应用程序在可维护性和…

SAP ERP系统PP模块计划策略2050详解

SAP/ERP系统中面向订单生产的计划策略主要有20和50两个策略,这两个策略都是面向订单生产的计划策略,也是离散制造行业应用比较广泛的策略。它们之间最大差异就是在于20策略完全是由订单驱动,而50策略是预测加订单驱动,本文主要介绍…

【Leetcode 剑指Offer】第 14 天 搜索与回溯算法(中等)

文章目录剑指 Offer 12. 矩阵中的路径DFS剪枝面试题13. 机器人的运动范围剑指 Offer 12. 矩阵中的路径 典型矩阵搜索题 DFS剪枝 深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上…

实现迭代回声服务器端/客户端

文章目录1.迭代服务器端/客户端2.迭代回声服务器端/客户端2.1 echo_server.c2.2 echo_client.c3.回声客户端存在的问题4.回声客户端问题解决方法1.迭代服务器端/客户端 之前讨论的 HelloWorld 服务器端处理完 111 个客户端连接请求即退出,连接请求等待队列实际没有…

唯品会盈利十年:韧性有余,冲劲不足

配图来自Canva可画唯品会在电商市场是一个特殊的存在,从2012年第四季度首次盈利至今,唯品会已经连续十年保持盈利。这十年,电商产业逐渐走向成熟,电商玩家新老接替成层出不穷,曾经家喻户晓的蘑菇街、聚美优品、苏宁易购…

Vue2.0开发之——购物车案例-Goods组件封装-商品数量的加减及总数量(53)

一 概述 Goods点击加减实现修改数量的原理Goods点击增加实现实例Goods点击-减少实现实例Footer计算商品总数量 二 Goods点击加减实现修改数量的原理 点击Counter组件里面的加减,修改Counter组件里面的数量Counter组件的数量变化时,Goods商品的数量相应…

leetcode-每日一题-807(中等,数组)

正常情况第一眼看这道题,看懂意思的话很简单就可以解出来。给你一座由 n x n 个街区组成的城市,每个街区都包含一座立方体建筑。给你一个下标从 0 开始的 n x n 整数矩阵 grid ,其中 grid[r][c] 表示坐落于 r 行 c 列的建筑物的 高度 。城市的…