Not logged in, Join Here! or Log In Below:  
News Articles Search    

 Home / 3D Theory & Graphics / Viewport Shifting in subpixel space ??? HowTo ? Account Manager
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.

April 22, 2005, 04:20 AM

I'm trying to implement a technique described in Game Programming Gems 4, used to build high resolution antialiased screenshots.

In the article, the writer speaks about viewport shifting, an important part of the algorithm relies on that.

But he is ALWAYS talking about viewport shifting in SUBPIXEL space, which means he shifts the viewport within a pixel unit, with translations smaller than a pixel.

In D3D I found no way of doing that, the API allows to shift the viewport in pixels but not less than a pixel.

Is there a way of doing that quite simply or not ...

Thanks a lot.



April 22, 2005, 06:15 AM

I suppose you do it by adding a small x/y translation matrix after your normal projection matrix. Then you can shift the pixels in clipspace, which is basically normalized screenspace...
so 1 pixel would have the dimensions 1/width and 1/height in clipspace.

Just remember that the coordinates are still homogenous at that point, so you should multiply your subpixel offsets with w aswell (just put them in the right part of the matrix, it's basically a skewing operation).


April 22, 2005, 06:58 AM

Thanks a lot !

I will try that right away and let you know if i'm facing difficulties.


Erik Faye-Lund

April 22, 2005, 10:19 AM

As Scali said, add fractions of w to x and/or y in clipspace to get subpixel viewport-shifting... this could easily be done in a vertexshader.

Fabian 'ryg' Giesen

April 22, 2005, 11:15 AM

You can just make that part of your projection matrix, no additional code in the vertex shader required.


April 26, 2005, 03:20 AM

I'm not sure of what I'm doing, I tried different stuff but I'm not a master yet in projection matrix and crap ...

My viewport is 1280*768, what I do is 2.0f/1280 and 2.0f/768 to have the size of a pixel. (2.0f cause in projection space values are within -1 +1 range).

Then I just multiply these obtained values by W (i'm not sure its W lol) :

W = z_far/(z_near - z_far)

So the final pixel size in projection space is

PixXSize = (2.0f/1280)*W
PixYSize = (2.0f/768)*W

Then to do my viewport shift, of let's say 1/2 pixel on X/Y I just put PixXSize/2 and PixYSize/2 in the bottom row (first and second column) of my projection matrix.

The translation of the "viewport" seems to be done correctly, however I'm not sure it shifts the viewport to the value I would like to shift it, as I dont get the good final result i'd like to abtain. Maybe my computations are wrong, maybe it comes from somewhere else ...

Please help if you know !

Thanks already ... :)


Victor Widell

April 26, 2005, 04:47 AM

I believe "W" refers to the 4th value of each vertex. (You know, on vertex = x,y,z,w.)


April 26, 2005, 04:59 AM

Yes I know that well, but got no vector here ;)


Erik Faye-Lund

April 26, 2005, 05:27 AM

just multiply your projection-matrix with something like this:

[ 1 0 0 (2 / viewport_width) * h_offset
0 1 0 (2 / viewport_height) * v_offset
0 0 1 0
0 0 0 1 ]

where (ofcourse) h_offset and v_offset is given in pixels.


April 26, 2005, 06:32 AM

Yes, if you post-multiply Erik Faye-Lund's matrix to your projection matrix, you basically get this idea:

Let x, y, z, w be the homogenous coordinates in clipspace, so after multiplying with the original projection matrix...

x' = 1*x + 0*y + 0*z + (2/viewport_width)*h_offset*w
y' = 0*x + 1*y + 0*z + (2/viewport_height)*v_offset*w
z' = 0*x + 0*y + 1*z + 0*w
w' = 0*x + 0*y + 0*z + 1*w

Then the homogenous coordinates will be projected back to w=1 for the perspective:

x'/w = x/w + (2/viewport_width)*h_offset
y'/w = y/w + (2/viewport_height)*v_offset
z'/w = z/w
w'/w = 1

Then the x and y coordinates will be scaled to the viewport:

vx = ((x/w) + (2/viewport_width)*h_offset)*viewport_width/2 = x/w*viewport_width/2 + h_offset
vy = ((y/w) + (2/viewport_height)*v_offset)*viewport_height/2 = y/w*viewport_height/2 + v_offset

So there you are, the offsets you've added, are now absolute in terms of screen pixels.


April 26, 2005, 08:02 AM

Thanks you all very much for these explanations !!!!!!

I'll keep you informed :)


This thread contains 11 messages.
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.