如何更改 webgl 点的颜色?

How Do I change the color of webgl points?

这是我用来尝试改变 WebGL 点颜色的代码:

我想在用户单击 body 元素时更改 WebGL 点的颜色。 仅供参考,着色器编译正确。

当我点击屏幕时,color_obj 对象中的数字似乎在变化。但是,WebGL 颜色不会改变。有人可以帮我解决这个问题吗?

const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");

gl.clearColor(0.3, 0.6, 0.7, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT || gl.DEPTH_BUFFER_BIT);

if (!gl) {
    throw new Error("WebGL not supported");
}

console.log("This is working");

const points = [
    1.0, 1.0, 0.0,
    1.0, -1.0, 0.0,
    -1.0, -1.0, 0.0,
    1.0, 1.0, 0.0,
    -1.0, -1.0, 0.0,
    -1.0, 1.0, 0.0
];

let color_obj = {
    color_1: 0.4,
    color_2: 0.7,
    color_3: 0.8,
    color_4: 0.0,
    color_5: 0.5,
}

let colors = [
    color_obj.color_1, color_obj.color_2, color_obj.color_3,
    color_obj.color_3, color_obj.color_1, color_obj.color_3,
    color_obj.color_4, color_obj.color_4, color_obj.color_4,
    color_obj.color_1, color_obj.color_2, color_obj.color_3,
    color_obj.color_4, color_obj.color_4, color_obj.color_4,
    color_obj.color_5, color_obj.color_5, color_obj.color_5
];

const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);

const buffer_2 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer_2);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW)

const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, `
precision mediump float;

attribute vec3 pos;
attribute vec3 rgb;
varying vec3 rgbColor;

void main() {
    rgbColor = rgb;
    gl_Position = vec4(pos, 1);
}
`);
gl.compileShader(vertexShader);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, `
precision mediump float;

varying vec3 rgbColor;

void main() {
    gl_FragColor = vec4(rgbColor, 1);
}
`);
gl.compileShader(fragmentShader);

const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

const positionRef = gl.getAttribLocation(program, `pos`);
gl.enableVertexAttribArray(positionRef);
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.vertexAttribPointer(positionRef, 3, gl.FLOAT, false, 0, 0);

const colorRef = gl.getAttribLocation(program, `rgb`);
gl.enableVertexAttribArray(colorRef);
gl.bindBuffer(gl.ARRAY_BUFFER, buffer_2);
gl.vertexAttribPointer(colorRef, 3, gl.FLOAT, false, 0, 0);

gl.useProgram(program);

document.body.addEventListener("mouseup", () => {
    console.log("Body Clicked");
    color_obj.color_1 += 0.1;
    color_obj.color_2 += 0.1;
    color_obj.color_3 += 0.1;
    color_obj.color_4 += 0.1;
    color_obj.color_5 += 0.1;

    console.log(color_obj.color_1);
    console.log(color_obj.color_2);
    console.log(color_obj.color_3);
    console.log(color_obj.color_4);
    console.log(color_obj.color_5);
});

function animate() {
    requestAnimationFrame(animate);

    gl.drawArrays(gl.TRIANGLES, 0, 6);
}

requestAnimationFrame(animate);
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>WebGL</title>
    <style>
        canvas {
            position:fixed;
            width:100%;
            height:100%;
        }

        html, body {
            margin:0 !important;
            padding:0 !important;
            overflow:hidden;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
    <script src="app.js"></script>
</body>

</html>

color_obj 中的值仅被复制到 colors 数组中,用于将它们写入缓冲区 (buffer_2),因此当您的点击处理程序更新 color_obj 它不会更新 colors 数组,更不用说 webgl 使用的实际缓冲区了。您需要绑定缓冲区并在您的点击处理程序中设置其数据以使更改生效。