个人博客 个人博客
首页
  • 前端
  • 后端
  • Git
  • Docker
  • 网络
  • 操作系统
工具
阅读
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

董先亮

前端react开发
首页
  • 前端
  • 后端
  • Git
  • Docker
  • 网络
  • 操作系统
工具
阅读
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 待整理
  • 相机
  • 核心
  • 几何体
  • 辅助对象
  • 灯光
  • 材质
    • Material
      • 属性
      • transparent
      • opacity
      • side
      • vertexColors
      • 方法
      • onBeforeCompile
    • MeshBasicMaterial
      • 属性
      • wireframe
      • color
      • map
      • alphaMap
      • aoMap
      • aoMapIntensity
    • MeshStandardMaterial
      • 属性
      • displacementMap
      • displacementScale
      • roughness
      • roughnessMap
      • metalness
      • metalnessMap
      • normalMap
    • PointsMaterial
      • 属性
      • sizeAttenuation
      • map
      • alphaMap
      • transparent
      • depthWrite
      • blending
  • 数学库
  • 物体
  • 控制
  • 常用方法
  • 三方库
  • 加载器
  • 纹理贴图
  • PBR
  • 相关网站
  • 场景
  • 全景投影方式
  • HDR
  • 渲染器
  • Geometry和BufferGeometry区别
  • WebGL
  • UV介绍
  • 数学知识
  • 着色器案例
  • blender
  • 后期处理
  • 缓冲区
  • 后期处理与分层渲染
  • 叠加渲染
  • Threejs
NeverStop1024
2022-09-15
目录

材质

三维场景中,可以 放置很多三维模型,一个三维模型Mesh是由一个几何体加上材质所构成的,几何体决定了模型的几何形状,材质决定了模型的外观属性,一个简单的理解就是一个西瓜的瓤决定了它的大小和圆扁,而西瓜皮决定了它外表啥样。
材质分为点、线、面(网格)、特殊、自定义材质

三维模型创建:
1.创建一个几何体
2.几何体指定相应材质
3.Mesh()方法,对三维模型进行构建
4.将三维模型加入到场景

# Material (opens new window)

材质基类

# 属性

# transparent (opens new window)

定义材质是否透明

# opacity (opens new window)

材质透明度

# side (opens new window)

定义将要渲染哪一面 - 正面,背面或两者

# vertexColors (opens new window)

是否启用顶点着色,如果修改顶点颜色的话,必须开启这个属性

# 方法

# onBeforeCompile (opens new window)

在编译shader程序之前立即执行的可选回调。此函数使用shader源码作为参数。用于修改内置材质。

# MeshBasicMaterial (opens new window)

基础网格材质(可以看作皮肤)
特点: 不反光,永远显示本身颜色

# 属性

# wireframe (opens new window)

将几何体渲染为线框

# color (opens new window)

材质的颜色

# map (opens new window)

颜色贴图,注意值类型是Texture (opens new window)

# alphaMap (opens new window)

alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 默认值为null。

// 导入纹理
const textureLoader = new THREE.TextureLoader();
const doorColorTexture = textureLoader.load("./textures/door/color.jpg");

// console.log(doorColorTexture);
// 

// 添加物体
const cubeGeometry = new THREE.BoxBufferGeometry(1, 1, 1);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture,
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# aoMap (opens new window)

环境遮挡,把环境的光挡住。注意:aoMap需要第二组UV

# aoMapIntensity (opens new window)

环境遮挡强度

// 导入纹理
const textureLoader = new THREE.TextureLoader();
const doorColorTexture = textureLoader.load("./textures/door/color.jpg");
const doorAplhaTexture = textureLoader.load("./textures/door/alpha.jpg");
const doorAoTexture = textureLoader.load(
  "./textures/door/ambientOcclusion.jpg"
);

// 添加物体
const cubeGeometry = new THREE.BoxBufferGeometry(1, 1, 1);
// 材质
const basicMaterial = new THREE.MeshBasicMaterial({
  color: "#ffff00",
  map: doorColorTexture,
  alphaMap: doorAplhaTexture,
  transparent: true,
  aoMap: doorAoTexture,
  aoMapIntensity: 1,
  //   opacity: 0.3,
  //   side: THREE.DoubleSide,
});
basicMaterial.side = THREE.DoubleSide;
const cube = new THREE.Mesh(cubeGeometry, basicMaterial);
scene.add(cube);
// 给cube添加第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

比如我们用这张图来进行环境遮挡 ocRU9a_ivrpUk
实现的效果,可以看到黑色线条遮挡部分,明显变黑了,这个门也更真实了
f1i1NL_GcwGMO

# MeshStandardMaterial (opens new window)

标准网格材质,基于PBR标准实现的材质,必须有灯光

# 属性

# displacementMap (opens new window)

置换贴图, 会影响网格顶点的位置,通过识别贴图的颜色,让顶点进行突出,所以顶点越多,突出效果会越细致。

woGZTG_grSqwi

// 导入纹理
const textureLoader = new THREE.TextureLoader();
const doorColorTexture = textureLoader.load("./textures/door/color.jpg");
const doorAplhaTexture = textureLoader.load("./textures/door/alpha.jpg");
const doorAoTexture = textureLoader.load(
  "./textures/door/ambientOcclusion.jpg"
);
//导入置换贴图
const doorHeightTexture = textureLoader.load("./textures/door/height.jpg");

// 添加物体,注意后面三个参数,因为置换贴图实际是在位移顶点,增加顶点数量很重要,顶点越多越细腻,不加的话,顶点少也就没啥突出效果,
const cubeGeometry = new THREE.BoxBufferGeometry(1, 1, 1, 100, 100, 100);
// 材质
const material = new THREE.MeshStandardMaterial({
  color: "#ffff00",
  map: doorColorTexture,
  alphaMap: doorAplhaTexture,
  transparent: true,
  aoMap: doorAoTexture,
  aoMapIntensity: 1,
  displacementMap: doorHeightTexture,
  displacementScale: 0.1,
});
material.side = THREE.DoubleSide;
const cube = new THREE.Mesh(cubeGeometry, material);
scene.add(cube);
// 给cube添加第二组uv
cubeGeometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

最后实现的这个门,根据置换贴图中,白色程度不同,突出程度也不同,整体看起来更加真实了。 YNQ57v_aFoBMK

# displacementScale (opens new window)

配合置换贴图,规定顶点最大位移程度,默认突出程度是1(可以看作长度)。一般都要修改这个突出程度

# roughness (opens new window)

修改材质粗糙程度,也就决定了漫反射的程度。如果还提供roughnessMap,则两个值相乘。

# roughnessMap (opens new window)

贴图方式,通过识别贴图的 去改变材质粗糙程度,贴图上越灰色的地方越粗糙,这样就可以随意设置哪部分粗糙,哪部分光滑了。 bMquo5_gSxkuQ

// 导入粗糙度贴图
const roughnessTexture = textureLoader.load("./textures/door/roughness.jpg");
// 材质
const material = new THREE.MeshStandardMaterial({
  // ...
  roughness: 1,
  roughnessMap: roughnessTexture,
  // ...
});
1
2
3
4
5
6
7
8
9

可以看到金属部分已经比较粗糙了 DgH8cx_PT3Io6

# metalness (opens new window)

材质与金属的相似度,如果还提供了metalnessMap,则两个值相乘。

# metalnessMap (opens new window)

金属度贴图,越白金属度越强 fQq0Ph_xwQhOW

// 导入金属贴图
const metalnessTexture = textureLoader.load("./textures/door/metalness.jpg");
// 材质
const material = new THREE.MeshStandardMaterial({
  // ...
  metalness: 1,
  metalnessMap: metalnessTexture,
  // ...
});
1
2
3
4
5
6
7
8
9

可以看到金属部分,与金属更相似了 zajzlS_GEjqrN

# normalMap (opens new window)

法线贴图,上面各种贴图完成以后,有一点不足之处,都是一个镜面,没有凹凸不平的感觉,这时候就要用到法线贴图,改变反射方向,让反射更真实。
贴图中每种颜色都代表不同的反射方向。 sHVhCs_EAynLo

// 导入法线贴图
const normalTexture = textureLoader.load("./textures/door/normal.jpg");
// 材质
const material = new THREE.MeshStandardMaterial({
  // ...
  normalMap: normalTexture,
  // ...
});
1
2
3
4
5
6
7
8

此时就有这种凹凸不平的感觉了 xcCc3L_87CJWJ

# PointsMaterial (opens new window)

点材质

# 属性

可以设置点样式、点大小、点颜色、透明度等

# sizeAttenuation (opens new window)

点的大小是否因相机深度而衰减,相机越远看到的越小,相机越近看到的越大,如果为false,相机近远,看到的大小都是一样的。(仅限透视相机)

# map (opens new window)

给点设置贴图

# alphaMap (opens new window)

开启透明度,像下面这张图,如果导入贴图不开透明度的话,四周黑色部分会对后面产生遮挡。 DIzf2M_u5QugX

# transparent (opens new window)

定义材质是否透明,想开启alphaMap,必须先开这个属性,材质透明是前提。

# depthWrite (opens new window)

深度写入,如果开了深度写入,前面的会遮挡后面的,不管透不透明。 可以看到,导入这样一张纹理贴图,也设置了透明,黑色部分虽然透明了,但还是遮挡住了后面的渲染。 NJ0WnL_SE2z7x 4zt7im_m8Uois 禁止掉深度写入后,可以看到,后面不再被遮挡,都渲染出来了。但现在重合之后,渲染看起来很别扭,这时候我们就要修改blending (opens new window)混合模式了 oHLec5_NdkOYi

# blending (opens new window)

比如上面开启深度写入后,两个重合的点怎么去混合。我们将混合模式改为THREE.AdditiveBlending叠加效果,这样就完美了 7bzmRg_UGw7CE

编辑 (opens new window)
上次更新: 2022/09/28
灯光
数学库

← 灯光 数学库→

最近更新
01
mock使用
07-12
02
websocket即时通讯
07-12
03
前端面试题
07-09
更多文章>
Theme by Vdoing | Copyright © 2022-2023 NeverStop1024 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式