【愚公系列】2023年08月 Three.js专题-材质


前言

材质是指制造物品所使用的原料或物质的种类,常见的材质包括金属、塑料、木材、玻璃、石头等。材质的选择取决于所制造物品的用途、设计和预算等因素。不同的材质有不同的特点和优缺点,如金属通常较为坚固,但较重且易锈蚀;塑料轻便且不易损坏,但耐久性较差。材质也会影响制造物品的外观和质感,如木材可以赋予物品自然美感,而玻璃则可以营造现代感。

一、材质

1.简介

1.1 基础材质(不会对光源做出反应)

名称 描述
网络基础材质 MeshBasicMaterial 基础材质,显示几何体线框或添加简单颜色
网络深度材质 MeshDepthMaterial 根据网格到相机的距离,决定如何染色
网络法向材质 MeshNormalMateria 根据物体表面法向向量计算颜色
网络面材质 MeshFaceMaterial 一种容器,可以给容器里物体的各个表面指定不同颜色

1.2 高级材质(郎伯材质 和 phone材质 会对光源做出反应)

名称 描述
网络郎伯材质 MeshLambertMateria 会考虑光照,创建暗淡的、不光亮的物体
网络 Phong 材质 MeshPhongMaterial 会考虑光照,创建光亮的物体
着色器材质 ShaderMaterial 自定义着色器程序 (之后的项目里会经常用到)
直线基础材质 LineBasicMaterial 用于直线几何体
愿线材质 LineDashedMateria 创建虚线效果

2.属性分类

2.1 基础属性

属性名称 描述
id 标识,创建物体时赋值
name 名称,可以通过此属性赋值给物体名称
opacity 透明度,取值范围 0~1,需要和 transparent 结合使用
transparent 是否透明,true透明,并且可以修改透明度, false 不透明
overdraw 过度描绘,可以消除在使用 CanvasRenderer 渲染时物体之间的缝隙
visible 是否可见,是否能在场景中看到此物体
side 侧面,设置在哪一面使用材质,
needsUpdate 是否需要刷新,可以刷新材质缓存

2.2 融合属性

决定物体如何与背景融合

属性名称 描述
blending 融合,决定物体上的材质如何与背景融合
blendsrc 融合源,创建自定义的融合模式
blenddst 融合目标
blendingequation 融合公式

2.3 高级属性

控制底层 webgl 上下文如何渲染物体

属性名称 描述
depthTest 深度测试
depthWrite 是否影响深度缓存
alphaTest 指定一个值,如果某个像素的值小于它,则不会将该像素展示

3.MeshBasicMaterial基础材质

3.1 属性

属性名称 描述
color 材质颜色
wireframe 是否渲染成线框
wireframeLinewidth 设置线框宽度
wireframeLinecap 线段间的端点如何显示
wireframeLinejoin 线段的连接点如何显示
shading 定义如何着色
vertexColors 为每个顶点定义不同的颜色
fog 是否会受全局雾化效果设置的影响

3.2 案例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质
  const cubeMaterial = new THREE.MeshBasicMaterial({
      
       color: 0xff0000, wireframe: false });

  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(cubeMaterial);
  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

4.MeshDepthMaterial深度材质

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质
  const cubeMaterial = new THREE.MeshDepthMaterial();

  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(cubeMaterial, camera);
  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

5.MeshNormalMateria法向材质

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质
  const cubeMaterial = new THREE.MeshNormalMaterial();

  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(cubeMaterial, camera);
  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

6.MeshFaceMaterial面材质

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质
  const cubeMaterial = new THREE.MeshFaceMaterial([
    new THREE.MeshBasicMaterial({
      
       color: 0x009e60 }),
    new THREE.MeshBasicMaterial({
      
       color: 0x0051ba }),
    new THREE.MeshBasicMaterial({
      
       color: 0xffd500 }),
    new THREE.MeshBasicMaterial({
      
       color: 0xff5800 }),
    new THREE.MeshBasicMaterial({
      
       color: 0xc41e3a }),
    new THREE.MeshBasicMaterial({
      
       color: 0xffff00 }),
  ]);

  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(cubeMaterial, camera);
  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

7.MeshLambertMaterial郎伯材质

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质
  const cubeMaterial = new THREE.MeshLambertMaterial({
      
       color: 0xff0000 });

  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(cubeMaterial, camera);
  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

8.MeshPhongMaterial(Phong材质)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质
  const cubeMaterial = new THREE.MeshPhongMaterial({
      
       color: 0xff0000 });

  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(cubeMaterial, camera);
  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

9.ShaderMaterial着色器材质

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质
  const cubeMaterial = new THREE.ShaderMaterial({
      
      
    uniforms: {
      
      
      r: {
      
      
        type: 'f',
        value: 1.0,
      },
      a: {
      
      
        type: 'f',
        value: 1.0,
      },
    },
    vertexShader: `
      void main() {
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      }
    `,
    fragmentShader: `
      uniform float r;
      uniform float a;

      void main() {
        gl_FragColor = vec4(r,0.0,0.0,a);
      }
    `,
    transparent: true,
  });

  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(cubeMaterial, camera);
  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

10.直线和虚线材质

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加直线和虚线
  const lines = new THREE.Geometry();
  lines.vertices = [
    new THREE.Vector3(0, 2, 5),
    new THREE.Vector3(0, -2, 5),
  ];

  // const material = new THREE.LineBasicMaterial({
      
      
  //   color: 0xff0000,
  //   linewidth: 10,
  // })

  const material = new THREE.LineDashedMaterial({
      
      
    color: 0xff0000,
    dashSize: 1, // 短划线的长度
    gapSize: 1, // 间隔的长度
  })

  const line = new THREE.Line(lines, material);
  // 计算 点到线起始点的累积长度
  lines.computeLineDistances()
  scene.add(line);
  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  initControls(material, camera);
  const animation = () => {
      
      
    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

11.联合材质

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      
      
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="../lib/three/three.js"></script>
  <script src="../lib/three/dat.gui.js"></script>
  <script src="../controls/index.js"></script>
</head>
<body>

</body>
</html>

<script>
  // 创建一个场景
  const scene = new THREE.Scene();

  // 创建一个相机 视点
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  // 设置相机的位置
  camera.position.set(0,0,20);

  // 创建一个渲染器
  const renderer = new THREE.WebGLRenderer();
  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  // 添加一个立方体
  // 定义了一个立方体的对象
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);

  // 创建材质

  const lambert = new THREE.MeshLambertMaterial({
      
       color: 0xff0000 })
  const basic = new THREE.MeshBasicMaterial({
      
       wireframe: true })

  const cube = THREE.SceneUtils.createMultiMaterialObject(cubeGeometry, [
    lambert,
    basic
  ])

  // 添加到场景里
  scene.add(cube);

  // 添加灯光
  const spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(-10,10,90);
  scene.add(spotLight);
  spotLight.shadowMapWidth = 4096;
  spotLight.shadowMapHeight = 4096;

  const animation = () => {
      
      
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 渲染
    renderer.render(scene, camera);

    requestAnimationFrame(animation);
  }
  animation()
</script>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/aa2528877987/article/details/132187275