Sprite Batching In OpenGL (Uniform Buffer Objects) // OpenGL Tutorial #33

Поделиться
HTML-код
  • Опубликовано: 25 ноя 2024

Комментарии • 51

  • @noobheeecker4211
    @noobheeecker4211 2 года назад +2

    Awesome, great video!

  • @miumpre2839
    @miumpre2839 7 месяцев назад

    Very good info and explanation! thanks

    • @OGLDEV
      @OGLDEV  7 месяцев назад

      You're welcome :-)

  • @grengren6421
    @grengren6421 2 года назад +1

    You hero among men.

    • @OGLDEV
      @OGLDEV  2 года назад +1

      LOL! Thanks!

  • @pal_7
    @pal_7 2 года назад +1

    Keep the hard work chief

    • @OGLDEV
      @OGLDEV  2 года назад

      Sure thing Boss ;-)

  • @laurentbedief2199
    @laurentbedief2199 2 года назад +1

    You're the best !!!!! thanks

    • @OGLDEV
      @OGLDEV  2 года назад

      Thank you so much!

  • @andreagenor
    @andreagenor 2 года назад +1

    Awesome videos!

  • @gokalpates1567
    @gokalpates1567 2 года назад +1

    Awesome.

    • @OGLDEV
      @OGLDEV  2 года назад

      Thanks :-)

  • @firstow
    @firstow Год назад

    many thanks!

    • @OGLDEV
      @OGLDEV  Год назад

      You're welcome!

  • @oddstonegames
    @oddstonegames 2 года назад +1

    thanks a lot

    • @OGLDEV
      @OGLDEV  2 года назад

      Your'e welcome :-)

  • @SB-pq8dp
    @SB-pq8dp 2 года назад +1

    You are awesome! I am very grateful for your work! I was wondering, is it worth doing batching in a 3D renderer? Or maybe it will turn out to be a useless feature (especially with different assimp optimizations)... It seems to me that this would be useful in a game with low-poly like graphics, but certainly not in a physically based renderer or something like that, am I right?

    • @OGLDEV
      @OGLDEV  2 года назад

      Thanks!
      Batching in 3D is usually beneficial because the GPU is (depending on your $$$) very fast and you don't want it to sit idle. You need to always feed it with work so you want to minimize the CPU-to-GPU interaction and batching is one way to do it.

  • @orocimarosay1447
    @orocimarosay1447 2 года назад

    Multiple identical quads is a simple sollution tho you can also use only one with very simple modifications

    • @OGLDEV
      @OGLDEV  2 года назад

      You mean with instancing?

    • @orocimarosay1447
      @orocimarosay1447 2 года назад +1

      @@OGLDEV yes

    • @OGLDEV
      @OGLDEV  2 года назад +3

      The main advantage with instancing comes when you have a very large model that you want to render multiple times while changing small bits and pieces such as matrices, etc. In the case of a single quad it seems a bit redundant but I have to admit that I haven't measured the two options so I can't say which will perform better.

  • @mourirsilfaut6769
    @mourirsilfaut6769 2 года назад +1

    Thanks a lot. Btw have you ever consider making a video about OIT ?

    • @OGLDEV
      @OGLDEV  2 года назад

      Yes, but will require some research because I'm not very familiar with the topic. Will add it to the todo list.

  • @thomasnguyen1150
    @thomasnguyen1150 11 месяцев назад

    Slightly unrelated, instead of using 6 vertices to draw the quad you could also use only 4 vertices with an element buffer object right? Does this make performance better?

    • @OGLDEV
      @OGLDEV  11 месяцев назад

      Sure, but I doubt whether it will perform better due to the low number of vertices. So I usually skip the element buffer in such cases. btw, you can achieve 4 vertices without an element buffer using GL_TRIANGLE_STRIP.

  • @TriPham-j3b
    @TriPham-j3b 5 дней назад

    3 Time of each color. 3 timer for each dimensions Each dimensions, each sprite had square and circle , and olygon and x an o super imposed onwith tecture of each and siper computer os can do fast only at location of display

    • @OGLDEV
      @OGLDEV  День назад

      Sorry, I didn't understand this comment.

  • @razcodes
    @razcodes Год назад

    How would you handle rotation of each individual sprite in this scenario?

    • @OGLDEV
      @OGLDEV  Год назад

      Excellent question! I haven't tried that but I guess that in general you need to apply a 2D rotation matrix in the vertex shader. The trick is that if you just apply it on the existing code the sprites will rotate around the center of the screen instead of around their center (which is what I guess you want to do). You need to translate them to the center of the screen, apply the rotation and then translate back and continue. The vertex buffer provides us with corners of the quad: (0,0), (0,1), (1,0) and (1,1). When we multiply it by the WidthHeight vector which is in NDC we get the location in NDC of each corner. You need to translate each corner by half the width and height (in the negative). This moves the sprite to the center. Next you need to apply the 2D rotation matrix which will be a new uniform. And then translate back using the positive half of WidthHeight. From there you can continue as usual.

    • @razcodes
      @razcodes Год назад

      @@OGLDEV That is a very clever take, but wouldn't that rotate all vertices (from all sprites)?

    • @OGLDEV
      @OGLDEV  Год назад +1

      @@razcodes The rotation angle needs to be a per sprite uniform, similar to position, etc. You will construct a different matrix for each sprite.

  • @developerdeveloper67
    @developerdeveloper67 2 года назад

    I'm still trying to figure out the vertex buffer, index buffer, and the vao thing. How do I draw multiple different models? Do I have to declare a different vertice and indice buffer for each object or do I declare all models in one vertex buffer and one index buffer? And the vao: what the f is this? I'm still confused...

    • @OGLDEV
      @OGLDEV  2 года назад +2

      You can manage your models in different ways and you basically mentioned the two main strategies. Option #1 is to use a dedicated VB/IB for each model. This seems more straightforward and I guess many people will go with that option because it makes sense to wrap the model in a C++ class and keep the buffers as private attributes. Option #2 is to load all the vertices and indices of all the models into a single VB or VB/IB pair and draw a specific model using glDrawElementsBaseVertex or any similar draw call that allows you to draw from the middle of the buffer. Whatever works better for you. The idea behind the VAO is to minimize the amount of state changes that you need to take care of before a draw call - you need to enable all the active vertex attributes and set the layout for each one. You can setup all this state once inside the VAO so that every time you bind the VAO you don't need to worry about all this state changes.

    • @developerdeveloper67
      @developerdeveloper67 2 года назад

      @@OGLDEV Thank you!

    • @OGLDEV
      @OGLDEV  2 года назад

      Did you write another comment? Seems like youtube deleted it.

    • @jw200
      @jw200 2 года назад

      @@OGLDEV RUclips sadly deletes lots of comments

    • @OGLDEV
      @OGLDEV  2 года назад

      Very true unfortunately.

  • @MrFabrizioV
    @MrFabrizioV Год назад

    Can't you create a struct containing the releavant quad info (base pos etc.) and then create an array of struct with size MAX_QUADS?
    struct T {
    vec2 BasePos;
    vec2 WidthHeight;
    ...
    };
    uniform T QuadInfo[MAX_QUADS];

    • @OGLDEV
      @OGLDEV  Год назад

      I haven't tried that but it should work. We are getting the offset of each element in T using glGetActiveUniformBlockiv. If you do this my way (structure of arrays) this gives you the offset to the corresponding array within T so all you need to do is to access the specific element using the offset as a base pointer: T.BasePos[i]. If you do this your way (array of structures) then you should get the offset inside a single struct. You then need to access the specific T element and use the offset to find the attribute inside it. The assumption is that the size of T is the sum of its attributes and that everything is packed together. It makes sense but I haven't studied the spec enough to verify it.

  • @pastasawce
    @pastasawce Год назад

    Is there a simple way to add a uniform to the frag shader so that we can determine the offset of the spritesheet? Your set up is quite different from the opengl tutorial I'm following, so I'm curious if it's a simple task or not.

    • @OGLDEV
      @OGLDEV  Год назад

      What do you mean 'offset of the spritesheet'? An offset inside it? In general, any value that you can calculate before the draw call can be set into the fragment shader as a regular uniform.

    • @pastasawce
      @pastasawce Год назад

      @@OGLDEV I define the vertices in an array with values being 1.0 and 0.0, I want to begin rendering at a specific part of the atlas, like we do with tilemaps, but the only solution I've gotten to work (which isn't a solution) was to call in c++ glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
      glPixelStorei(GL_UNPACK_SKIP_PIXELS, currentFrameX);
      glPixelStorei(GL_UNPACK_SKIP_ROWS, currentFrameY);
      and then after calling glTexImage2D, calling those same functions, and passing in 0 as an argument. This is definitely not ideal lol

    • @OGLDEV
      @OGLDEV  Год назад +1

      If I understand this correctly you are using glPixelStorei to point to the correct sprite. My intuition is that using the uniforms and not touching the texture itself is better but I can't prove it or anything.

    • @pastasawce
      @pastasawce Год назад

      @@OGLDEV I actually just figured out that in the vertex array, the texture coord values just needed to be changed from 0 to like 0.3 etc to begin the coords at a different spot. Now I need to figure out how to calculate screen coords to these decimals. It was confusing how the text coords and positions essentially alternate in the array.

    • @OGLDEV
      @OGLDEV  Год назад +1

      That's what I do in the tutorial. 'screen coords' - you mean where to finally render the sprite? I translate screen position to NDC and provide it to the vs.

  • @TriPham-j3b
    @TriPham-j3b 5 дней назад

    Start from 1 so need no -1

    • @OGLDEV
      @OGLDEV  День назад

      Do you mean the screen position?