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