three 材质基类

235 阅读14分钟

这一节中主要介绍材质基类,所有的材质类型都是从这个基类继承而来

Material 材质基类,无法单独使用 所有属性通常在标准材质当参数传入

  • alphaHash 布尔值 为 true 时会在透明的材质有 使用 hash 算法生成一些随机的不透明区域 可以与 opacity 配合查看效果
    const material = new THREE.MeshBasicMaterial({
        color: 0xff0000,  // 红色
        transparent: true,
        alphaHash: true,
        opacity: 0.5
    });
  • alphaTest 取值范围 0 - 1 当材质材的不透明度小于当前 值时会不渲染小于当前值透明度的区域
    // 立方体渲染
    const material = new THREE.MeshBasicMaterial({
        color: 0xff0000,  // 红色
        alphaTest: 0.5,
        opacity: 0.5
    });
    // 立方体不渲染
    const material = new THREE.MeshBasicMaterial({
        color: 0xff0000,  // 红色
        alphaTest: 0.6,
        opacity: 0.5
    });
  • alphaToCoverage 布尔属值 为 true 时 平滑边滑与边缘上的锯齿 const renderer = new THREE.WebGLRenderer({antialias: true});在创建渲染器时将抗锯齿参数
  • blendAlpha 取值范围 0 - 1 当两个透明对象重合时,透明混合时当前材质颜色混合背景的权重比

    // 创建第二个立方体,使用 blendAlpha = 1.0
    const materialWithHighBlendAlpha = new THREE.MeshBasicMaterial({
        color: 0x00ff00, // 绿色
        transparent: true,
        opacity: 0.5,
        blending: THREE.CustomBlending,
        blendSrc: THREE.SrcAlphaFactor, // 使用 ConstantAlphaFactor
        blendDst: THREE.OneMinusConstantAlphaFactor,
        blendAlpha: 1.0, // 这个属性能够在 blendDst 值为 THREE.OneMinusConstantAlphaFactor 改变颜色混合背景的权重 可以通过上面的示例做出调整
        blendEquation: THREE.AddEquation,
        blendEquationAlpha: THREE.AddEquation
    });
  • blendColor 恒定混合颜色的 RGB 在例子中,绿色(源颜色)与红色(blendColor)会根据 blendDst 的值进行混合。由于 blendDst 是 THREE.OneMinusConstantColorFactor,它会将目标因子设置为 1 - blendColor 的 RGB 值。计算方式 R 0 - 0 = 0; G 255 - 0 = 255; B 0 - 255 = - 255 由于颜色不存在于负数 重置为 0 最终得到 RGB(0,255, 0)
    // 创建第二个立方体,使用 blendAlpha = 1.0
    const materialWithHighBlendAlpha = new THREE.MeshBasicMaterial({
        color: 0x00ff00,  // 源颜色为绿色
        transparent: true,
        opacity: 0.5,
        blending: THREE.CustomBlending,
        blendSrc: THREE.ConstantColor,
        blendDst: THREE.OneMinusConstantColorFactor, // 目标因子为 1 - 源的 alpha
        blendColor: new THREE.Color(0, 0, 1) // 这里的 1 为 255, 当透明遇到纯红色时显示的颜色为 R 0 - 0 = 0; G 255 - 0 = 255; B 0 - 255 = - 255 由于颜色不存在于负数 重置为 0 最终得到 RGB(0,255, 0) 后将这个参与透明度计算0.5
    });
  • blendDst 混合目标 下面是可选值列表并对作用做出了详细的描述 默认值为OneMinusSrcAlphaFactor
  • blendDstAlpha blendDst的透明度。 默认值为 null.
    `THREE.ZeroFactor`: 目标颜色因子为 0,意味着目标颜色对混合结果没有影响。通常用于完全不考虑目标颜色的情况。
    `THREE.OneFactor`: 目标颜色因子为 1,目标颜色完全参与混合。即目标颜色的贡献量为 100%。
    `THREE.SrcColorFactor`: 源颜色因子,源颜色的 RGB 值直接用作混合计算。
    `THREE.OneMinusSrcColorFactor`: 源颜色的反色因子,即 `1 - 源颜色`。它表示源颜色的补色参与混合。
    `THREE.SrcAlphaFactor`: 源颜色 alpha 值作为因子。即源颜色的 alpha 值参与混合计算。
    `THREE.OneMinusSrcAlphaFactor`: 源颜色 alpha 的补色因子,即 `1 - 源 alpha``THREE.DstColorFactor`: 目标颜色的 RGB 值作为因子。目标颜色直接参与混合。
    `THREE.OneMinusDstColorFactor`: 目标颜色的反色因子,即 `1 - 目标颜色``THREE.DstAlphaFactor`: 目标颜色的 alpha 值作为因子。即目标颜色的 alpha 值参与混合。
    `THREE.OneMinusDstAlphaFactor`: 目标颜色 alpha 的补色因子,即 `1 - 目标 alpha``THREE.ConstantColorFactor`: 目标颜色为一个常量值(`blendColor`),常用于特定的混合效果。
    `THREE.OneMinusConstantColorFactor`: 常量颜色的反色因子,即 `1 - blendColor
    `THREE.ConstantAlphaFactor`: 常量 alpha 值参与混合。
    `THREE.OneMinusConstantAlphaFactor`: 常量 alpha 的补色因子,即 `1 - blendAlpha`。
    // 目标 alpha  是指透视后方  计算 0xff0000 材质的颜色, 这里就是材质为红色的参与透明计算为 0
    const materialWithHighBlendAlpha = new THREE.MeshBasicMaterial({
        color: 0xff0000,  // 红色
        transparent: true,
        opacity: 0.5,     // 设置整体透明度
        blending: THREE.CustomBlending,
        blendSrc: THREE.SrcAlphaFactor,
        blendDst: THREE.OneMinusSrcAlphaFactor,
        blendDstAlpha: THREE.ZeroFactor
    });
  • blendEquation 混合时所采用的混合方程式。默认值为THREE.AddEquation 取值范围见下方
  • blendEquationAlpha blendEquation 的透明度. 默认值为 null。取值范围见下方
    `THREE.AddEquation`:将源颜色和目标颜色相加。通常用于普通的透明效果。
    `THREE.SubtractEquation`:目标颜色减去源颜色。常用于特殊效果,如一些特殊的视觉效果。
    `THREE.ReverseSubtractEquation`:源颜色减去目标颜色。也用于特殊的视觉效果。
    `THREE.MinEquation`:取源颜色和目标颜色中的最小值。
    `THREE.MaxEquation`:取源颜色和目标颜色中的最大值。
    
    //   其中目标颜色为  为透视后方的颜色  源颜色 0xff0000
    const materialWithHighBlendAlpha = new THREE.MeshBasicMaterial({
        color: 0xff0000,
        transparent: true,
        opacity: 0.5,     // 设置整体透明度
        blending: THREE.CustomBlending, // 自定度混合模式
        blendSrc: THREE.SrcAlphaFactor,
        blendEquation: THREE.AddEquation, // 颜色混合计算方程
        blendEquationAlpha: THREE.ReverseSubtractEquation // 透明计算混合方程
    });
  • blending 在使用此材质显示对象时要使用何种混合。必须将其设置为CustomBlending才能使用自定义blendSrc, blendDst,blendEquation 取值范围
    THREE.NoBlending 源颜色完全覆盖目标颜色,没有混合效果。
    THREE.NormalBlending 标准的 alpha 混合模式,源颜色和目标颜色按 alpha 值进行混合。
    THREE.AdditiveBlending 源颜色和目标颜色相加。适用于发光效果,例如光环和火焰。
    THREE.SubtractiveBlending 目标颜色减去源颜色。适用于创建一些特殊的视觉效果。
    THREE.MultiplyBlending 源颜色和目标颜色相乘。适用于阴影和纹理叠加效果。
    THREE.CustomBlending 允许自定义混合方程和混合因子
  • blendSrc 混合源。默认值为SrcAlphaFactor 与 blendDst 的区别是 dst 主要针对目录 即北景 而 src 主要针对的是源 就是 当前材质 取值范围为下面列表
  • blendSrcAlpha blendSrc的透明度。 默认值为 null 取值范围为下面列表
    // 源 指的材质 材目指的北景
    `THREE.ZeroFactor` 源因子为0。源颜色在最终混合中不产生影响。
    `THREE.OneFactor` 源颜色在最终混合中完全影响结果。
    `THREE.SrcColorFactor` 源因子为源颜色的颜色值(红色、绿色、蓝色分量)。
    `THREE.OneMinusSrcColorFactor` 源因子为1减去源颜色的颜色值。
    `THREE.SrcAlphaFactor` 源因子为源颜色的 alpha 值。
    `THREE.OneMinusSrcAlphaFactor` 源因子为1减去源颜色的 alpha 值。
    `THREE.DstColorFactor` 源因子为目标颜色的颜色值。
    `THREE.OneMinusDstColorFactor` 源因子为1减去目标颜色的颜色值。
    `THREE.DstAlphaFactor` 源因子为目标颜色的 alpha 值。
    `THREE.OneMinusDstAlphaFactor` 源因子为1减去目标颜色的 alpha 值。
  • clipIntersection 更改剪裁平面的行为,以便仅剪切其交叉点,而不是它们的并集。默认值为 false。要使剪裁生效要配置 renderer.localClippingEnabled = true; 渲染器属性
  • clippingPlanes 定义裁前位置
  • clipShadows 裁剪阴影,
    const materialWithHighBlendAlpha = new THREE.MeshBasicMaterial({
        color: 0x00ff00,      // 物体颜色
        clippingPlanes: [new THREE.Plane(new THREE.Vector3(1, 0, 0), 0)],  // 裁剪平面数组 在当前材质中当X坐标大于0时裁剪 1, 0, 0 分别对应 x y z 一个 Plane 对象只能定义一个平面的裁剪
        clipIntersection: true,  // 交集模式,保留多个平面相交的部分
        clipShadows: true, // 裁剪阴影,在这里当材质对应物体的阴影大于x坐标1时裁剪
        transparent: true  // 开启透明以查看裁剪效果
    });
  • colorWrite 是否对当前材质写入颜色,这可以与网格的renderOrder属性结合使用,以创建遮挡其他对象的不可见对象。默认值为true。
    // 在这个示例中通过设置 renderOrder 后渲染将写入颜色设置为 0 使得立方体的B能摭挡立方体A
    // 立方体 A,设置 renderOrder 为 1
    const materialA = new THREE.MeshPhongMaterial({ color: 0x00ff00 }); // 绿色
    const cubeA = new THREE.Mesh(cubeGeometry, materialA);
    cubeA.position.set(-5, 0, 0);
    cubeA.renderOrder = 1; // 先渲染
    scene.add(cubeA);
    
    // 立方体 B,设置 renderOrder 为 0
    const materialB = new THREE.MeshPhongMaterial({ color: 0xff0000,colorWrite: false }); // 红色
    const cubeB = new THREE.Mesh(cubeGeometry, materialB);
    cubeB.position.set(5, 0, 0);
    cubeB.renderOrder = 0; // 后渲染
    scene.add(cubeB);
  • defines 注入shader的自定义对象,由于太过复杂,请移步 three 官方文档
  • depthFunc 使用何种深度函数 取值范围为正面列表
    `THREE.NeverDepth` 总是失败。新片元不会被绘制,无论其深度值如何。这可以用于在特定情况下禁用深度测试。
    `THREE.AlwaysDepth` 总是通过深度测试。无论新片元的深度值是多少,它总是会被绘制。适用于需要始终渲染的情况,例如在深度缓冲区上绘制效果图。
    `THREE.LessDepth` 仅当新片元的深度值小于当前深度缓冲区中的值时,新片元才会被绘制。这是最常用的设置,通常用于前景物体遮挡背景物体。
    `THREE.LessEqualDepth` 仅当新片元的深度值小于或等于当前深度缓冲区中的值时,新片元才会被绘制。这通常用于不完全遮挡的效果。
    `THREE.GreaterDepth` 仅当新片元的深度值大于当前深度缓冲区中的值时,新片元才会被绘制。这通常用于渲染反向效果。
    `THREE.GreaterEqualDepth` 仅当新片元的深度值大于或等于当前深度缓冲区中的值时,新片元才会被绘制。这通常用于不完全遮挡的效果。
    `THREE.EqualDepth` 仅当新片元的深度值等于当前深度缓冲区中的值时,新片元才会被绘制。这可以用于特殊效果,比如只渲染深度值完全匹配的部分。
    `THREE.NotEqualDepth` 仅当新片元的深度值不等于当前深度缓冲区中的值时,新片元才会被绘制。用于渲染具有不同深度值的部分。
    //  此物体总会被显示
    const materialA = new THREE.MeshBasicMaterial({ 
        color: 0xff0000,
        transparent: true, // 启用透明度
        depthFunc: THREE.AlwaysDepth // 确保只有深度较小的物体被渲染
    });
    //  正常摭挡
    const materialA = new THREE.MeshBasicMaterial({ 
        color: 0xff0000,
        transparent: true, // 启用透明度
        depthFunc: THREE.LessDepth // 确保只有深度较小的物体被渲染
    });
  • depthTest 深度测试 下面两个立方体当深度测试为 false 是不会摭挡,为 true 是正常摭挡
    // 立方体 A,设置 renderOrder 为 1
    const materialA = new THREE.MeshPhongMaterial({ color: 0x00ff00, depthTest: false }); // 绿色
    const cubeA = new THREE.Mesh(cubeGeometry, materialA);
    cubeA.position.set(-5, 0, 0);
    scene.add(cubeA);
    // 立方体 B,设置 renderOrder 为 0
    const materialB = new THREE.MeshPhongMaterial({ color: 0xff0000, depthTest: false}); // 红色
    const cubeB = new THREE.Mesh(cubeGeometry, materialB);
    cubeB.position.set(5, 0, 0);
    scene.add(cubeB);
  • depthWrite 物体的深度信息会影响其他物体的渲染顺序 为 true 是深度影晌渲染,为false 时深度不影晌渲染,即 Z 轴。 当值为 false 时 后渲染的总是在前方,不受深度影晌
  • forceSinglePass 默认值 false 当渲染大量的双面透明物体时设置为true可以提升性能 side: THREE.DoubleSide 这个设置材质为双面渲染 opacity 设置透明
  • isMaterial 检查对象是否为材质 只读属性
  • stencilWrite 模板是否启用 写入操作 在使用这个属性之前需要先在 const renderer = new THREE.WebGLRenderer({stencil: true}); 渲染器中启用模板 还有一点要注意就是在第一比较材质中要设置 stencilFunc: THREE.AlwaysStencilFunc, stencilZPass: THREE.ReplaceStencilOp 比较方法为 AlwaysStencilFunc 这样就能初始化缓冲区的值 参与比较 否则缓冲区没有比较对象 stencilZPass 这个是为了设置缓冲区的值 在下面示例中一个使用了 EqualStencilFunc 这个来为红色立方体做了以绿色立方体的可视方的裁剪,一个使用了NotEqualStencilFunc 为用绿色立方体为红色立方体做了描边
  • stencilRef 模板基准值。
  • stencilFuncMask 模板遮罩 模板遮罩计算方式比较复杂,感性趣的朋友自行了解下
  • stencilFunc 比较函数 模板启用后的比较函数 下列是属性值列表
    `THREE.NeverStencilFunc` 总是拒绝通过测试。
    `THREE.LessStencilFunc` 通过测试,如果模板缓冲区中的值小于参考值。
    `THREE.EqualStencilFunc` 通过测试,如果模板缓冲区中的值等于参考值。
    `THREE.LequalStencilFunc` 通过测试,如果模板缓冲区中的值小于或等于参考值。
    `THREE.GreaterStencilFunc` 通过测试,如果模板缓冲区中的值大于参考值。
    `THREE.NotEqualStencilFunc` 通过测试,如果模板缓冲区中的值不等于参考值。
    `THREE.GequalStencilFunc` 通过测试,如果模板缓冲区中的值大于或等于参考值。
    `THREE.AlwaysStencilFunc` 总是通过测试。
  • stencilFail 当比较函数没有通过的时候要执行的模板操作 取值为下面列表
  • stencilZFail 当比较函数通过了但是深度检测没有通过的时候要执行的模板操作 取值为下面列表
  • stencilZPass 当比较函数和深度检测都通过时要执行的模板操作 取值为下面列表
    ZeroStencilOp 将模板值设置为0KeepStencilOp 不会对模板值进行任何操作。
    ReplaceStencilOp 使用模板基准值覆盖模板值。
    IncrementStencilOp 将当前模板值加1DecrementStencilOp 将当前模板值减1IncrementWrapStencilOp 将当前模板值加1,如果这个值超过了255则会设置为0DecrementWrapStencilOp 将当前模板值减1,如果这个值低于0则会设置为255
    InvertStencilOp 将当前模板值按位反转.
  • id 材质实例的唯一编号
  • name 对象的可选名称
  • meedsUpdate 指定需要重新编译材质
  • opacity 透明度 0.0 完全透明 1.0 完全不透明 需要将 transparent 属性设置为 true 才能生效
  • polygonOffset 启用多边形偏移 布尔值 默认为 false
  • polygonOffsetFactor 偏移因子 浮点数
  • polygonOffsetUnits 偏移单位 以下偏移使用示例
  • precision 重写此材质一默认精度 可以是 highp mediump lowp 这个属性在片段着色器与顶点着色器中使用。
        // 定义顶点着色器
        const vertexShader = `
            varying vec2 vUv;

            void main() {
                vUv = uv;
                gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            }
        `;

        // 定义片段着色器
        const fragmentShader = `
            varying vec2 vUv;

            void main() {
                vec3 color = vec3(vUv, 0.5);
                gl_FragColor = vec4(color, 1.0);
            }
        `;

        // 创建两个不同精度的材质
        const materialHighp = new THREE.ShaderMaterial({
            precision: "highp", // 设置精度为高
            vertexShader,
            fragmentShader
        });

        const materialLowp = new THREE.ShaderMaterial({
            precision: "lowp", // 设置精度为低
            vertexShader,
            fragmentShader
        });
  • premultipliedAlpha 是一个布尔属性,控制材质是否使用预乘 alpha(透明度)值。这对材质的混合模式和透明度处理有重要影响。
  • dithering 是否对颜色应用抖动以消除条带的外观。默认值为 false。消除颜色过度中有条纹 开启会增加一些性能开销
  • shadowSide 取值为下面列表 对于立方体,正方体外部的面都是正面,而内部的面都是反面。
    THREE.FrontSide 只为物体的正面投射阴影。默认情况下,物体的正面被渲染。
    THREE.BackSide 只为物体的背面投射阴影。
    THREE.DoubleSide 同时为物体的正面和背面投射阴影。
    // 示例只希望材质在正面被照射时才出现阴影
    const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
    material.shadowSide = THREE.FrontSide; 
    const mesh = new THREE.Mesh(geometry, material);
    mesh.castShadow = true;
  • side 默认为THREE.FrontSide。其他选项有THREE.BackSide 和 THREE.DoubleSide。
  • toneMapped 定义这个材质是否会被渲染器的 toneMapping 设置所影响,默认为 true,当为假时会使得映射更亮,这个与材质有关当材质为 MeshStandardMaterial 时效果明显。 先了解下 renderer.toneMapping 这个属性是渲染器的属性取值有下面列表
     `THREE.NoToneMapping`:不应用色调映射。
    `THREE.LinearToneMapping`:线性色调映射。
    `THREE.ReinhardToneMapping`:一种常见的压缩高亮区域的色调映射算法。
    `THREE.CineonToneMapping`:模拟电影胶片的色调映射。
    `THREE.ACESFilmicToneMapping`:适用于电影渲染的色调映射算法。
  • type 值为 Material 默认植
  • uuid 当前材质的惟一ID
  • version 默认为 0 每调用一次 needsUpdate 为 true 加 1
  • vertexColors 启用顶点颜色 详情请看示例
    // 创建几何体,例如一个平面
    const geometry = new THREE.PlaneGeometry(1, 1, 1, 1);
    // 创建一个 Float32Array 来存储顶点颜色
    const colors = new Float32Array([
      1, 0, 0, // 顶点1的颜色:红色
      0, 1, 0, // 顶点2的颜色:绿色
      0, 0, 1, // 顶点3的颜色:蓝色
      1, 1, 0  // 顶点4的颜色:黄色
    ]);
    // 将颜色添加到几何体的 attributes 中
    geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
    // 创建材质,并启用 vertexColors
    const material = new THREE.MeshBasicMaterial({
      vertexColors: true, // 启用顶点颜色
      side: THREE.DoubleSide // 双面显示
    });
    // 创建网格
    const plane = new THREE.Mesh(geometry, material);
    // 添加到场景中
    scene.add(plane);
  • visible 材质是否可见
  • userData 默认为 false 当前材质的自定义数据
  • clone 方法 无参数 将当前材质的参数属性考贝返回
  • copy 方法 一个参数 类型为材质 将参数中的材质属性复制到当前属性中
  • dispose 方法 无参数 销毁材质的纹理
  • onBeforeCompile 自定义方法 一个参数 为three 自动传入 参数是片元着色器对象。
  • onBeforeRender 材质渲染之前的回调 六个参烽 为 three 自动传入 renderer, scene, camera, geometry, material, group 在回调中可以定义任意几何的本的操作 onBeforeCompile 方法先于这个回调执行
  • customProgramCacheKey 自定义缓存键 通过返回值判断是否需要重新编译片元着色器 在下面示例中当 black 改变是缓存也会从 0 与 1 切换 而后片元着色器钩子,会替换掉对应的值。这样,你可以确保在渲染过程中根据 black 的状态,材质使用不同的着色器程序,并且避免缓存冲突。
    // 自定义 onBeforeCompile 钩子
    material.onBeforeCompile = function (shader) {
      if (black) {
        shader.fragmentShader = shader.fragmentShader.replace('gl_FragColor = vec4(1)', 'gl_FragColor = vec4(0)');
      }
    };
    // 自定义程序缓存键
    material.customProgramCacheKey = function() {
      return black ? '1' : '0';
    };
  • setValues 方法 一个参数 类型对象 将材质的属性设置为对象内对应属性值
  • toJSON 将 访对象的纹理或图片等元数据转换为 three 中的 JSON