wnr Posted August 20, 2021 Share Posted August 20, 2021 Hello, I'm working on a 2D infinite world built by destructible quads. The quads are rendered procedurally by using a noise shader + color mapping. This because I want to learn shaders, and have no seams or repeating as the camera moves around. I've managed to implement this and all is well, except for the horrible performance of my naive implementation. I've made an example that captures the gist of my naive implementation, by using n meshes and shaders: https://www.pixiplayground.com/#/edit/kuHFKOZiQsydVdzrP1PrT When I monitored the scene by using Spector.js, I understood that the problem is the meshes not being batched so that each mesh results in a WebGL drawCall. So having n meshes means n drawCalls. I went further to test having n sprites/geometries without shaders, which indeed performs much faster by being batched into a single drawCall. I tried mesh instancing, which did result in only 1 drawCall, but the performance was still really bad. I don't know why, the only difference I noticed is that the function drawElementsInstanced was being used instead of drawElements... After reading many many posts on this forum about batching, I came to the conclusion that I needed to implement my own batching plugin. So I've tried, and here is the result: https://www.pixiplayground.com/#/edit/kTcHxuSMF7wvehlHvpQPY The performance is great, as all meshes are batched into 1 drawCall. However, I get the feeling that this is the wrong approach. Hacking the AbstractBatchRenderer the way I do seems awful, and I'm having a hard time understanding how to handle the uniforms. More specifically, I cannot manage to set my colormap texture uniform correctly, it keeps uploading a white 16x16 texture to WebGL. Also, I don't understand how to send mesh-instance specific uniforms to my plugin shader, like "uWorldPosition" in my example. I would really appreciate some help, as I've banged my head against this for a week now ? Cheers Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 20, 2021 Share Posted August 20, 2021 (edited) > Hacking the AbstractBatchRenderer the way I do seems awful Its supposed to be this way > I'm having a hard time understanding how to handle the uniforms. ShukantPal approach : https://api.pixijs.io/pixi-batch-renderer.html my approach: https://github.com/pixijs/pixi-projection/blob/master/src/base/webgl/UniformBatchRenderer.ts here I stop batch if sprite uses different "uniforms" object (I compare as a link, not fields) > it keeps uploading a white 16x16 texture to WebGL The thing is , first MAX_TEXTURES units are needed for batching purposes, and by default pixi texture in shader is bound to 0, 1 , e.t.c. which contradics batching. However, in AbstractBatchRenderer you can add more features by overriding certain methods. There's `buildTexturesAndDrawCalls` in it, that can be hacked to take one more texture into account. For example, for my masked renderer( maskSprite ) I added one more texture in texture array: https://github.com/pixijs/pixi-heaven/blob/eb554499afe3fcbb42bb4d4f77edb2ee0c27b7fa/src/twotint/sprites/MaskedBatchRenderer.ts#L148-L210 . You can compare it and vanilla pixi implementations to understand what is going on there. ==== Current AbstractBatchRenderer architecture exists because of mine and ShukantPal's plugins. I've banged the head against it for many hours long time ago. Edited August 20, 2021 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
wnr Posted August 23, 2021 Author Share Posted August 23, 2021 Thank you Ivan, I've now managed to create two solutions that are able to render my desired output with great performance. One approach is to hack the AbstractBatchRenderer (per your suggestion) like so: https://www.pixiplayground.com/#/edit/VgBCR9r6_ZLx94VzCC_Fn . Is this how you would have done? I had to remove the texture binding in order for my colormap uniform texture to work. Another approach that performs great is to use mesh instancing like so: https://www.pixiplayground.com/#/edit/k3LQY3-KoA0E61Nu07UBI . However, it seems a bit tedious to remove/add instances. What are the pros/cons of these two approaches? In the plugin approach, I had to add the "uWorldPosition" uniform in order to keep track of the global world position of each vertex. I was surprised that it was not needed in the mesh instancing approach. I think my understanding of the transforms are too low, perhaps this is a bit off topic ? Thank you for your input! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 23, 2021 Share Posted August 23, 2021 looks good! saved both to my computer, in case playground wil be lost Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 23, 2021 Share Posted August 23, 2021 About instances, I have an idea how to make it easier for people to do it later, also with fallback, in case its not supported y certain mobile device Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.