Interlaced rendering - image space translation?

Started by
7 comments, last by Robert Frunzke 17 years, 7 months ago
The bottleneck of my application is the pixel shading. So my idea was to use interlaced rendering: render a frame with half height, toggle the rendering target (two FBOs), and generate the final image as a composition of current and previous rendering. This works very well, and one does not see the interlacing (because changes in my scene are rather smooth). Only problem is that the resulting rendering has only half the y-resolution and aliasing becomes a problem. So the next idea is to toggle a one pixel y-offset between the frames. So that each frame renders another half-picture of the final rendering - as it should be - interlaced. But how to compute the required offset for the modelview matrix, or how to apply the offset otherwise (e.g. on the projection matrix)? The whole scene somehow has to be translated by one pixel in image space. Without interlacing: With interlacing (and some fake anti-aliasing applied):
Advertisement
Very interesting approach :)

How about not applying an offset at all but masking out the areas that you don't want to draw (every other line in your case). It sounds like glPolygonStipple will do the trick.

Quote:If it's enabled, a rasterized polygon fragment with window coordinates x and y is sent to the next stage of the GL if and only ifwthe (x mod 32)th bit in the (y mod 32)th row of the stipple pattern is 1 (one). When polygon stippling is disabled, it is as if the stipple pattern consists of all 1's.

Let me know if and how it works for you, might be interested in implementing something similar in my engine :)

I tried the polygon stipples, but it did not work as expected, cause it breaks the tone mapping and bloom effect, the black lines make trouble. Is there another option?
Ok, it works now. Using just one FBO, and the stippling pattern, replacing clear with drawing a black fullscreen quad and so on.

And you cant spot the difference in still images:


But in motion you clearly see the difference:


But thats ok in my case.

Thank you for the hint nts!

The algorithm is simple:

static int toggle = 0;
toggle = !toggle;
glPolygonStipple( patterns[toggle] );
clear scene by drawing fullscreen quad with clear color
render scene

It should also work without using FBOs if you can assume that the backbuffer will be copied, not swapped.
The performance for a window of 1024x450:

without interlaced rendering: 35fps
with interlaced rendering: 40fps

And the difference increases as window / screen size increases. And it gives the possibility to put more power into the pixel shaders.

Sorry to spit in your soup, but:

The next logical step would be to implement an adaptive deinterlacer to get rid of the artifacts. As long as you have scenes with little to no horizontal scrolling, your approach may be all right, but once that's not the case anymore, you'll wish you hadn't taken a route that has plagued TV for ages now.

You've gone from 28.6ms/frame to 25ms/frame, in a range where it may not even be noticeable for slow-moving objects, by using a method that will definitely kill fast movement.
I doubt that an adaptive interlacer would help.

Well, usually the scene looks like the following image - smooth changes everywhere, not user-interactive, so the interlacing is totally ok (I would not even have tried to implement this algorithm otherwise).



The only real problem is the snow, which is a rather fast moving thing compared to the rest.



It depends on framerate of course and I do not have a good solution yet (except to increase framerate, which would make the interlacing less visible). However, animated it still looks ok.
Quote:Original post by Robert Frunzke
The algorithm is simple:

static int toggle = 0;
toggle = !toggle;
glPolygonStipple( patterns[toggle] );
clear scene by drawing fullscreen quad with clear color
render scene


Glad it works, that's almost the algorithm I had in mind too. :)

Just one question, why are you clearing the screen by drawing a quad with the clear color (why do you need to clear the color buffer at all)?

From the looks of it you should just need to clear the depth buffer and not even do it every frame (every 2 frames).

Quote:
Just one question, why are you clearing the screen by drawing a quad with the clear color (why do you need to clear the color buffer at all)?

From the looks of it you should just need to clear the depth buffer and not even do it every frame (every 2 frames).


In short: its just required in my case. For other applications it may not be required. Depth buffer clear is always required, forgot to write that.

Long description: The rendering consists of different layers: one nightsky layer (with stars drawn as billboars), the moon, the atmosphere (which uses alpha to blend to nightsky), the cirrostratus clouds, cumulus clouds, the ocean and the islands.

So, day sky does not require the clear, but the night sky. ´There is no on/off switch for day and night. Stars will be drawn at day, atmosphere drawn at night. And a smooth transition between day and night occurs. So, the clear is just required.

This topic is closed to new replies.

Advertisement