I've been writing my own renderer for a while now and I just about got the system running decently, but I am running into some speed issues.
At about 1000 scene objects, the fps drops really fast and by 2000 objects, the max my laptop can get is 25 fps. I made the exact same scene with THREE and i get a constant 60fps which is really annoying and I'm not sure what to do.
After creating a debug timer for myself, I disscovered that most of the lag is coming from assigning my attributes, the uniforms and also the draw call itself.
In my pipeline i have a map of shaders and for each object using that shader, I get the required attributes and uniforms and then send the data over to the gpu.
I have a feeling that it is the func.call(this.gl, args...) is what is slowing it down but I am really not sure.
the code is below.
for (let [shader, mesh] of this.shaders) {
shader.use(gl);
let attributes = shader.attr;
let uniforms = shader.uni;
for (let i = 0; i < mesh.length; i++) {
const mesh_attr = mesh[i].attributes;
for (let key in attributes) {
if (!attributes.hasOwnProperty(key)) continue;
if (mesh_attr[key] === undefined || mesh_attr[key] === null) {
console.warn(`mesh ${mesh[i].uuid} does not have the attribute ${key}\nwill not render this object`);
continue;
}
const numComponents = mesh_attr[key].size;
const type = FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.bindBuffer(ARRAY_BUFFER, mesh_attr[key].buffer);
gl.vertexAttribPointer(
attributes[key],
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(attributes[key]);
}
if (mesh[i].geometry.indexed === true) {
{
gl.bindBuffer(ELEMENT_ARRAY_BUFFER, mesh_attr.indices.buffer);
}
}
const mesh_uni = mesh[i].uniforms;
for (let key in uniforms) {
if (!uniforms.hasOwnProperty(key)) continue;
switch (key) {
case 'uModel':
uniforms[key].func.call(this.gl, uniforms[key].location, false, mesh[i].modelMatrix);
break;
case 'uProjection':
uniforms[key].func.call(this.gl, uniforms[key].location, false, projectionMatrix);
break;
case 'uView':
uniforms[key].func.call(this.gl, uniforms[key].location, false, viewMatrix);
break;
default:
if (uniforms[key].matrix) {
uniforms[key].func.call(this.gl, uniforms[key].location, false, mesh_uni[key].data);
}
else {
uniforms[key].func.call(this.gl, uniforms[key].location, mesh_uni[key].data);
}
break;
}
}
let vertexCount;
if (mesh[i].geometry.indexed === true) {
vertexCount = mesh[i].attributes.indices.data.length;
const type = gl.UNSIGNED_SHORT;
const offset = 0;
gl.drawElements(mesh[i].material.drawMode, vertexCount, type, offset);
}
else {
vertexCount = mesh[i].attributes.aPosition.data.length / mesh[i].attributes.aPosition.size;
const type = gl.UNSIGNED_SHORT;
gl.drawArrays(mesh[i].material.drawMode, vertexCount, type);
}
}
}
Does anyone know why im experiencing all this lag? I'm really not sure wht and I've been playing around with it for 2 days with no success. I'm not sure if its just my bad code :) or a weird bug in my code?
Any help would be greatly appreciated.
Also I am really sorry I couldn't think of an appropriate title so I put whatever and I dont think its very good.