shader知识点
约 1100 字大约 4 分钟
2025-05-07
GLSL 函数
算术函数
函数名 | 描述 |
---|---|
abs(x) | 返回 x 的绝对值 |
sign(x) | 返回 x 的符号,如果 x 是正数,返回 1;如果 x 是负数,返回-1;如果 x 是 0,返回 0 |
floor(x) | 返回小于等于 x 的最大整数 |
ceil(x) | 返回大于等于 x 的最小整数 |
fract(x) | 返回 x 的小数部分 |
mod(x,y) | 返回 x 除以 y 的余数 |
max(x,y) | 返回 x 和 y 中的最大值 |
min(x,y) | 返回 x 和 y 中的最小值 |
mix(x,y,a) | 返回 x 和 y 的线性混合,a 是混合因子 |
clamp(x,min,max) | 返回 x 被限制在 min 和 max 之间的值 |
step(edge,x) | 如果 x 小于等于 edge,返回 0;否则返回 1 |
smoothstep(edge0,edge1,x) | 返回 x 在 edge0 和 edge1 之间的平滑插值 |
几何函数
函数名 | 描述 |
---|---|
length(v) | 返回向量 v 的长度 |
distance(v1,v2) | 返回向量 v1 和 v2 之间的距离 |
dot(v1,v2) | 返回向量 v1 和 v2 的点积 |
cross(v1,v2) | 返回向量 v1 和 v2 的叉积 |
normalize(v) | 返回向量 v 的单位向量 |
faceforward(n,i,nref) | 返回向量 n 的反射向量,i 是入射向量,nref 是法线向量 |
reflect(i,n) | 返回向量 i 的反射向量,n 是法线向量 |
refract(i,n,eta) | 返回向量 i 的折射向量,n 是法线向量,eta 是折射率 |
三角函数
函数名 | 描述 |
---|---|
radians(x) | 将角度 x 转换为弧度 |
degrees(x) | 将弧度 x 转换为角度 |
sin(x) | 返回 x 的正弦值 |
cos(x) | 返回 x 的余弦值 |
tan(x) | 返回 x 的正切值 |
asin(x) | 返回 x 的反正弦值 |
acos(x) | 返回 x 的反余弦值 |
atan(y,x) | 返回 y/x 的反正切值 |
sinh(x) | 返回 x 的双曲正弦值 |
cosh(x) | 返回 x 的双曲余弦值 |
tanh(x) | 返回 x 的双曲正切值 |
纹理函数
函数名 | 描述 |
---|---|
texture2D(s,v) | 从纹理 s 中采样,v 是纹理坐标,返回纹理的颜色值 |
texture2DProj(s,v) | 从纹理 s 中采样,v 是投影纹理坐标,返回纹理的颜色值 |
textureCube(s,v) | 从立方体纹理 s 中采样,v 是纹理坐标,返回纹理的颜色值 |
向量和矩阵函数
函数名 | 描述 |
---|---|
matrixCompMult(m1,m2) | 返回 m1 和 m2 的元素乘积 |
outerProduct(u,v) | 返回向量 u 和 v 的外积 |
transpose(m) | 返回矩阵 m 的转置矩阵 |
determinant(m) | 返回矩阵 m 的行列式 |
inverse(m) | 返回矩阵 m 的逆矩阵 |
着色器材质
ShaderMaterial:自定义着色器材质,可以完全控制顶点着色器和片元着色器的代码。
RawShaderMaterial:原始着色器材质,可以完全控制顶点着色器和片元着色器的代码,不会自动添加内置代码需要手动管理
uniform
变量。
差异
ShaderMaterial
和 RawShaderMaterial
都是 Threejs
中用于自定义着色器的材质,他们的主要差异在于 Threejs
对着色器代码的处理方式。
ShaderMaterial
会自动添加常用的 GLSL
代码和变量,而 RawShaderMaterial
则要求开发者完全手动编写所有 GLSL
代码。
// ShaderMaterial
const material = new THREE.ShaderMaterial({
vertexShader: `
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
});
// RawShaderMaterial
const material = new THREE.RawShaderMaterial({
vertexShader: `
attribute vec3 position;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
});
自定义 uniforms
在 Threejs
中,uniforms
是一种特殊的变量,可以在着色器中访问,并且可以在 JavaScript
代码中动态更新。uniforms
可以是任何类型,包括标量、向量、矩阵、纹理等。
使用
每个 uniforms
都是一个对象,包含一个 value
属性,例如:
const material = new THREE.ShaderMaterial({
uniforms: {
color: { value: new THREE.Color(0xff0000) },
},
});
传递纹理贴图
着色器类型材质不支持 map
属性做纹理贴图,需要使用 uniforms
传递纹理贴图,例如:
const material = new THREE.RawShaderMaterial({
vertexShader: vertexShader,
fragmentShader: fragmentShader,
uniforms: {
u_texture:{value:new THREE.TextureLoader().load('texture.jpg');}
}
})
这个 u_texture
就是传递给着色器的纹理贴图,可以直接在片元着色器中可以通过 uniform sampler2D u_texture
来访问这个纹理贴图。
uniform sampler2D u_texture;
void main(){
vec4 color = texture2D(u_texture,uv);
gl_FragColor = vec4(1.0,0.0,0.0,1.0)*color; //将纹理贴图的颜色和红色混合
}
sampler2D
是采样器类型,texture2D
是用于在片元着色器中对二维纹理采样的函数,uv
是纹理坐标,用于指定在纹理图像中采样的点。