Jump to content

Performance, Batch Rendering, Draw Calls


ammychoice
 Share

Recommended Posts

Hey. I would like to know about drawCalls and their optimization. For example, there is an atlas, one of the pictures with additive blending mode. - Can we do it all in 1 drawCall. (If possible, explain why it is impossible and how it would be possible). The second question, is the developer Yggdrasil in his games uses sequence, an atlas filled with sequences. My developers said that the sequence in Pixi js is bad, and it is better not to use them because of optimization. But Yggdrasil normally uses them and is not afraid of it. Do they use webgl instances? with vertex shader? Can you tell me?

Untitled-1.jpg

Link to comment
Share on other sites

In general, app performance is the art of balancing stuff. It doesn't matter whether you have 10 or100 drawcalls if you draw all the pixels on retina screen 10 times :)

Pixi renders elements in their order in the tree. If it draws several sprites with same blendMode, and maybe same baseTexture (or several, shader is multi-textured), it draws them in one drawcall. So, different blendMode breaks batch for sure. 

To count number of drawcalls you can override "renderer.gl.drawElements" or just use existing plugin for it: https://github.com/eXponenta/gstatsjs

If you use at least one sprite with additive blendMode - your app is ruined. Its a joke. 1 drawcall doesn't matter. Just keep the number below 50 for mobile and below 200 for PC and you'll be OK.

I see that you only have one water sprite, and I doubt you use it many times on scene - so its not important at all. There's a trick that allows to batch normals and additives together but I don't have an example for it right now. Its very easy if you know how exactly blending works.

As for sequences the common problems is  memory. Size of files is not important - size of images is. Every pixels costs 4 bytes in common memory when image is decoded and when its uploaded it costs 4 more. Also uploading induces the lag first time its drawn, you have to use PREPARE plugin (packaged with pixi) or manually "renderer.texture.bind()" all your baseTextures before you start the game scene.

Link to comment
Share on other sites

Thanks for the answer, I'm not a programmer, but an animator, but I check our game through spector js, and I see a large number of drawCalls. I think that it is clearly implemented here that the tone is correct. The developers respond to this that the number of drawCall does not matter. Can you check on spector JS this game? and say what wrong?
http://evoplay.games/portfolio/legend-of-kaan/
174 drawCalls

I think they dont know how to do right.

174 drawCalls.png

kaan.png

Link to comment
Share on other sites

  • 1 month later...
  • 3 years later...

Hi there. I wish to share my final solution regarding draw calls computation in case someone needs it.

The code below must be in class, which inherits the pixi Application.
 

// here are the fields

    private gl: IRenderingContext;
    private realDrawElements: Function;
    private realWebGLClear: Function;
    private drawCalls: number;
// here is the snippet from the App constructor
        this.gl = (this.renderer as Renderer)?.gl;
        if (this.gl) {
            // @ts-ignore
            this.realDrawElements = this.gl.__proto__.drawElements;
            // @ts-ignore
            this.realWebGLClear = this.gl.__proto__.clear;

            // @ts-ignore
            this.gl.__proto__.drawElements = this.fakeDrawElements.bind(this);
            // @ts-ignore
            this.gl.__proto__.clear = this.fakeWebGLClear.bind(this);
        }
// Here are the fake methods    
private fakeDrawElements(mode: number, count: number, type: number, offset: number): void {
        this.drawCalls++;
        this.realDrawElements.call(this.gl, mode, count, type, offset);
    }

    private fakeWebGLClear(bitmask: number): void {
        if (bitmask == 16640) {
          // HERE IS THE PLACE WHERE YOU HAVE THE DRAW CALLS COMPUTED.
          // IN MY CASE I AM RAISING AN EVENT, BUT THIS WON'T COMPILE FOR YOU.
            App.dispatcher.emit(GameEvents.DRAW_CALLS_COMPUTED, this.drawCalls);
          
          // After this we reset the draw calls back to 0.
            this.drawCalls = 0;
        }

        this.realWebGLClear.call(this.gl, bitmask);
    }

 

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...