Golden Sun Hacking Community

The Community => Tech, Gaming and Entertainment => Topic started by: Luna_blade on March 04, 2016, 11:12:15 AM



Title: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: Luna_blade on March 04, 2016, 11:12:15 AM
Just out of curiosity, I'd like to know how a Z-buffer and framebufferobjects work in a 3D game.
Apparently, both are a solution to the Visibility problem in 3D games.
I spent a lot of time looking for proper explanations, which I didn't find.
I know and understand the painters algorithm, but the other two however...

 


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: Fox on March 04, 2016, 02:14:05 PM
Wait, what?

I think buffer is pretty much just an array in RAM?
So I take it that Z-buffer is probably just an array where each value is for each pixel....? Probably holding the layer number or something... well... something representing priority? (My guess is if a pixel in another triangle is lower than this priority, it gets completely ignored.... but if greater, it gets set on top and z-buffer gets updated with the new info about it. - Whether "lower" or "greater" is closer to 0, I'm not sure.)


I have something for blending in Yoshi Magic.. but it's done via flags for each pixel... (1 means blend on next layer, 0 means don't...)
Before blending feature was added, I drew the bottom layer first, after adding the blending feature, I changed Yoshi Magic to draw the top layer first. I chose top-down because that's how the blended layers are selected....


---
Is framebufferobjects like a cache or something? No idea? (Guessing again.)


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: Luna_blade on March 04, 2016, 04:27:39 PM
Well, what I do understand about Z-buffer is, that it is indeed an array in the GPU-RAM and every pixel is a floating point number.
The number corresponds to what the 'depth' of that pixel is. I also get that you start with every pixel each frame set to 0 and then counting up for each object which is more in the front.
But... I don't quite get how the Z-buffer keeps all the objects apart and how it is used to draw after the depth calculations.


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: Fox on March 04, 2016, 04:43:57 PM
Yes... except in the event that it is a user-created z-index array, I'd argue that floating-point could be any value datatype you choose. (Preferably integer/32-bit?) I'd recommending staying away from floating point (single or double) if you don't need it since it may be slower... (Could also depend on your processor? In which case, I'd be interested in more information.)
Basically... I don't think it's about keeping the objects apart, but about calculating what's in front....
-Like draw one object... its z-indexes are set... draw the next object... and whatever pixels shown from that object alters z-indexes.. but everything that comes behind the object (Which is compared with the z-index for those pixels) is ignored.).
-Objects are kept separate in other table(s)... (Triangle and vertex listings and such).... and those are rendered to the screen every frame...

@after the depth calculations: Do you mean like the HUD one might always make displayed in front?
If you want something to always display in front... you just draw it after you've drawn your 3D map... (For stuff always on top, you may not need to use z-index table anymore... unless you got some more priority-ing going on, maybe..)

Or is it something I'm missing? Like texture calculations and such instead?

---
^May not have spent enough time on this post, so could take some editing.


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: leaf on March 05, 2016, 05:45:40 AM
Fox, at least read the wikipedia article (https://en.wikipedia.org/wiki/Z-buffering) before you try to help someone. The z-buffer is typically stored as a normalized 24-bit or 32-bit fixed point number (not floating point, and not an integer), taking on a value between 0 and 1, where 1 represents the cut-off point for rendering, and 0 represents the camera. This makes the camera size-agnostic, capable of handling both large and small scenes alike. Note that this isn't simply stack ranking their depth; it's precisely calculating *how* far away an object is from the camera.

As I understand it, the z-buffer essentially operates as an evolved version of the reverse painter's algorithm, but instead of operating on entire objects, it operates on individual pixels. The rendering engine examines each object in the scene that could potentially occupy a given pixel, and performs a simple less than check. It then selectively renders only the object with the lowest value (i.e. is nearest to the camera). It's important to note that it's only rendering a pixel, which is only a small sample of the object; it does not render the whole object, so if an object is partially occluded, it will only be partially rendered. This saves an immense amount of processing by reducing the amount of data that needs to be sent to the GPU; there's no need to send the data for 100 objects if only 50 of them are ever visible in the scene, and only half of those 50 objects are ever fully visible. Sending data to the GPU is the primary bottleneck in the rendering pipeline, so while you do end up saving by not doing the additional rendering passes for the hidden objects, the greatest saving ends up being that the data for the hidden objects is never sent to the GPU to begin with. Naturally, this is only useful for opaque objects.

As for a frame buffer object... I don't really know how that relates to solving the depth problem. From some cursory searching, it seems to be an OpenGL-specific thing, though other APIs use similar systems. It's basically a back buffer that can have post-processing effects applied to it. So it calculates the rendering for the next frame in one section of memory, applies whatever effects it needs to, then points to the data for that frame on the next draw call. Use of a back buffer is extremely common in rendering as a means of solving screen tearing, since there's always a complete image for the screen to display on a given frame.


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: Fox on March 05, 2016, 06:13:56 AM
I saw that article when I was looking up the Painter's Algorithm article... I did go to the Z-Index article from there, and yes, I did read some of it at that time... not the whole thing because it's long... . (I don't think I was fully paying attention, though..  But I do remember reading about the 16-bit+ part and that 8-bit was rarely used... and was thinking about that in my post.... What I SHOULD have paid attention to and looked up was fixed point... since I didn't exactly realize what that was... And assumed you could use any data type you wanted as long as you had enough bits... (Yes, you can put (invisible) decimal numbers in ints (if number is shifted) ... But not straight forward for numbers that are repeating like 1/3rd, which could be rounded anyway...) based on some quick theories... note that I've not built my own 3D engine yet, but I know that with some research I can do it. (Including sin/cos rotation) Don't exactly have the motivation right now, though.)

And yes, 0 being the camera's position makes a lot of sense.

But since you seem more knowledgeable about terms, then I leave the answers up to you for right now, I guess.

I've known this for a while now, though... And I think of both as floating-point.
32-bit = Single
64-bit = Double
And huh... must have missed Decimal (fixed-point.) (I recognize that keyword Decimal, but I not pay much attention to it. - I get the feeling it is one of those things I looked up in the past, learned it was fixed-point... and then forgot about it, though.) -  I still prefer to use the integer data-types when possible, though... it's just my way of doing things, I guess. (It is possible there may be exceptions, however. But so far, I haven't had to really worry about it in my coding as of yet... - I can maybe think of some things where one may get the computer's date/time (Double), though... But we're not likely to need that here.... )


-----
TL;DR = Basically, this post doesn't actually contribute to the topic itself.... so moving on...


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: Luna_blade on March 05, 2016, 07:09:33 AM
Quote from: Fox
@after the depth calculations: Do you mean like the HUD one might always make displayed in front?
If you want something to always display in front... you just draw it after you've drawn your 3D map... (For stuff always on top, you may not need to use z-index table anymore... unless you got some more priority-ing going on, maybe..)
Well after depth calculations, the GPU starts to actually draw the frame. That's more what I meant.

As I understand it, the z-buffer essentially operates as an evolved version of the reverse painter's algorithm, but instead of operating on entire objects, it operates on individual pixels. The rendering engine examines each object in the scene that could potentially occupy a given pixel, and performs a simple less than check. It then selectively renders only the object with the lowest value (i.e. is nearest to the camera). It's important to note that it's only rendering a pixel, which is only a small sample of the object; it does not render the whole object, so if an object is partially occluded, it will only be partially rendered. (quote shortened)
So if I understand correct: first when a polygon is rendered it's pixel are give a depth value, then they are placed in the Z-buffer. And when the depth calculations are over, every pixel from this object that is visible, is drawn.

I think I understand now. Isn't it however a bit silly that the GPU still has to fetch all the colors and texture for the given drawn pixel?
Also, by using a Z-buffer, you can't just draw triangles anymore (not that it mattered for untextured things though), but have to use something else?


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: leaf on March 05, 2016, 09:18:33 AM
How is it silly? Yes, it needs to fetch the texture data, but it only fetches that texture data once for a given object, regardless of how many pixels it takes up on screen.

Second part, not sure what you're asking, but I think that's my fault for the way I explained it. You still need to know the geometry of an object to use z-culling, but you get the advantage of fewer draw calls. Calculating geometry is done by the CPU, and is no where near as big of a deal as the process of actually rendering a texture or a light to screen.

As I alluded to earlier, sending data to the GPU is the slowest part of the rendering pipeline. It's the physical act of data being sent across from the CPU to the GPU that is slow, but it needs to be done for each draw call, which writes the display data to the buffer. Thus, we can improve rendering time by reducing the number of draw calls. In general, each texture that gets rendered to the screen needs to be a separate draw call, and game engines like unity will often batch all objects with the same texture in one draw call; this optimization is possible thanks to the z-buffer.

For example, suppose you're using the painter's algorithm. You perform a draw call for the far objects, then the nearer objects, then the nearer-nearer objects, and so on. Even if some of these objects use the same texture, they still need to be separate draw calls, because one might get overwritten later, and the buffer only stores a flat image. But, with z-culling, you calculate ahead of time which objects should actually be rendered. So if something is half-occluded, you're only writing to half as many pixels when you draw that object, and those pixels don't get written to by any other objects in the scene*. This isn't a big deal on its own (writing to a pixel is relatively cheap, performance-wise), but what happens if you have another object with the same texture in the scene, also visible in the viewing plane? Both objects can now be rendered in the same draw call, because you've calculated ahead of time which objects should be rendered in the scene. You end up only sending that texture data to the GPU once, instead of multiple times.

*(Except lights. Baked lighting is one additional draw call after all other objects are rendered, and each dynamic light is another.)


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: Luna_blade on March 06, 2016, 06:47:15 AM
Oh right! That makes sense.


Title: Re: Anybody who can explain Z-buffer and Framebufferobjects?
Post by: dave newman on November 01, 2017, 09:52:10 AM
That's what I thought. Thanks for clarification!