Optimisation of drawing 3d
Posted: Sun Feb 11, 2024 4:06 pm
hello!
so, in general my question is very basic: what exactly i should and shouldn't do in draw function?
but here more spcific info.
i making a very simple voxel 3d game and now working on particles and billboards, and im using instancing to draw one simple square bunch of times at different positions.
initialisation, called once:
update, each frame:
draw, each frame:
and similar logic for billboards. aaand here is where i got an issue.
all data for each particle stored as single table of values where each N values related to one particle, so there is a table witn N * MAX_COUNT values and another table of pointers - indices of 'alive' particles. so, yeah, its a circular array.
this works fine and naturally prevents an issue of overflowing - new particles just override old ones, who cares, its just a visual thing.
but purpose of billboards are different, its more like flat model for entities, like fire, emm... "chunk"? so its just an unlimited table and there is no lifetime, i create and remove them when create/remove entities.
and then i tried to spawn heck-a-lot fire entities and got en error: Too many vertices (expected at most 1000, got 1125)
so, not surprised, my instance mesh can handle only 1000 of them, its current max count, and i need to fix this.
first of all i can just increase max count of items, but even 1000 should be enough for 99.99% of cases. so, all this memory will be reserved by mesh and allmost never used, am i correct? and also this only delay issue, but not prevent.
next obvious solution is just draw all in cycle by 1000 or less pieces until all drawn.
but to do this i need make both update and draw in each cicle iteration, not big deal, and here where i start ask myself some dumb questions:
what calculations should i do in update, what is better to keep in draw, and is there any differences at all?
also, im not good in glsh or shaders at all, so maybe there are some things i need to know about mesh instancing that is not in love2d wiki?
im doing some matrix multiplications just before sending them in shaders, but refreshing particle/billboard data is slightly more time consuming thing, esp if there would be quite a lot of them, so... should i be worried about it? i dont know, is there any 'rules' or some, i just doing things where i think it suppose to be, and its kinda messy now.
i know basic rules of optimisation - create less tables, use more local variables then table props, and so on, but some fps drops already happens, not much, but if i will not think about it now i could have "funny" time later.
thx.
so, in general my question is very basic: what exactly i should and shouldn't do in draw function?
but here more spcific info.
i making a very simple voxel 3d game and now working on particles and billboards, and im using instancing to draw one simple square bunch of times at different positions.
initialisation, called once:
Code: Select all
local mesh3d = require ('modules/mesh3d')
state.PARTICLE_MESH = mesh3d.newTexturedParticleMesh ()
state.MAX_PARTICLE_COUNT = 1000
local particle_vertices = {}
for i = 1, state.MAX_PARTICLE_COUNT do
particle_vertices [i] = { 0, 0, 0, 0, 0 }
end
state.PARTICLE_INSTANCES_MESH = love.graphics.newMesh (
{
{ 'InstancePosition', 'float', 3 },
{ 'InstanceTexIndex', 'float', 1 },
{ 'InstanceScale', 'float', 1 }
},
particle_vertices,
'points',
'dynamic'
)
state.PARTICLE_MESH:attachAttribute ('InstancePosition', state.PARTICLE_INSTANCES_MESH, 'perinstance')
state.PARTICLE_MESH:attachAttribute ('InstanceTexIndex', state.PARTICLE_INSTANCES_MESH, 'perinstance')
state.PARTICLE_MESH:attachAttribute ('InstanceScale', state.PARTICLE_INSTANCES_MESH, 'perinstance')
local particle3d = require ('modules/particle3d')
state.PARTICLE_COUNT = 0
state.MAX_PARTICLE_COUNT = 1000
state.PARTICLE_DATASET = particle3d.newDataset (state.MAX_PARTICLE_COUNT)
state.PARTICLE_SYSTEM = particle3d.newSystem (state.PARTICLE_DATASET)
Code: Select all
local vertices_data = particle3d.update (state.PARTICLE_SYSTEM, dt)
state.PARTICLE_COUNT = #vertices_data
if state.PARTICLE_COUNT > 0 then
state.PARTICLE_INSTANCES_MESH:setVertices (vertices_data)
end
Code: Select all
love.graphics.drawInstanced (state.PARTICLE_MESH, state.PARTICLE_COUNT)
all data for each particle stored as single table of values where each N values related to one particle, so there is a table witn N * MAX_COUNT values and another table of pointers - indices of 'alive' particles. so, yeah, its a circular array.
this works fine and naturally prevents an issue of overflowing - new particles just override old ones, who cares, its just a visual thing.
but purpose of billboards are different, its more like flat model for entities, like fire, emm... "chunk"? so its just an unlimited table and there is no lifetime, i create and remove them when create/remove entities.
and then i tried to spawn heck-a-lot fire entities and got en error: Too many vertices (expected at most 1000, got 1125)
so, not surprised, my instance mesh can handle only 1000 of them, its current max count, and i need to fix this.
first of all i can just increase max count of items, but even 1000 should be enough for 99.99% of cases. so, all this memory will be reserved by mesh and allmost never used, am i correct? and also this only delay issue, but not prevent.
next obvious solution is just draw all in cycle by 1000 or less pieces until all drawn.
but to do this i need make both update and draw in each cicle iteration, not big deal, and here where i start ask myself some dumb questions:
what calculations should i do in update, what is better to keep in draw, and is there any differences at all?
also, im not good in glsh or shaders at all, so maybe there are some things i need to know about mesh instancing that is not in love2d wiki?
im doing some matrix multiplications just before sending them in shaders, but refreshing particle/billboard data is slightly more time consuming thing, esp if there would be quite a lot of them, so... should i be worried about it? i dont know, is there any 'rules' or some, i just doing things where i think it suppose to be, and its kinda messy now.
i know basic rules of optimisation - create less tables, use more local variables then table props, and so on, but some fps drops already happens, not much, but if i will not think about it now i could have "funny" time later.
thx.