定义Material
class ColorMaterial extends ShaderMaterial {
constructor(params: { u_mvpMatrix: Matrix4, u_color: Vector4 }) {
super();
this.vertexShader = VERTEX_SHADER_SOURCE;
this.fragmentShader = FRAGMENT_SHADER_SOURCE;
this.vertexColors = true; // 要使用顶点着色器定义顶点颜色
this.uniforms = {
u_mvpMatrix: {
value: params.u_mvpMatrix
},
u_color: {
value: params.u_color
}
}
}
}
在定义ShaderMaterial 的时候要指定 vertexColors = true; 这样threejs 会在顶点着色器中定义一个 vec3 color/ vec4 color 属性,具体定义成vec3, 还是vec4 就由你定义的值有关;通过下面讲解
定义BufferGeometry
const cube = createCubeVertices(2)
const faceColors: number[][] = [
[1, 0, 0, 1],
[0, 1, 0, 1],
[1, 1, 0, 1],
[0, 0, 1, 1],
[1, 0, 1, 1],
[0, 1, 1, 1],
]
var colorVerts: number[] = [];
for (var f = 0; f < 6; ++f) {
for (var v = 0; v < 4; ++v) {
colorVerts = colorVerts.concat(faceColors[f]);
}
}
const buffer = new BufferGeometry();
const positions = new Float32BufferAttribute(cube.position.array, 3)
const colors = new Float32BufferAttribute(colorVerts, 4);
buffer.setAttribute('position', positions);
buffer.setAttribute('color', colors);
buffer.setIndex([...cube.indices.array]);
在上面我们在BufferGeometry 中定义的color 属性是一个 vec4 变量,在合建程序对象的时候,threejs 会先生成 一个程序对象的配置参数
vertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4,
判断当前材质有没有定义 vertexColors,然后才根据属性的数量来决定vertexAlphas 的值。 这个值将决定着色器模块的内容。 下面是在生成着色器前的宏定义
parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
可以看到 vertexAlphas 如果存在 就会增加一个宏定义,这个宏定义又直接影响了着色器中color 属性的类型;下面是定义着色器的代码
'#if defined( USE_COLOR_ALPHA )',
' attribute vec4 color;',
'#elif defined( USE_COLOR )',
' attribute vec3 color;',
'#endif',
综上可知,
- 在ShaderMaterial 中设置vertexColors = true
- 在定义BufferGeometry 的时候 将color值定义为一个vec4 的量
这样 着色器中就能使用alpha 值了。