Rendering process clarification needed

Started by Aisaaax, March 04, 2020, 04:16:16

Previous topic - Next topic

Aisaaax

Hello!
It is not clear to me how some of OpenGL rendering works, especially depth testing and mixing.

So, let's assume I have five meshes created, each consists of triangles that occupy the same flat plane. For example, let's assume they're five squares, each square smaller than the last. Assume mesh 1 is the smallest and mesh5 is the largest. Also assume that each next square completely includes the last one. Also let's assume they are not textured and just filled with some flat color, each mesh having a different color.
//These are just here to set up the starting rules
        glDisable(GL_BLEND);
        glDisable(GL_DEPTH_TEST);

        renderer.render(mesh1);
        renderer.render(mesh2);
        renderer.render(mesh3);
        renderer.render(mesh4);
        renderer.render(mesh5);


So, the way I understand it, the way it works:
- OpenGL goes into vertex shader for Mesh 1, calculates positions of vectors
- Goes into fragment shader of Mesh 1, and fills fragments with color.
- A framebuffer is generated, and the filled fragments are written in some already existing "main" frame buffer
- Then it does the same for Mesh 2. Because Mesh 2 is bigger than mesh 1, it completely writes over whatever fragments were colored by mesh 1.
- The process continues. The result is that after mesh5 gets filled, it once again paints over the previous meshes completely.

Basically, what I'm trying to say is that rendering of meshes 1-4 was completely useless and irrelevant, because the last mesh to be rendered is "always on top", because there's no depth testing or mixing.
Is that correct?

The desired effect can be achieved if I arrange the meshes backwards, so that the smallest one is rendered last. But it still does a lot of empty work.

Now, let's check out another example.
//These are just here to set up the starting rules
        glDisable(GL_DEPTH_TEST);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);

        renderer.render(mesh1);
        renderer.render(mesh2);
        renderer.render(mesh3);
        renderer.render(mesh4);
        renderer.render(mesh5);

Assume that Alpha is always 1 for all meshes.
Here, we enable Blending, and set up Blend func to have the source pixels be zero, if the destination pixels are filled with anything with alpha 1.

So how I'm assuming it works is:
- It renders the first mesh (fills some fragments on the screen with color)
- Then it renders the second mesh completely into another buffer (including the part overlapping with mesh 1).
- Then it mixes the buffers, and basically only fills those fragments that are not already filled by Mesh 1.
- And continues for all other meshes.

Is that how it works? So, basically, it produces the desired effect of squares being inside each other like Russian doll, but they are all visible?
Again, the meshes need to be ordered a certain way before rendering to make this work.

My question is though - does it make ANY sense to enable blending in this example, if basically you still need to keep your meshes ordered and still the fragment shaders do full work for each of them? Does it make any sense? Maybe I'm missing something or don't understand it at all?

Aisaaax

A quick reply to anyone concerned.

Every rendering call indeed renders the full buffer. Then the mixing occurs, determined either by depth buffer, glBlendFunc, and glBlendEquation

There are examples online to see how those functions work. But basically, there is no performance advantage in rendering one way or the other.