在 three 中材质大约分三个类,网格材质,线材质,与其他材质,其中线材质主要针对 three 中的线段渲染,而网格材质主要针对的时几何体的渲染,还有其他材质,例如点精录,阴影材质,着色器材质,这些只有在特殊情况才会用到
MeshBasicMaterial 基础网格材质 有 17 个属性
基础网格材质是一种不受光影晌的材质,如果几何体不需要与光做任何交互这种材质是非常合适的一种,在使用alphaMap 时需要注意 开启透明 transparent 设置为 true 才能使纹理透明生效。aoMap需要第二组UV 在这里说下UV是什么,uv2 是几何体的属性,UV 坐标用于定义如何将 2D 纹理映射到 3D 网格上。还有一点要注意红色通道是指的灰度 灰度 这个贴图一般都是黑白的,或灰色的。在使用 combine 时要注意可以使用 reflectivity 控制贴图对表面的影晌。对于envMap与refractionRatio 与 specularMap 属性虽然基础材质中有这个属性但是这几个属性不透用于基础材质。
- alphaMap 值类型 texture 用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 默认值为null。
- aoMap 该纹理的红色通道用作环境遮挡贴图。默认值为null。aoMap需要第二组UV。
- aoMapIntensity 环境遮挡效果的强度。默认值为1。零是不遮挡效果。
- color 材质的颜色
- combine 如何将表面颜色的结果与环境贴图(如果有)结合起来。选项为THREE.MultiplyOperation(默认值),THREE.MixOperation, THREE.AddOperation。如果选择多个,则使用.reflectivity在两种颜色之间进行混合。
- envMap 环境贴图。默认值为null。
- fog 是否支持雾,默认 true
- lightMap 光照贴图。默认值为null。lightMap需要第二组UV。
- lightMapIntensity 烘焙光的强度。默认值为1。
- map 颜色贴图。可以选择包括一个alpha通道,通常与.transparent 或.alphaTest。默认为null。
- reflectivity 环境贴图对表面的影响程度; 见.combine。默认值为1,有效范围介于0(无反射)和1(完全反射)之间。
- refractionRatio 空气的折射率(IOR)(约为1)除以材质的折射率。它与环境映射模式THREE.CubeRefractionMapping 和THREE.EquirectangularRefractionMapping一起使用。 The index of refraction (IOR) of air (approximately 1) divided by the index of refraction of the material. It is used with environment mapping mode THREE.CubeRefractionMapping. 折射率不应超过1。默认值为0.98。
- wireframe 将几何体渲染为线框。默认值为false(即渲染为平面多边形)。
- wireframeLinecap 定义线两端的外观。可选值为 'butt','round' 和 'square'。默认为'round'。
- wireframeLinejoin 定义线连接节点的样式。可选值为 'round', 'bevel' 和 'miter'。默认值为 'round'。
- wireframeLinewidth 控制线框宽度。默认值为1。 下面是一些简单的使用示例协助理解这些属性
<template>
<div id="parkingLot" ref="parkingLot">
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
import { PMREMGenerator } from 'three/src/extras/PMREMGenerator.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import redbgImage from "@public/redbg.png"
import banner2 from "@public/banner2.jpg"
import rgImage from "@public/rg.png"
import hdrImg from "@public/hdr/bgImage.hdr"
import rgImageban from "@public/person.jpg"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const parkingLot = ref();
onMounted(() => {
const DOMEl = parkingLot.value;
// 获取 DOMEl 的宽度和高度,以设置渲染器的大小。
const width = DOMEl.clientWidth;
const height = DOMEl.clientHeight;
const renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height );
DOMEl.appendChild( renderer.domElement );
const scene = new THREE.Scene();
renderer.shadowMap.enabled = true; // 启用阴影映射
const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 );
camera.position.set( 0, 300, 800 );
camera.lookAt( 0, 0, 0 );
// 创建 PMREM 生成器
const pmremGenerator = new PMREMGenerator(renderer);
// 使用 RGBELoader 加载 HDR 环境图
new RGBELoader().load(hdrImg, (hdrTexture) => {
// 从 HDR 图像生成 PMREM 贴图
const pmremTexture = pmremGenerator.fromEquirectangular(hdrTexture).texture;
scene.background = pmremTexture; // 作为背景图像
scene.environment = pmremTexture; // 作为全局环境贴图
const geometry = new THREE.TorusKnotGeometry( 10, 4, 100, 16 );
// 创建一个 ImageLoader 实例
const loader = new THREE.TextureLoader();
// 加载图像文件
const texture = loader.load(rgImage);
const material = new THREE.MeshBasicMaterial({
color: 0xffff00,
alphaMap: texture,
transparent: true, // 开启透明度
});
const torusKnot = new THREE.Mesh(geometry, material);
scene.add(torusKnot);
// 创建几何体
const geometry1 = new THREE.BoxGeometry(10, 10, 10);
// 复制第一组 UV 坐标作为第二组 UV 坐标
geometry1.setAttribute('uv2', new THREE.BufferAttribute(geometry1.attributes.uv.array, 2));
const baseTexture = loader.load(rgImageban);
// 创建材质
const material1 = new THREE.MeshBasicMaterial({
map: baseTexture,
aoMap: texture,
aoMapIntensity: 1, // 控制环境遮挡效果的强度
});
// 创建网格对象
const mesh = new THREE.Mesh(geometry1, material1);
mesh.position.x = 50;
scene.add(mesh);
// 创建几何体
const geometry2 = new THREE.BoxGeometry(10, 10, 10);
const redbgImageTexture = loader.load(redbgImage);
// 创建材质
const material2 = new THREE.MeshBasicMaterial({
color: 0x0000ff,
map: redbgImageTexture,
combine: THREE.MixOperation
});
// 创建网格对象
const mesh2 = new THREE.Mesh(geometry2, material2);
mesh2.position.x = -50;
scene.add(mesh2);
// 假设你已经加载了六个图像作为立方体贴图的面
const loaderCube = new THREE.CubeTextureLoader();
const cubemap = loaderCube.load([
banner2, banner2,
banner2, banner2,
banner2, banner2
]);
// 创建几何体
const geometry3 = new THREE.BoxGeometry(10, 10, 10);
console.log(pmremGenerator,"pmremGenerator")
// 从立方体贴图生成 PMREM 贴图
const pmremTexture2 = pmremGenerator.fromCubemap(cubemap).texture;
// 创建材质
const material3 = new THREE.MeshStandardMaterial({
envMap: pmremTexture2,
roughness: 0.1,// 光滑度,0 完全光滑 1 表面非常粗粗
metalness: 0.9 // 反射属性是否类似于金属 0 非类似 1 完全
});
// 创建网格对象
const mesh3 = new THREE.Mesh(geometry3, material3);
mesh3.position.y = 50;
scene.add(mesh3);
// 创建几何体
const geometry4 = new THREE.BoxGeometry(10, 10, 10);
// 复制第一组 UV 坐标作为第二组 UV 坐标
geometry4.setAttribute('uv2', new THREE.BufferAttribute(geometry4.attributes.uv.array, 2));
// 创建材质
const material4 = new THREE.MeshBasicMaterial({
color: 0xffffff, // 材质颜色
lightMap: baseTexture, // 设置光照贴图
lightMapIntensity: 1.0 // 光照贴图的强度
});
// 创建网格对象
const mesh4 = new THREE.Mesh(geometry4, material4);
mesh4.position.y = -50;
scene.add(mesh4);
// 创建几何体
const geometry5 = new THREE.BoxGeometry(10, 10, 10);
// 创建材质
const material5 = new THREE.MeshBasicMaterial({
color: 0x00ff00,
specularMap: baseTexture, // 高光纹理无效
wireframe: true,
});
// 创建网格对象
const mesh5 = new THREE.Mesh(geometry5, material5);
mesh5.position.x = 100;
scene.add(mesh5);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(10, 10, 10);
directionalLight.castShadow = true; // 启用阴影投射
scene.add(directionalLight);
// 创建 OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 渲染循环
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
});
});
</script>
<style lang="scss" scoped="scoped">
#parkingLot {
width: 940px;
height: 940px;
border: 1px solid #ccc;
margin: 30px auto;
}
</style>
结语:由于这个是基础材质,不具备反光属性对其中几个接近无效的属性专门做了描述。对有一些比较难的属性做了立方体示例。