- three.js的安装及使用
- 使用 Three.js 创建一个场景(Creating a Scene)
- 使用 Three.js 进行 WebGL 兼容性检查
- 使用 Three.js 进行线条绘制(Drawing Lines)
- 使用 Three.js 创建文字(Creating Text)
- 使用 Three.js 载入 3D 模型(Loading 3D Models)
- 使用 Three.js 更新场景(How to Update Things)
- 使用 Three.js 废置对象(How to Dispose of Objects)
- 使用 Three.js 创建 VR 内容(How to Create VR Content)
- 使用 Three.js 实现后期处理(How to Use Post-Processing)
- 使用 Three.js 进行矩阵变换(Matrix Transformations)
- 使用 Three.js 动画系统(Animation System)
- 使用 Three.js 框架中的 AnimationAction
- 使用 Three.js 框架中的 AnimationClip
- Three.js 框架中的 AnimationMixer 使用详解
- Three.js 框架中的 AnimationObjectGroup 使用详解
- Three.js 框架中的 AnimationUtils 使用详解
- Three.js 框架中的 KeyframeTrack 使用详解
- Three.js 框架中的 PropertyBinding 使用详解
- Three.js 框架中的 PropertyMixer 使用详解
- Three.js 框架中 BooleanKeyframeTrack 的使用详解
- Three.js 框架中 ColorKeyframeTrack 的使用详解
- Three.js 框架中的 NumberKeyframeTrack 使用详解
- Three.js 框架中的 QuaternionKeyframeTrack 使用详解
- Three.js 框架中的 StringKeyframeTrack 使用详解
- Three.js 框架中的 VectorKeyframeTrack 使用详解
- Three.js 框架中的音频(Audio)使用详解
- Three.js 框架中的音频分析器(AudioAnalyser)使用详解
- Three.js 框架中 `AudioContext` 的使用详解
- Three.js 框架中的 `AudioListener` 使用详解
- Three.js 框架中的 `PositionalAudio` 使用详解
- Three.js 框架中的 `ArrayCamera` 使用详解
- Three.js 框架中的 Camera 使用详解
- Three.js 中 CubeCamera 的使用详解
- Three.js 框架:`OrthographicCamera` 与音频的使用详解
- Three.js 中 PerspectiveCamera 的使用详解
- Three.js 框架中的 StereoCamera 使用详解
- Three.js 框架中的动画常量(Animation Constants)详解
- Three.js 框架中的常量——自定义混合方程常量(Custom Blending Equation Constants)详解
- Three.js 框架中的常量——Material Constants 使用详解
- Three.js 框架中的常量——WebGLRenderer Constants 使用详解
- Three.js 框架中的常量——Texture Constants 使用详解
- Three.js 框架中的常量——Core Constants 使用详解
- Three.js 框架中 `BufferAttribute` 的使用详解
- Three.js 框架中 `BufferGeometry` 的使用详解
- Three.js 框架中 `Clock` 的使用详解
- Three.js 框架中的 `EventDispatcher` 使用详解
- Three.js 框架中的 `GLBufferAttribute` 使用详解
- Three.js 框架中的 `InstancedBufferAttribute` 使用详解
- Three.js 框架中的 `InstancedBufferGeometry` 使用详解
- Three.js 框架中的 `InstancedInterleavedBuffer` 使用详解
- Three.js 框架中的 `InterleavedBufferAttribute` 使用详解
- Three.js 框架中的 `Layers` 使用详解
- Three.js 的 Object3D
- Three.js 的 Raycaster
- Three.js 框架中的 `Uniform` 使用详解
- Three.js 框架中 BufferAttribute Types 的使用详解
- 从入门到精通 Three.js 的 DataUtils
- 从入门到精通 Three.js 的 Earcut
- 深入了解 Three.js 中的 ImageUtils
- 深入了解 Three.js 中的 PMREMGenerator
- 深入了解 Three.js 中的 ShapeUtils
- 深入了解 Three.js 中的 Curve
- 深入了解 Three.js 中的 CurvePath
- 插值(Interpolations)
- 路径(Path)
- 形状(Shape)
- 形状路径(ShapePath)
- Three.js 框架中的弧线(ArcCurve)使用详解
- 深入解析 Three.js 中的 CatmullRomCurve3 使用
- 深入解析 Three.js 中的二维三次贝塞尔曲线(CubicBezierCurve)使用
- 深入解析 Three.js 中的三维三次贝塞尔曲线(CubicBezierCurve3)使用
- 深入解析 Three.js 中的椭圆曲线(EllipseCurve)使用
- 深入解析 Three.js 中的二维线段曲线(LineCurve)
- 深入解析 Three.js 框架中三维线段曲线(LineCurve3)的使用
- 深入解析 Three.js 框架中二维二次贝塞尔曲线(QuadraticBezierCurve)的使用
- 深入理解与应用 Three.js 的三维二次贝塞尔曲线(QuadraticBezierCurve3)
- Three.js 框架中的样条曲线(SplineCurve)的使用
- Three.js 框架中的立方缓冲几何体(BoxGeometry)使用
- Three.js 中的CapsuleGeometry使用
- Three.js 中的 CircleGeometry 使用详解
- 深入了解 Three.js 框架中的 ConeGeometry 使用
- 深入了解 Three.js 框架中的 CylinderGeometry 使用
- 深入理解 Three.js 中的 DodecahedronGeometry 使用
Three.js 框架中的 `Uniform` 使用详解
class UniformUniform
在 Three.js 中用于在自定义着色器中传递全局变量。通过 Uniform
,我们可以将 JavaScript 层的数据传递给 WebGL 着色器(Shader),并在着色器程序的运行过程中保持这些数据的一致性。在复杂的三维场景渲染中,Uniform
对于处理材质效果、动画、光照和交互等操作非常关键。
本文将详细介绍 Uniform
的使用,包括属性、方法、示例代码,以及如何结合其他组件使用 Uniform
,帮助你掌握在 Three.js 中使用 Uniform
的技巧。
1. 什么是 Uniform
Uniform
是 WebGL 中用于在顶点和片段着色器中传递一致数据的变量。与 attribute
和 varying
不同,Uniform
是全局变量,每次渲染时,它们的值对所有顶点或片段都保持一致。这意味着 Uniform
的值是每一帧在 JavaScript 层面更新后传递到 GPU 的,在着色器中,它们不会随着顶点或片段的变化而变化。
在 Three.js 中,Uniform
可以用于控制诸如光照强度、材质属性、时间变量等。
2. Uniform
的基本使用
Three.js 提供了一个 Uniform
类,并且自定义着色器材质(如 ShaderMaterial
)中的 uniforms
属性就是通过它来定义的。以下是定义和使用 Uniform
的基本步骤。
2.1 定义 Uniform
当我们使用 ShaderMaterial
时,可以在 uniforms
对象中定义所有需要传递给着色器的全局变量。每个 uniform
都需要指定类型和值。
const uniforms = {
time: { value: 1.0 },
resolution: { value: new THREE.Vector2() },
color: { value: new THREE.Color(0xff0000) }
};
time
:这是一个浮点数类型的uniform
,它的值随着时间变化。resolution
:这是一个Vector2
类型的uniform
,表示屏幕的分辨率。color
:这是一个Color
类型的uniform
,表示一个颜色值。
2.2 在 ShaderMaterial
中使用 uniforms
在创建 ShaderMaterial
时,我们可以将 uniforms
传递给它,并在顶点和片段着色器中使用这些 uniform
变量。
const material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: vertexShaderCode,
fragmentShader: fragmentShaderCode
});
vertexShaderCode
和 fragmentShaderCode
分别表示顶点着色器和片段着色器的代码。
2.3 使用 Uniform
传递数据
在 Three.js 的渲染循环中,我们可以通过修改 uniforms
对象中的值来控制着色器的行为。例如,我们可以根据时间动态更新 time
uniform。
function animate() {
requestAnimationFrame(animate);
// 动态更新 time uniform
uniforms.time.value += 0.05;
renderer.render(scene, camera);
}
animate();
在每一帧中,uniforms.time.value
的值都会增加,这样我们就可以在着色器中根据时间来控制动画效果。
3. Uniform
的数据类型
在 WebGL 中,Uniform
支持多种数据类型,每种类型对应着不同的值结构。以下是 Three.js 中常用的 Uniform
数据类型及其对应的 JavaScript 类型。
float
:对应THREE.Uniform({ value: 0.0 })
,表示一个浮点数。vec2
:对应THREE.Uniform({ value: new THREE.Vector2(x, y) })
,表示一个二维向量。vec3
:对应THREE.Uniform({ value: new THREE.Vector3(x, y, z) })
,表示一个三维向量。vec4
:对应THREE.Uniform({ value: new THREE.Vector4(x, y, z, w) })
,表示一个四维向量。mat3
:对应THREE.Uniform({ value: new THREE.Matrix3() })
,表示一个 3x3 矩阵。mat4
:对应THREE.Uniform({ value: new THREE.Matrix4() })
,表示一个 4x4 矩阵。sampler2D
:对应THREE.Uniform({ value: texture })
,表示一个二维纹理。
示例代码
const uniforms = {
time: { value: 0.0 },
color: { value: new THREE.Color(0x00ff00) },
texture: { value: new THREE.TextureLoader().load('path/to/texture.jpg') }
};
在这个例子中,我们定义了三个 uniforms
:一个时间变量 time
、一个颜色变量 color
和一个纹理变量 texture
。
4. Uniform
的属性和方法
Three.js 中的 Uniform
主要有两个属性:value
和 needsUpdate
。
4.1 value
value
是 Uniform
的核心属性,它表示传递给着色器的值。你可以随时更新 value
,它的变化会直接影响着色器中的变量。
uniforms.time.value = performance.now() / 1000; // 根据时间更新 time
4.2 needsUpdate
needsUpdate
是一个布尔值,用于告诉渲染器当前 Uniform
的值是否需要更新。在大多数情况下,Three.js 会自动检测 Uniform
是否需要更新,但在一些特殊情况下,你可以手动设置 needsUpdate = true
来强制更新。
uniforms.texture.needsUpdate = true; // 强制更新纹理
5. Uniform
使用的完整示例
下面是一个完整的示例,展示了如何在 Three.js 中使用 Uniform
动态控制着色器中的动画效果。
示例:使用 Uniform
控制时间动画
// 创建场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 定义 uniforms
const uniforms = {
time: { value: 0.0 },
resolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) }
};
// 定义着色器
const vertexShader = `
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const fragmentShader = `
uniform float time;
uniform vec2 resolution;
void main() {
vec2 uv = gl_FragCoord.xy / resolution;
vec3 color = vec3(0.5 + 0.5 * cos(time + uv.xyx + vec3(0, 2, 4)));
gl_FragColor = vec4(color, 1.0);
}
`;
// 创建材质
const material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader
});
// 创建几何体和网格对象
const geometry = new THREE.PlaneGeometry(2, 2);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// 设置相机位置
camera.position.z = 1;
// 渲染循环
function animate() {
requestAnimationFrame(animate);
// 更新时间 uniform
uniforms.time.value += 0.05;
renderer.render(scene, camera);
}
animate();
在这个示例中,我们创建了一个简单的片段着色器,通过 time
uniform 实现了颜色随时间变化的动画效果。resolution
uniform 则确保了片段着色器根据屏幕分辨率正确绘制。
6. 结合其他组件使用 Uniform
6.1 与 TextureLoader
一起使用
Uniform
经常用于传递纹理数据到着色器中。例如,我们可以使用 THREE.TextureLoader
来加载纹理,并将其传递给着色器。
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('path/to/texture.jpg');
const uniforms = {
texture: { value: texture }
};
在着色器中,我们可以通过 sampler2D
类型的 uniform
来访问这个纹理,并根据纹理的颜色信息进行渲染。
6.2 与 Clock
一起使用
Three.js 中的 Clock
对象非常适合与 Uniform
结合使用来实现基于时间的动画。通过 Clock.getElapsedTime()
,
我们可以获取程序运行的总时间,并将其传递给 time
uniform。
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
// 使用 Clock 获取经过的时间
uniforms.time.value = clock.getElapsedTime();
renderer.render(scene, camera);
}
animate();
7. 总结
Uniform
是 Three.js 中用于在 JavaScript 和着色器之间传递全局数据的关键机制。通过 Uniform
,我们可以动态控制渲染效果、动画、光照等场景中的重要元素。本文详细介绍了 Uniform
的基本概念、使用方法、属性,以及如何与其他组件结合使用的示例。
希望通过本文的学习,你能够熟练掌握 Uniform
在 Three.js 中的使用,并在项目中创造更加丰富的视觉效果。如果你在项目中需要自定义着色器或动态控制场景元素,Uniform
将是不可或缺的工具。