3D数字孪生 – Three.js 项目实战之场景材质(三)

接上文# 3D数字孪生 – Three.js 场景光源(二)最后的问题:

“为何已关闭场景中所有光源,仍然有些面是亮的呢?”
image.png

我们不妨近距离的观察一下,打开场景中的方向光 DirectionalLight,发光的 线

const Lights = () => {
  return (
    <>
      {/* 首先添加个环境光,AmbientLight,影响整个场景的光源 */}
      {/* <ambientLight intensity={0.5} /> */}
      {/* 模拟远处类似太阳的光源 */}
      <directionalLight color={0xffffff} intensity={3} position={[10, 10, 0]} />
      {/* <MovingSpot color="#fff" position={[3, 2000, 2]} /> */}
    </>
  );
};

20230620105618_rec_.gif

不难发现,在绿色的巷道上,是有类似油漆的镜面投影效果的,而黄色面却没有,所以,顺藤摸瓜很自然就可以想到,它们的材质(Material)有问题!

OK,定位到问题,我们看下绘制巷道的组件tunnel.tsx组件的代码:

代码位置: 查看BaseScene=>components=>tunnel.tsx文件(项目结构,可以查看上篇# 3D数字孪生 – Three.js 项目介绍与基础环境搭建(一)

import React from 'react';
import { Vector3 } from 'three';
import { MeshReflectorMaterial, Html } from '@react-three/drei';

export interface ITunnelProps {
  x: number;
  y: number;
  width: number;
  height: number;
  tunnelNumber: string;
}
const Tunnel: React.FC<ITunnelProps> = ({ x, y, width, height, tunnelNumber }) => {
  // 巷道的位置
  const innerPosition = new Vector3(x + width / 2, 1.1, y + height / 2);
  const outerPosition = new Vector3(x + width / 2, 1, y + height / 2);
  const textPosition = new Vector3(x + width / 2, 1.2, y + height / 2);

  return (
    <group>
      <mesh position={innerPosition} rotation={[-Math.PI / 2, 0, 0]}>
        <planeGeometry args={[width, height]}></planeGeometry>
        <MeshReflectorMaterial
          blur={[400, 100]}
          resolution={1024}
          mixBlur={1}
          mixStrength={5}
          depthScale={1}
          minDepthThreshold={1}
          color="rgb(0, 73, 45)"
          metalness={0.85}
          roughness={0.95}
          mirror={0}
        ></MeshReflectorMaterial>
      </mesh>
      <mesh position={outerPosition} rotation={[-Math.PI / 2, 0, 0]}>
        <planeGeometry
          args={[width > 0 ? width + 20 : width - 20, height > 0 ? height + 20 : height - 20]}
        ></planeGeometry>
        <meshBasicMaterial color="rgb(221, 165, 15)"></meshBasicMaterial>
      </mesh>
      <Html scale={100} rotation={[-Math.PI / 2, 0, 0]} position={textPosition} transform occlude>
        {tunnelNumber}
      </Html>
    </group>
  );
};

export default Tunnel;

Group中的代码分三块,第一个网格(mesh)是绿色的镜面。

将其中另外两块组件注释:

<group>

  <mesh position={innerPosition} rotation={[-Math.PI / 2, 0, 0]}>
    <planeGeometry args={[width, height]}></planeGeometry>
    <MeshReflectorMaterial
      blur={[400, 100]}
      resolution={1024}
      mixBlur={1}
      mixStrength={5}
      depthScale={1}
      minDepthThreshold={1}
      color="rgb(0, 73, 45)"
      metalness={0.85}
      roughness={0.95}
      mirror={0}
    ></MeshReflectorMaterial>
  </mesh>
  {/* <mesh position={outerPosition} rotation={[-Math.PI / 2, 0, 0]}>
    <planeGeometry
      args={[width > 0 ? width + 20 : width - 20, height > 0 ? height + 20 : height - 20]}
    ></planeGeometry>
    <meshBasicMaterial color="rgb(221, 165, 15)"></meshBasicMaterial>
  </mesh>

  <Html scale={100} rotation={[-Math.PI / 2, 0, 0]} position={textPosition} transform occlude>
    {tunnelNumber}

  </Html> */}
</group>

image.png
可以看到,绿色的网格,我们使用的是MeshReflectorMaterial材质,我们接下来,切换一下地下黄色面的网格。

<group>

  {/* <mesh position={innerPosition} rotation={[-Math.PI / 2, 0, 0]}>
    <planeGeometry args={[width, height]}></planeGeometry>
    <MeshReflectorMaterial
      blur={[400, 100]}
      resolution={1024}
      mixBlur={1}
      mixStrength={5}
      depthScale={1}
      minDepthThreshold={1}
      color="rgb(0, 73, 45)"
      metalness={0.85}
      roughness={0.95}
      mirror={0}
    ></MeshReflectorMaterial>
  </mesh> */}
  <mesh position={outerPosition} rotation={[-Math.PI / 2, 0, 0]}>
    <planeGeometry
      args={[width > 0 ? width + 20 : width - 20, height > 0 ? height + 20 : height - 20]}
    ></planeGeometry>
    <meshBasicMaterial color="rgb(221, 165, 15)"></meshBasicMaterial>
  </mesh>

  <Html scale={100} rotation={[-Math.PI / 2, 0, 0]} position={textPosition} transform occlude>
    {tunnelNumber}

  </Html>
</group>

image.png

可以看到黄色网格面,我们使用的是meshBasicMaterial

那么,MeshReflectorMaterialmeshBasicMaterial又有什么区别,它们对于我们的问题,又有什么关联呢?

MeshReflectorMaterial和MeshBasicMaterial是Three.js中的两种材质类型,它们在渲染和功能上有一些区别。

  1. 反射: 具有反射属性,可以反射其他物体的外观。它使用环境贴图和镜面反射来实现这一效果。而MeshBasicMaterial没有反射属性,只能显示基本的材质颜色。

  2. 环境贴图:MeshReflectorMaterial可以使用环境贴图来模拟物体周围的环境光照效果,使其看起来更加真实。MeshBasicMaterial不支持环境贴图,只能显示固定的颜色。

  3. 高光反射:MeshReflectorMaterial可以通过镜面反射属性显示高光反射,使物体表面出现明亮的高光效果。MeshBasicMaterial不支持高光反射。

  4. 性能:由于MeshReflectorMaterial具有反射和高光反射等更复杂的属性,它可能会比MeshBasicMaterial更加耗费性能。如果你只需要简单的材质显示,MeshBasicMaterial可能是更好的选择。

总的来说,MeshReflectorMaterial适用于需要模拟反射和高光效果的场景,而MeshBasicMaterial适用于简单的、没有复杂需求的材质显示场景。选择使用哪种材质取决于你的需求和对性能的考虑。

所以,MeshReflectorMaterial受环境光的影响,而MeshBasicMaterial只是显示自身固定的颜色,这就能解释,为什么场景灯都关闭,还能看到网格线和面的原因啦~

three/drei中,关于着色器(shaders)还有很多玩法,以下是几种常用的材质:

  1. MeshReflectorMaterial: MeshReflectorMaterial是一种用于创建反射效果的材质。它可以应用于Mesh对象,使其表面反射周围环境的内容。

20230620164534_rec_.gif

  1. MeshWobbleMaterial: MeshWobbleMaterial是一种用于创建弹跳或扭曲效果的材质。它可以应用于Mesh对象,使其以一种有趣的方式呈现动画效果。

  2. MeshDistortMaterial: MeshDistortMaterial是一种用于创建扭曲效果的材质。它可以应用于Mesh对象,使其以一种扭曲的方式呈现。

  3. MeshRefractionMaterial: MeshRefractionMaterial是一种用于创建折射效果的材质。它可以应用于Mesh对象,使其通过物体的表面产生折射效果。

  4. MeshTransmissionMaterial: MeshTransmissionMaterial是一种用于创建透明传输效果的材质。它可以应用于Mesh对象,使其表现出透明度和光线传输的效果。

  5. MeshDiscardMaterial: MeshDiscardMaterial是一种用于创建丢弃(discard)效果的材质。它可以应用于Mesh对象,根据给定的条件来丢弃或保留片段。

  6. PointMaterial: PointMaterial是一种用于创建点精灵(point sprites)的材质。它可以应用于Points对象,使其以一种精灵化的方式呈现。

  7. SoftShadows: SoftShadows是一种用于创建柔和阴影效果的组件。它可以应用于场景中的光源,通过模糊处理来实现更柔和和更真实的阴影效果。
    20230620163626_rec_.gif

  8. shaderMaterial: shaderMaterial是一种自定义着色器材质,它允许您通过编写自定义着色器代码来创建完全定制的材质效果。

具体材质不同的玩法可以直接在这查看: Shaders demo案例

好啦,想必对于小白还有新手对材质都有一定的了解了吧o( ̄︶ ̄)o,下一章,我们继续讲解,场景中的相机以及相机控制器,分享如何在场景中行走与飞行,以及制作固定巡航大片!

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYFJVQ3U' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片