在 Three.js 中,
ShaderChunk是一个非常重要的概念,主要用于管理和组织着色器代码的片段。它允许开发者重用着色器的常见部分,以提高代码的可维护性和可读性。
在 Three.js 中,ShaderLib是一个存储了一些预定义着色器库的对象,它提供了多种常见材质的着色器代码,可以帮助开发者快速创建各种效果。通过使用这些内置的着色器库,开发者可以省去自己编写基础着色器的时间,同时还可以根据自己的需求进行扩展或修改。
在 Three.js 中,UniformsLib是一个用于管理着色器中 uniforms 的集合,它提供了各种常用的 uniforms,如光照、环境贴图、雾等。UniformsLib可以帮助开发者快速配置和使用这些 uniforms,而不需要手动定义每一个。
THREE.UniformsUtils是 Three.js 中用于管理和合并 uniforms 的工具类,特别适用于着色器程序。在自定义着色器时,您可能需要将不同的 uniforms 组合在一起,以便为顶点和片元着色器提供所需的数据。以下是UniformsUtils的主要功能和一个使用示例。
ShaderChunk 使用示例
// 定义自定义 ShaderChunk
THREE.ShaderChunk['myCustomChunk'] = `
vec3 myCustomFunction(vec3 color) {
return color * 0.5; // 简单的颜色减半示例
}
`;
// 自定义材质
const customMaterial = new THREE.ShaderMaterial({
vertexShader: `
varying vec3 vColor;
void main() {
vColor = position; // 将立方体的顶点位置作为颜色值
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
varying vec3 vColor;
// 引入自定义代码片段
#include <myCustomChunk>
void main() {
vec3 finalColor = myCustomFunction(vColor * 0.5 + 0.5); // 使用自定义函数处理颜色
gl_FragColor = vec4(finalColor, 1.0);
}
`
});
// 创建立方体几何体
const geometry = new THREE.BoxGeometry();
const cube = new THREE.Mesh(geometry, customMaterial);
scene.add(cube);
ShaderLib 有以下属性列表
**`basic`** - 基础材质的着色器。
**`lambert`** - 使用 Lambertian 反射模型的材质。
**`phong`** - 使用 Phong 反射模型的材质。
**`standard`** - 物理基础渲染(PBR)材质,适用于现代光照模型。
**`physical`** - 基于物理的材质,通常用于需要更复杂的光照和反射效果。
**`depth`** - 深度测试用的着色器,通常用于后期处理效果。
**`normal`** - 用于显示法线信息的着色器。
**`meshbasic`** - 适用于简单的基础材质。
**`meshlambert`** - 适用于 Lambert 材质。
**`meshphong`** - 适用于 Phong 材质。
**`meshstandard`** - 适用于标准 PBR 材质。
**`meshphysical`** - 适用于物理 PBR 材质。
**`sprite`** - 精灵的着色器,用于2D效果。
**`line`** - 线条的着色器,用于渲染线条几何体。
**`points`** - 点的着色器,用于渲染粒子效果。
// 创建几何体
const geometry = new THREE.BoxGeometry(10, 10, 10);
// 复制 THREE.ShaderLib.basic
const basicShader = { ...THREE.ShaderLib.basic };
// 使用 replace 方法替换片元着色器代码
basicShader.fragmentShader = `
varying vec3 vNormal; // 接收法线
varying vec3 vViewPosition; // 视点位置
uniform vec3 diffuse; // 用于替换颜色的 Uniform
void main() {
// 设置颜色为红色
gl_FragColor = vec4(1.0,0.0,0.0, 1.0); // RGBA
}
`;
// 创建自定义材质,使用替换后的着色器
const material = new THREE.ShaderMaterial({
uniforms: basicShader.uniforms,
vertexShader: basicShader.vertexShader,
fragmentShader: basicShader.fragmentShader,
});
// 创建网格并添加到场景
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
# UniformsLib 有以下属性
`lights` 用于光照的 uniforms,包含以下属性:
- `ambient`: 环境光颜色。
- `directionalLight[0].color`: 第一个方向光的颜色。
- `directionalLight[0].direction`: 第一个方向光的方向。
- `directionalLight[0].intensity`: 第一个方向光的强度。
- `pointLight[0].color`: 第一个点光源的颜色。
- `pointLight[0].position`: 第一个点光源的位置。
- `pointLight[0].intensity`: 第一个点光源的强度。
- `spotLight[0].color`: 第一个聚光灯的颜色。
- `spotLight[0].position`: 第一个聚光灯的位置。
- `spotLight[0].direction`: 第一个聚光灯的方向。
- `spotLight[0].angle`: 第一个聚光灯的角度。
- `spotLight[0].intensity`: 第一个聚光灯的强度。
`fog` 用于雾效果的 uniforms,包含以下属性:
- `fog.color`: 雾的颜色。
- `fog.near`: 雾开始的距离。
- `fog.far`: 雾结束的距离。
`envMap` 用于环境映射的 uniforms,包含以下属性:
- `envMap`: 环境贴图纹理。
- `reflectivity`: 反射率。
`map` 用于纹理映射的 uniforms,包含以下属性:
- `map`: 基础纹理。
- `alphaMap`: 透明纹理。
- `lightMap`: 光照贴图。
- `aoMap`: 环境光遮蔽贴图。
- `emissiveMap`: 自发光贴图。
`skin` 用于皮肤渲染的 uniforms,包含以下属性:
- `boneTexture`: 骨骼纹理。
- `boneCount`: 骨骼数量。
- `skinWeight`: 皮肤权重。
`fog` 用于雾效果的 uniforms,包含以下属性:
- `fog.color`: 雾的颜色。
- `fog.near`: 雾开始的距离。
- `fog.far`: 雾结束的距离。
// 添加光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(10, 10, 10);
scene.add(pointLight);
// 创建几何体
const geometry = new THREE.BoxGeometry(10, 10, 10);
// 从 UniformsLib 获取光照和雾相关的 uniforms
const uniforms = THREE.UniformsUtils.merge([
THREE.UniformsLib.lights, // 添加光照 uniforms
]);
// 自定义材质
const material = new THREE.ShaderMaterial({
uniforms: uniforms,
lights: true, // 启用光照
vertexShader: `
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vNormal = normalize(normalMatrix * normal);
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
uniform vec3 diffuse;
varying vec3 vNormal;
void main() {
vec3 normal = normalize(vNormal);
vec3 lightDirection = normalize(vec3(1.0, 1.0, 1.0)); // 光源方向
float brightness = max(dot(normal, lightDirection), 0.0);
gl_FragColor = vec4(diffuse * brightness, 1.0); // 计算最终颜色
}
`,
});
// 设置材质的扩散颜色(例如红色)
material.uniforms.diffuse = { value: new THREE.Color(1.0, 0.0, 0.0) }; // 红色
// 创建网格并添加到场景
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
UniformsUtils 有两个方法
- clone ( src : Object ) : Object src -- 表示定义uniforms的对象的路径 通过执行深层复制克隆给定的统一定义。 这意味着如果uniform的[page:Uniform.value 值]引用Vector3或Texture之类的对象,则克隆的uniform将引用新的对象引用。
// 定义一个包含一些 uniforms 的对象
const originalUniforms = {
diffuse: { value: new THREE.Color(0xff0000) },
opacity: { value: 1.0 },
lightPosition: { value: new THREE.Vector3(10, 10, 10) }
};
// 克隆原始 uniforms 对象
const clonedUniforms = THREE.UniformsUtils.clone(originalUniforms);
// 修改克隆对象的某个属性
clonedUniforms.diffuse.value.set(0x00ff00); // 将颜色改为绿色
console.log('Original Uniforms:', originalUniforms); // 原始 uniforms 仍然是红色
console.log('Cloned Uniforms:', clonedUniforms); // 克隆的 uniforms 是绿色
- merge ( uniforms : Array ) : Object uniforms -- 包含uniforms定义的对象数组 将给定的统一定义合并到一个对象中。由于该方法在内部使用.clone(),因此它在生成合并的统一定义时执行深度复制。