简介
材质默认只有正面可见 side: THREE.FrontSide,可以设置为 THREE.DoubleSide THREE.BackSide
材质分类
受光源影响的材质会受到光源和材质本身颜色影响 色谱叠加 模型正对光源的部分为高光部分
网格基础材质 不受光源影响
new THREE.MeshBasicMaterial({ color: 0xff0000, side: THREE.DoubleSide });
网格漫反射材质 受光源影响
new THREE.MeshLambertMaterial({ color: 0xff0000, })
网格高光材质 受光源影响
new THREE.MeshPhongMaterial({
color: 0xff0000,//0xff0000设置材质颜色为红色
shininess: 20, //高光部分的亮度,默认30
specular: 0xF7F709, //高光部分的颜色
});
物理材质(PBR材质) 受光源影响
new THREE.MeshStandardMaterial({ color: 0xff0000, })
new THREE.MeshPhysicalMaterial({ color: 0xff0000, })
深入学习
点材质
new THREE.PointsMaterial({ color: 0xff0000, })
线基础材质
THREE.LineBasicMaterial({ color: 0xff0000, })
THREE.SpriteMaterial({ color: 0xff0000, })
-
占用渲染资源 MeshBasicMaterial < MeshLambertMaterial < MeshPhongMaterial < MeshStandardMaterial < MeshPhysicalMaterial
-
渲染表现能力 MeshBasicMaterial < MeshLambertMaterial < MeshPhongMaterial < MeshStandardMaterial < MeshPhysicalMaterial
顶点法线
受光照影响的材质需要顶点法线数据才能显示正常颜色
当前示例为面示例
const geometry11 = new THREE.BufferGeometry();
const vertices1 = new Float32Array([
0, 0, 0, //顶点1坐标
80, 0, 0, //顶点2坐标
80, 80, 0, //顶点3坐标
0, 0, 0, //顶点4坐标 和顶点1位置相同
80, 80, 0, //顶点5坐标 和顶点3位置相同
0, 80, 0, //顶点6坐标
]);
const attribue1 = new THREE.BufferAttribute(vertices1, 3);
geometry11.attributes.position = attribue1;
const material11 = new THREE.MeshLambertMaterial({
color: 0xff0000,
side: THREE.DoubleSide, //两面可见
});
const normals = new Float32Array([
0, 0, 1, //顶点1法线( 法向量 )
0, 0, 1, //顶点2法线
0, 0, 1, //顶点3法线
0, 0, 1, //顶点4法线
]);
// 设置几何体的顶点法线属性.attributes.normal
geometry11.attributes.normal = new THREE.BufferAttribute(normals, 3);
var mesh21 = new THREE.Mesh(geometry11, material11);
scene.add(mesh21);
更改材质颜色的方式
material1.color.r = 0.0;
material1.color.b = 0.0;
material1.color.g = 0.0;
material1.color.setRGB(0, 1, 0);//RGB方式设置颜色
material1.color.setHex(0x00ff00);//十六进制方式设置颜色
material1.color.setStyle('#00ff00');//前端CSS颜色值设置颜色
material1.color.set(0x00ff00);//十六进制方式设置颜色
material1.color.set('#00ff00');//前端CSS颜色值设置颜色
material1.color.set('rgb(0,255,0)');
material1.color = new THREE.Color(0x000000);
纹理贴图
简单纹理
const geometry = new THREE.PlaneGeometry(200, 100);
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('/images/background.jpg');
//设置为SRGB颜色空间
texture.colorSpace = THREE.SRGBColorSpace;
const material = new THREE.MeshLambertMaterial({
// 设置纹理贴图:Texture对象作为材质map属性的属性值
//一般设置贴图后不需要设置color 如果设置color颜色值会叠加
map: texture,//map表示材质的颜色贴图属性
side: THREE.DoubleSide
});
const geometry1 = new THREE.BoxGeometry(100, 100, 100); //长方体
const geometry2 = new THREE.SphereGeometry(60, 25, 25); //球体
//CircleGeometry的顶点UV坐标是按照圆形采样纹理贴图
const geometry3 = new THREE.CircleGeometry(60, 100);
//纹理贴图加载器TextureLoader
const texLoader1 = new THREE.TextureLoader();
const texture1 = texLoader1.load('/images/background.jpg');
const material1 = new THREE.MeshBasicMaterial({
map: texture1,//map表示材质的颜色贴图属性
side: THREE.DoubleSide,
});
//纹理坐标0~1之间随意定义
//获取纹理贴图左下角四分之一部分的像素值
const uvs = new Float32Array([
0, 0,
0.5, 0,
0.5, 0.5,
0, 0.5,
]);
// 设置几何体attributes属性的位置normal属性
//2个为一组,表示一个顶点的纹理坐标
geometry1.attributes.uv = new THREE.BufferAttribute(uvs, 2);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(400, 0, 0);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(200, 200, 200);
var mesh2 = new THREE.Mesh(geometry2, material);
const mesh3 = new THREE.Mesh(geometry3, material1);
mesh3.position.set(0, 400, 0);
scene.add(mesh, mesh1, mesh2, mesh3);
console.log('uv', geometry2.attributes.uv);
运行效果
纹理阵列
const geometry = new THREE.PlaneGeometry(200, 200);
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('/images/background.jpg');
//设置在u轴上的包装方式 宽
//THREE.RepeatWrapping(重复) THREE.ClampToEdgeWrapping(边缘剪切) THREE.MirroredRepeatWrapping(镜像重复)。
texture.wrapS = THREE.RepeatWrapping;
//设置在v轴上的包装方式 高 参数同wrapS
texture.wrapT = THREE.RepeatWrapping;
// 根据你的纹理尺寸更新3D纹理的尺寸参数
//texture.image.width = 200; // 你的纹理宽度
//texture.image.height = 48; // 你的纹理高度
//当纹理比显示窗口小时的过滤方式
//THREE.NearestFilter(最近点采样) THREE.LinearFilter(线性采样)
texture.magFilter = THREE.NearestFilter;
//当纹理比显示窗口大时的过滤方式
//THREE.NearestMipMapNearestFilter
//当纹理放大时(即纹理像素映射到多个屏幕像素),它会在最接近的mipmap级别中选择最近的像素。
//当纹理缩小时,它同样会在最接近的mipmap级别中选择最近的像素。
//这种模式可能会导致放大时的方块效应(像素化),但在缩小时通常表现较好。
//THREE.NearestMipMapLinearFilter
//当纹理放大时,它会在最接近的mipmap级别中选择最近的像素。
//当纹理缩小时,它会在两个最接近的mipmap级别之间选择,并在这两个级别上使用最邻近过滤原则获取两个中间值,然后将这两个中间值传递给线性过滤器以获得最终效果。
//这种模式结合了最邻近过滤和线性过滤的特性,通常能在缩小时提供更好的平滑效果
//THREE.LinearMipMapNearestFilter
//当纹理放大时,它会在四个最近的像素之间进行线性插值(混合),从而得到更平滑的效果。
//当纹理缩小时,它会在最接近的mipmap级别上选择像素。
//这种模式在放大时提供了平滑的过渡,但在缩小时可能不如其他模式平滑。
//THREE.LinearMipMapLinearFilter。
//当纹理放大时,它会在四个最近的像素之间进行线性插值。
//当纹理缩小时,它会在两个最接近的mipmap级别之间选择,并在这两个级别上使用线性过滤原则获取两个中间值,然后将这两个中间值传递给线性过滤器以获得最终效果。
//这种模式在放大和缩小时都提供了平滑的过渡,是纹理过滤的默认设置之一,因为它通常能够提供最佳的视觉质量。
//不同模式计算成本和视觉效果成反比
texture.minFilter = THREE.LinearMipMapLinearFilter;
//纹理格式
//THREE.RGBFormat 表示每个像素点使用三个分量来表示,分别是红、绿、蓝。这种格式不包含透明度信息,也就是说纹理不会有透明的效果 一般很少使用
//THREE.RGBAFormat 表示每个像素点使用四个分量来表示,分别是红、绿、蓝和透明(Alpha)。这种格式支持透明度,允许纹理具有透明或半透明的效果 一般使用这种
//THREE.LuminanceFormat 表示每个像素点使用一个亮度分量来表示。这种格式通常用于灰度图像,其中颜色信息被简化为单一的亮度值 一般在只关心亮度变化而不关心具体颜色的场合使用
texture.format = THREE.RGBAFormat;
// uv两个方向纹理重复数量
texture.repeat.set(12, 12);//注意选择合适的阵列数量
//当纹理的图片数据改变后,需要将这个参数设置为true以确保渲染器更新纹理
texture.needsUpdate = true;
//纹理偏移一般加到循环执行里 实现几何体表面纹理移动效果
//texture.offset.x += 0.1;//纹理u方向偏移
//texture.offset.y += 0.1;//纹理v方向偏移
const material = new THREE.MeshBasicMaterial({
// 设置纹理贴图:Texture对象作为材质map属性的属性值
map: texture,//map表示材质的颜色贴图属性
side: THREE.DoubleSide,
//使用背景透明的png贴图,注意开启透明计算
//一般使用背景透明的图片的时候使用 可以不显示透明部分 可以图片做标注
transparent: true,
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
运行效果
纹理偏移一般加到循环执行里 实现几何体表面纹理移动效果
texture.offset.x += 0.1;//纹理u方向偏移
texture.offset.y += 0.1;//纹理v方向偏移
材质中使用背景透明的png贴图,注意开启透明计算 项目中使用会比较多
一般使用背景透明的图片的时候使用 可以不显示透明部分 可以图片做标注
transparent: true,