RawShaderMaterial 与 ShaderMaterial

目录

[自动添加的 Uniforms 和 Attributes](#自动添加的 Uniforms 和 Attributes)

ShaderMaterial

RawShaderMaterial

[GLSL 预处理](#GLSL 预处理)

ShaderMaterial

RawShaderMaterial

使用场景

ShaderMaterial

RawShaderMaterial

代码示例对比

[使用 ShaderMaterial](#使用 ShaderMaterial)

[使用 RawShaderMaterial](#使用 RawShaderMaterial)

常见问题与注意事项

总结


在 Three.js 中,RawShaderMaterialShaderMaterial 都是用于自定义着色器的材质类,但它们的核心区别在于 Three.js 对着色器代码的预处理程度。以下是它们的详细对比:


自动添加的 Uniforms 和 Attributes

ShaderMaterial
  • Three.js 会 自动添加 常用的内置 uniforms 和 attributes,例如:

    • projectionMatrix(相机投影矩阵)

    • modelViewMatrix(模型视图矩阵)

    • viewMatrix(视图矩阵)

    • normalMatrix(法线矩阵)

    • cameraPosition(相机位置)

    • 光照、雾效等参数(如果启用相关功能)。

  • 你不需要在着色器代码中手动声明这些变量,Three.js 会隐式注入它们。

RawShaderMaterial
  • 不会自动添加任何内置变量,所有 uniforms 和 attributes 必须手动声明。

  • 你需要自己传递所有必需的参数(如矩阵、相机位置等)。


GLSL 预处理

ShaderMaterial
  • Three.js 会自动在着色器代码顶部插入一些预定义内容,例如:

    javascript 复制代码
    precision highp float; // 自动设置精度
    #include <common>      // 包含 Three.js 的通用 GLSL 代码块
  • 支持 Three.js 的 GLSL 代码块(如 #include <fog_pars_vertex>)。

RawShaderMaterial
  • 不进行任何预处理,所有 GLSL 代码必须完整且自包含。

  • 必须手动设置精度(如 precision highp float;)。

  • 无法直接使用 Three.js 的内置 GLSL 代码块。


使用场景

ShaderMaterial
  • 推荐大多数情况使用,尤其是需要 Three.js 内置功能(如光照、雾效)时。

  • 适合快速开发,减少重复代码。

RawShaderMaterial
  • 适用于需要 完全控制着色器代码 的高级场景。

  • 适合学习 WebGL 底层原理,或需要避免 Three.js 隐式行为干扰的情况。


代码示例对比

使用 ShaderMaterial
javascript 复制代码
const material = new THREE.ShaderMaterial({
  vertexShader: `
    void main() {
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    void main() {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  `,
});
  • 无需声明 projectionMatrixmodelViewMatrix,Three.js 已自动处理。
使用 RawShaderMaterial
javascript 复制代码
const material = new THREE.RawShaderMaterial({
  vertexShader: `
    precision highp float;
    uniform mat4 projectionMatrix;
    uniform mat4 modelViewMatrix;
    attribute vec3 position;
    
    void main() {
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    precision highp float;
    
    void main() {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  `,
});
  • 必须手动声明所有 uniforms 和 attributes(如 projectionMatrixposition)。

  • 必须手动设置精度(precision highp float;)。


常见问题与注意事项

  • 错误处理

    使用 RawShaderMaterial 时,若忘记声明必要的 uniforms/attributes,会导致着色器编译失败,但 Three.js 可能不会明确提示具体原因。

  • 性能差异

    两者性能几乎无差异,最终都会被编译为 WebGL 着色器程序。

  • 兼容性

    如果从 ShaderMaterial 切换到 RawShaderMaterial,需确保着色器代码中不再依赖 Three.js 的隐式变量(如 vNormalvViewPosition 等)。


总结

特性 ShaderMaterial RawShaderMaterial
内置变量支持 自动添加 需手动声明
GLSL 预处理 自动插入精度、代码块 完全手动编写
适合场景 常规需求、快速开发 完全控制、学习 WebGL 底层
代码复杂度

选择依据:

  • 如果需要快速实现常见效果(如光照、雾效),用 ShaderMaterial

  • 如果需要彻底掌控着色器逻辑,或避免 Three.js 的隐式行为,用 RawShaderMaterial

相关推荐
一代明君Kevin学长5 分钟前
快速自定义一个带进度监控的文件资源类
java·前端·后端·python·文件上传·文件服务·文件流
4Forsee14 分钟前
【Android】动态操作 Window 的背后机制
android·java·前端
用户904438163246019 分钟前
从40亿设备漏洞到AI浏览器:藏在浏览器底层的3个“隐形”原理
前端·javascript·浏览器
小二李23 分钟前
第12章 koa框架重构篇 - Koa框架项目重构
java·前端·重构
鸡吃丸子27 分钟前
React Native入门详解
开发语言·前端·javascript·react native·react.js
阿蒙Amon31 分钟前
JavaScript学习笔记:12.类
javascript·笔记·学习
qq_4287232434 分钟前
英语歌10个月之前启蒙磨耳朵
前端
Hao_Harrision37 分钟前
50天50个小项目 (React19 + Tailwindcss V4) ✨ | DrinkWater(喝水记录组件)
前端·react.js·typescript·vite7·tailwildcss
SadSunset44 分钟前
(19)Bean的循环依赖问题
java·开发语言·前端
JIngJaneIL1 小时前
基于Java+ vue图书管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端