Was just reading an article on here about dynamic rendering (dynamic screen resolutions). I'm new to some of those terms, so I wanted to ask about viewports and "off-screen render targets", what the buffer is that stores said "render target"...and what all that means. I know it's fairly straightforward stuff, but I need to have a lil' jump start here. Thanks!
A "render target" is just a large block of video memory that has been set up to hold an image and allow the GPU to draw into that image. By default you have two render targets, a "front buffer" and "back buffer". The front buffer is what is being displayed on screen at any given moment; the back buffer is where GPU-rendered triangles etc. are getting drawn. Once the frame being built up in the back buffer is finished, the two are swapped, so the frame that just finished is displayed on screen. The dual buffers are used to prevent flickering; the user does not see the frame as it's being composed by the GPU, but only sees the completed frame. The previous front buffer is now the back buffer and its memory is reused to create the next frame.
However, you can also create additional render targets - as many as you want. These offscreen render targets never get displayed directly. They act as scratch space where you can do some rendering, then later use the rendered image as a texture for further rendering. An example of an offscreen render target is a shadow map. You'd draw the scene from the light's point of view, then use that later in a shader to calculate shadows, but the shadow map itself is never directly displayed on screen.
In the case of the dynamic-resolution-rendering article, they're basically suggesting rendering the scene to a variable-size offscreen render target, then stretching that image to the size of the actual back buffer. The point is that by varying the size you can stabilize performance; you can make the buffer smaller and therefore faster when the rendering slows down, and make it larger and more detailed when the rendering is fast.
The "viewport" is the rectangle that the GPU draws into, within the render target. Almost always, the viewport will be equal to the entire render target, but if you wish you can set the viewport to a sub-rectangle, which will cause the GPU to draw a lower-resolution image and leave some of the render target unused. They're using the viewport to change the size of the image because that's faster than deleting and recreating the whole render target at a different size every frame. Instead, they just create the render target once, using the largest possible size, and use the viewport to control the size after that.
Ah, thanks Reedbeta; very clear and understandable explanation. Thanks again.
I'm curious now; how is a new buffer, or render target (or in this case, the viewport-layered-on-top-of-render-target-buffer) created in code? I use Unity right now, and I'm also curious if such software can perform dynamic rendering.
It would need to be done with the underlying graphics API (Direct3D or OpenGL). Engines often will have a class representing a render target, for the convenience of engine programmers. I'm not certain whether Unity gives you the level of access needed to create and manage render targets yourself, though.
unity would handle it for you.
Thank y'all. Yes, good ol' Unity; guess that's one less thing to worry about.