sprite render faster

This commit is contained in:
John Alanbrook 2024-09-27 10:19:05 -05:00
parent 4756955c1a
commit f47be2d30c
4 changed files with 48 additions and 25 deletions

View file

@ -247,7 +247,6 @@ var entity = {
delete ent.objects; delete ent.objects;
ent.objects = {}; ent.objects = {};
for (var i in o) { for (var i in o) {
console.info(`creating ${i} on ${ent.toString()}`);
var newur = o[i].ur; var newur = o[i].ur;
delete o[i].ur; delete o[i].ur;
var n = ent.spawn(ur[newur], o[i]); var n = ent.spawn(ur[newur], o[i]);
@ -431,7 +430,7 @@ var entity = {
rename_obj(name, newname) { rename_obj(name, newname) {
if (!this.objects[name]) { if (!this.objects[name]) {
console.warn(`No object with name ${name}. Could not rename to ${newname}.`); // console.warn(`No object with name ${name}. Could not rename to ${newname}.`);
return; return;
} }
if (name === newname) { if (name === newname) {

View file

@ -5,13 +5,16 @@ render.doc = {
}; };
var cur = {}; var cur = {};
cur.images = [];
// When changing a shader, everything must wipe
render.use_shader = function use_shader(shader) { render.use_shader = function use_shader(shader) {
if (typeof shader === "string") shader = make_shader(shader); if (typeof shader === "string") shader = make_shader(shader);
if (cur.shader === shader) return; if (cur.shader === shader) return;
cur.shader = shader; cur.shader = shader;
cur.bind = undefined; cur.bind = undefined;
cur.mesh = undefined; cur.mesh = undefined;
cur.ssbo = undefined;
render.setpipeline(shader.pipe); render.setpipeline(shader.pipe);
shader_globals(cur.shader); shader_globals(cur.shader);
}; };
@ -24,7 +27,7 @@ render.use_mat = function use_mat(mat) {
cur.mat = mat; cur.mat = mat;
cur.images = []; cur.images.length = 0;
if (!cur.shader.fs.images) return; if (!cur.shader.fs.images) return;
for (var img of cur.shader.fs.images) for (var img of cur.shader.fs.images)
if (mat[img.name]) cur.images.push(mat[img.name]); if (mat[img.name]) cur.images.push(mat[img.name]);
@ -372,10 +375,32 @@ function shader_apply_material(shader, material = {}, old = {}) {
if ("diffuse_size" in shader.vs.unimap) render.setuniv2(0, shader.vs.unimap.diffuse_size.slot, [material.diffuse.width, material.diffuse.height]); if ("diffuse_size" in shader.vs.unimap) render.setuniv2(0, shader.vs.unimap.diffuse_size.slot, [material.diffuse.width, material.diffuse.height]);
} }
// Creates a binding object for a given mesh and shader
var bindcache = {};
var bcache = new WeakMap();
function sg_bind(mesh, ssbo) { function sg_bind(mesh, ssbo) {
cur.mesh = mesh; if (cur.mesh === mesh && cur.ssbo === ssbo) {
cur.bind.ssbo = [ssbo];
cur.bind.images = cur.images;
render.setbind(cur.bind);
return;
}
// var sid = os.value_id(cur.shader);
// var mid = os.value_id(mesh);
if (bcache.has(cur.shader) && bcache.get(cur.shader).has(mesh)) {
cur.bind = bcache.get(cur.shader).get(mesh);
cur.bind.images = cur.images;
if (ssbo)
cur.bind.ssbo = [ssbo];
render.setbind(cur.bind);
return;
}
var bind = {}; var bind = {};
if (!bcache.has(cur.shader)) bcache.set(cur.shader, new WeakMap());
if (!bcache.get(cur.shader).has(mesh)) bcache.get(cur.shader).set(mesh, bind);
cur.mesh = mesh;
cur.ssbo = ssbo;
cur.bind = bind;
bind.attrib = []; bind.attrib = [];
if (cur.shader.vs.inputs) if (cur.shader.vs.inputs)
for (var a of cur.shader.vs.inputs) { for (var a of cur.shader.vs.inputs) {
@ -393,11 +418,8 @@ function sg_bind(mesh, ssbo) {
bind.ssbo = []; bind.ssbo = [];
if (cur.shader.vs.storage_buffers) for (var b of cur.shader.vs.storage_buffers) bind.ssbo.push(ssbo); if (cur.shader.vs.storage_buffers) for (var b of cur.shader.vs.storage_buffers) bind.ssbo.push(ssbo);
bind.inst = 1;
bind.images = cur.images; bind.images = cur.images;
cur.bind = bind;
render.setbind(cur.bind); render.setbind(cur.bind);
return bind; return bind;
@ -501,11 +523,7 @@ render.draw_gui = true;
render.draw_gizmos = true; render.draw_gizmos = true;
render.buckets = []; render.buckets = [];
render.sprites = function render_sprites(gridsize = 1) { render.sprites = function render_sprites() {
// When y sorting, draw layer is firstly important followed by the gameobject position
//for (var sprite of allsprites)
// sprite.sync();
profile.frame("drawing"); profile.frame("drawing");
render.use_shader(spritessboshader); render.use_shader(spritessboshader);
var buckets = component.sprite_buckets(); var buckets = component.sprite_buckets();
@ -515,7 +533,8 @@ render.sprites = function render_sprites(gridsize = 1) {
var sparray = layer[img]; var sparray = layer[img];
if (sparray.length === 0) continue; if (sparray.length === 0) continue;
var ss = sparray[0]; var ss = sparray[0];
render.use_mat(ss); // render.use_mat(ss);
cur.images = [ss.diffuse];
render.make_sprite_ssbo(sparray, sprite_ssbo); render.make_sprite_ssbo(sparray, sprite_ssbo);
render.draw(shape.quad, sprite_ssbo, sparray.length); render.draw(shape.quad, sprite_ssbo, sparray.length);
if (debug.sprite_nums) render.text(ss.diffuse.getid(), ss.transform.pos); if (debug.sprite_nums) render.text(ss.diffuse.getid(), ss.transform.pos);
@ -722,11 +741,11 @@ function img_e() {
} }
render.image = function image(tex, pos, scale, rotation = 0, color = Color.white) { render.image = function image(tex, pos, scale, rotation = 0, color = Color.white) {
if (typeof tex === "string") { if (typeof tex === "string")
tex = game.texture(tex); tex = game.texture(tex);
scale.x ??= tex.width;
scale.y ??= tex.height; scale ??= [tex.width,tex.height];
}
if (!tex) return; if (!tex) return;
if (!lasttex) { if (!lasttex) {
@ -740,7 +759,7 @@ render.image = function image(tex, pos, scale, rotation = 0, color = Color.white
} }
var e = img_e(); var e = img_e();
e.transform.trs(pos, undefined, scale ? scale.div([tex.width, tex.height]) : undefined); e.transform.trs(pos, undefined, scale);
e.shade = color; e.shade = color;
return; return;

View file

@ -21,17 +21,14 @@ readonly buffer ssbo {
sprite sprites[]; sprite sprites[];
}; };
uniform mat4 projection;
uniform mat4 view;
uniform mat4 vp; uniform mat4 vp;
uniform vec2 diffuse_size;
void main() void main()
{ {
sprite s = sprites[gl_InstanceIndex]; sprite s = sprites[gl_InstanceIndex];
pos = a_pos; pos = a_pos;
uv = a_uv; uv = a_uv;
pos *= vec3(diffuse_size * s.rect.zw,1); pos *= vec3(s.rect.zw,1);
uv = (uv*s.rect.zw)+s.rect.xy; uv = (uv*s.rect.zw)+s.rect.xy;
gl_Position = vp * s.model * vec4(pos, 1.0); gl_Position = vp * s.model * vec4(pos, 1.0);
shade = s.shade; shade = s.shade;

View file

@ -715,9 +715,8 @@ sg_bindings js2bind(JSValue v)
sg_bindings bind = {0}; sg_bindings bind = {0};
JSValue attrib = js_getpropstr(v, "attrib"); JSValue attrib = js_getpropstr(v, "attrib");
for (int i = 0; i < js_arrlen(attrib); i++) { for (int i = 0; i < js_arrlen(attrib); i++)
bind.vertex_buffers[i] = *js2sg_buffer(js_getpropidx(attrib,i)); bind.vertex_buffers[i] = *js2sg_buffer(js_getpropidx(attrib,i));
}
JSValue index = js_getpropstr(v, "index"); JSValue index = js_getpropstr(v, "index");
if (!JS_IsUndefined(index)) if (!JS_IsUndefined(index))
@ -1107,7 +1106,16 @@ JSC_CCALL(render_make_sprite_ssbo,
for (int i = 0; i < js_arrlen(array); i++) { for (int i = 0; i < js_arrlen(array); i++) {
JSValue sub = js_getpropidx(array,i); JSValue sub = js_getpropidx(array,i);
ms[i].model = transform2mat(js2transform(js_getpropstr(sub, "transform"))); ms[i].model = transform2mat(js2transform(js_getpropstr(sub, "transform")));
texture *t = js2texture(js_getpropstr(sub, "texture"));
if (t) {
HMM_Vec3 tscale;
tscale.x = t->width;
tscale.y = t->height;
tscale.z = 1;
ms[i].model = HMM_MulM4(ms[i].model, HMM_Scale(tscale));
}
ms[i].rect = js2vec4(js_getpropstr(sub,"rect")); ms[i].rect = js2vec4(js_getpropstr(sub,"rect"));
ms[i].shade = js2vec4(js_getpropstr(sub,"shade")); ms[i].shade = js2vec4(js_getpropstr(sub,"shade"));
} }