返回

驾驭WebGL,深入绘制3D六色立方体

前端

你好,亲爱的读者,欢迎来到WebGL的奇妙世界。在上一篇文章中,我们探索了绘制渐变色立方体的迷人之旅。然而,今天,我们将踏上更进一步的征程,揭开如何绘制六面为不同纯色的立方体的奥秘。

理解顶点着色器

WebGL之旅始于顶点着色器,它就像魔法棒,将每个顶点转化为屏幕上的像素。为了实现我们的目标,我们需要编写一个自定义顶点着色器,它将赋予我们的立方体每一面的不同颜色。

// 顶点着色器
void main() {
    // 根据顶点的索引分配颜色
    vec3 color;
    int index = gl_VertexIndex % 6;  // 0-5表示立方体的6个面
    if (index == 0) { color = vec3(1, 0, 0); }  // 红色
    else if (index == 1) { color = vec3(0, 1, 0); }  // 绿色
    else if (index == 2) { color = vec3(0, 0, 1); }  // 蓝色
    else if (index == 3) { color = vec3(1, 1, 0); }  // 黄色
    else if (index == 4) { color = vec3(1, 0, 1); }  // 品红
    else { color = vec3(0, 1, 1); }  // 青色

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
    vColor = color;
}

片段着色器的魔力

旅程的下一站是片段着色器,它是决定每个像素最终颜色的魔法师。为了匹配顶点着色器赋予的颜色,我们必须编写一个片段着色器来处理这些颜色。

// 片段着色器
void main() {
    // 直接输出顶点着色器分配的颜色
    gl_FragColor = vColor;
}

整合代码,释放色彩

现在,我们有了顶点着色器和片段着色器,是时候将它们组合起来,让六色立方体跃然屏幕了。

// 获取着色器
var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

// 创建着色器程序
var shaderProgram = createProgram(gl, vertexShader, fragmentShader);

// 绑定着色器程序
gl.useProgram(shaderProgram);

构建六色立方体

现在,让我们构建立方体的几何形状,并为其赋予六个不同的顶点颜色:

// 立方体顶点
var vertices = [
    -1, -1, -1,  1, -1, -1,  1,  1, -1,  -1,  1, -1,
    -1, -1,  1,  1, -1,  1,  1,  1,  1,  -1,  1,  1,
    -1, -1, -1, -1,  1, -1, -1,  1,  1,  -1, -1,  1,
     1, -1, -1,  1,  1, -1,  1,  1,  1,  1, -1,  1,
    -1, -1, -1, -1, -1,  1,  1, -1,  1,  1, -1, -1,
    -1,  1, -1, -1,  1,  1,  1,  1,  1,  1,  1, -1,
];

// 立方体顶点颜色
var colors = [
    1, 0, 0, 1,  0, 1, 0, 1,  0, 0, 1, 1,
    1, 0, 0, 1,  0, 1, 0, 1,  0, 0, 1, 1,
    0, 0, 1, 1,  0, 0, 1, 1,  0, 0, 1, 1,
    1, 1, 0, 1,  1, 1, 0, 1,  1, 1, 0, 1,
    1, 0, 1, 1,  1, 0, 1, 1,  1, 0, 1, 1,
    0, 1, 1, 1,  0, 1, 1, 1,  0, 1, 1, 1
];

准备就绪,让立方体闪耀

我们已经配备了所有必要的武器,是时候让我们的六色立方体在屏幕上大放异彩了:

// 创建并绑定顶点缓冲区
var vertexBuffer = createBuffer(gl, gl.ARRAY_BUFFER, vertices);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

// 创建并绑定颜色缓冲区
var colorBuffer = createBuffer(gl, gl.ARRAY_BUFFER, colors);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);

// 链接顶点着色器中的位置属性
var positionAttributeLocation = gl.getAttribLocation(shaderProgram, "position");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);

// 链接顶点着色器中的颜色属性
var colorAttributeLocation = gl.getAttribLocation(shaderProgram, "color");
gl.enableVertexAttribArray(colorAttributeLocation);
gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);

// 绘制立方体
gl.drawArrays(gl.TRIANGLES, 0, 36);

瞧!一个六色立方体,由WebGL绘制,它的每个面都闪烁着不同的色彩。