Javascript WebGL渲染循环性能

Javascript WebGL渲染循环性能,javascript,glsl,webgl,Javascript,Glsl,Webgl,我刚刚开始学习WebGL 我正在渲染多个球体,但我不确定渲染循环中的“bindBuffer”和“bufferData”调用 我可以渲染一个有200万个顶点的球体没有问题。但一旦我尝试渲染3个球体,每个球体有100k个顶点(总共300k个,减少85%的顶点),性能就会开始下降 我想确切地知道什么需要保留在渲染循环中,什么不需要。如果我还遗漏了什么 这是我的球体“类”: 这里是主要的“类”: 除非更改缓冲区中的数据,否则不应在渲染时调用bufferData unction Sphere (resol

我刚刚开始学习WebGL

我正在渲染多个球体,但我不确定渲染循环中的“bindBuffer”和“bufferData”调用

我可以渲染一个有200万个顶点的球体没有问题。但一旦我尝试渲染3个球体,每个球体有100k个顶点(总共300k个,减少85%的顶点),性能就会开始下降

我想确切地知道什么需要保留在渲染循环中,什么不需要。如果我还遗漏了什么

这是我的球体“类”:

这里是主要的“类”:


除非更改缓冲区中的数据,否则不应在渲染时调用bufferData

unction Sphere (resolution, gl, vertex, fragment) {

    const {positions, indexes} = createPositionsAndIndexes(resolution);

    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertex);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragment);
    const program = createProgram(gl, vertexShader, fragmentShader);

    this.x = 0;
    this.y = 0;
    this.z = -6;
    this.angle = {x:0,y:0,z:0};

    const positionBuffer = gl.createBuffer();
    const indexBuffer = gl.createBuffer();

    const positionLocation = gl.getAttribLocation(program, "position");
    const viewLocation = gl.getUniformLocation(program, "view");  
    const projectionLocation = gl.getUniformLocation(program, "projection");

    // create buffers and put data in them
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
    
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indexes), gl.STATIC_DRAW);


    this.render = () => {
    
        gl.useProgram(program);

        // bind the position buffer to the attribute
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(positionLocation);
    
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    

        const viewMatrix = glMatrix.mat4.create();
        glMatrix.mat4.translate(viewMatrix, viewMatrix, [this.x, this.y, this.z]);   
        glMatrix.mat4.rotateX(viewMatrix, viewMatrix, this.angle.x);
        glMatrix.mat4.rotateY(viewMatrix, viewMatrix, this.angle.y);
        glMatrix.mat4.rotateZ(viewMatrix, viewMatrix, this.angle.z);
        gl.uniformMatrix4fv(viewLocation, false, viewMatrix);

        const projectionMatrix = glMatrix.mat4.create();
        glMatrix.mat4.perspective(projectionMatrix, 45 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 100.0);
        gl.uniformMatrix4fv(projectionLocation, false, projectionMatrix);
        
        gl.drawElements(gl.TRIANGLES, indexes.length, gl.UNSIGNED_INT, 0);

    };

}

您可能会发现,尤其是在渲染时不应该调用bufferData,除非您正在更改缓冲区中的数据

unction Sphere (resolution, gl, vertex, fragment) {

    const {positions, indexes} = createPositionsAndIndexes(resolution);

    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertex);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragment);
    const program = createProgram(gl, vertexShader, fragmentShader);

    this.x = 0;
    this.y = 0;
    this.z = -6;
    this.angle = {x:0,y:0,z:0};

    const positionBuffer = gl.createBuffer();
    const indexBuffer = gl.createBuffer();

    const positionLocation = gl.getAttribLocation(program, "position");
    const viewLocation = gl.getUniformLocation(program, "view");  
    const projectionLocation = gl.getUniformLocation(program, "projection");

    // create buffers and put data in them
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
    
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indexes), gl.STATIC_DRAW);


    this.render = () => {
    
        gl.useProgram(program);

        // bind the position buffer to the attribute
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(positionLocation);
    
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    

        const viewMatrix = glMatrix.mat4.create();
        glMatrix.mat4.translate(viewMatrix, viewMatrix, [this.x, this.y, this.z]);   
        glMatrix.mat4.rotateX(viewMatrix, viewMatrix, this.angle.x);
        glMatrix.mat4.rotateY(viewMatrix, viewMatrix, this.angle.y);
        glMatrix.mat4.rotateZ(viewMatrix, viewMatrix, this.angle.z);
        gl.uniformMatrix4fv(viewLocation, false, viewMatrix);

        const projectionMatrix = glMatrix.mat4.create();
        glMatrix.mat4.perspective(projectionMatrix, 45 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 100.0);
        gl.uniformMatrix4fv(projectionLocation, false, projectionMatrix);
        
        gl.drawElements(gl.TRIANGLES, indexes.length, gl.UNSIGNED_INT, 0);

    };

}

你可能会发现,尤其是

就是这样!刚刚渲染了每个球体,每个球体有200万个顶点(6kk个顶点)。就是这样!仅渲染每个球体,每个球体有200万个顶点(6kk个顶点)。
unction Sphere (resolution, gl, vertex, fragment) {

    const {positions, indexes} = createPositionsAndIndexes(resolution);

    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertex);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragment);
    const program = createProgram(gl, vertexShader, fragmentShader);

    this.x = 0;
    this.y = 0;
    this.z = -6;
    this.angle = {x:0,y:0,z:0};

    const positionBuffer = gl.createBuffer();
    const indexBuffer = gl.createBuffer();

    const positionLocation = gl.getAttribLocation(program, "position");
    const viewLocation = gl.getUniformLocation(program, "view");  
    const projectionLocation = gl.getUniformLocation(program, "projection");

    // create buffers and put data in them
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
    
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indexes), gl.STATIC_DRAW);


    this.render = () => {
    
        gl.useProgram(program);

        // bind the position buffer to the attribute
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(positionLocation);
    
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    

        const viewMatrix = glMatrix.mat4.create();
        glMatrix.mat4.translate(viewMatrix, viewMatrix, [this.x, this.y, this.z]);   
        glMatrix.mat4.rotateX(viewMatrix, viewMatrix, this.angle.x);
        glMatrix.mat4.rotateY(viewMatrix, viewMatrix, this.angle.y);
        glMatrix.mat4.rotateZ(viewMatrix, viewMatrix, this.angle.z);
        gl.uniformMatrix4fv(viewLocation, false, viewMatrix);

        const projectionMatrix = glMatrix.mat4.create();
        glMatrix.mat4.perspective(projectionMatrix, 45 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 100.0);
        gl.uniformMatrix4fv(projectionLocation, false, projectionMatrix);
        
        gl.drawElements(gl.TRIANGLES, indexes.length, gl.UNSIGNED_INT, 0);

    };

}