Question about Temporal Upscaling - Killzone Style

I was reading the presentation for Killzone Shadow Fall and I have a question about their temporal upscaling solution. In the slides they state they render two 960x1080 buffers with one containing odd pixels and the other containing even pixels. I am a little confused how you would do this. I know how you can just write odd or even pixels to the framebuffer using something like this:

Code:
// Default color is fully transparent
float4 color = 0;

// Scale to int texture size, add x and y
float2 vpos = texCoord * TextureSize * 0.5f;
float vposSum = vpos.x + vpos.y;

// Calc diff between rounded half and half to get 0 or 0.5
float diff = round(vposSum) - vposSum;
float diffSq = diff * diff;

// Even or odd? Only even pixels are sampled
if(diffSq < 0.1)
{
color = tex2D(TexSampler, texCoord);
}
return color;

But how would you have a buffer filled entirely with just odd pixels and not have "gaps" where the even pixels would be? Could someone explain this to me? Its probably something obvious I am just not understanding.
 
Maybe it's similar to (IIRC) Crytek's chroma-sub-sampling technique. I'll try to remember which paper its described in... and I think there's a thread on it in this subforum.

edit - done similarlly to
 
Last edited:
You shouldn't need to do anything special when initially rendering the scene to a 960x1080 target. You should be able to just render normally, with a screen-space half-pixel offset to either the right or to the left depending on whether you're rendering an "even" frame or an "odd" frame (-0.5 for even, +0.5 for odd). This could be done by adding the offset into the projection matrix. Then at the end of the frame, you would perform the upscale by combining the current frame's data with the previous frame's data. You would essentially render to a 1920x1080 render target, and in the pixel shader you would choose which texture to sample based on whether you're shading an even pixel or an odd pixel. I made a really quick diagram to show what I mean:

temporalupscale.png

So since you're initially rasterizing at half the horizontal resolution, the spacing of the pixels in a 2D grid will naturally place them at either the "odd" or "even" locations in the final full-resolution image.

I'll also note that their upscaling step was a bit more complicated than what I described. They also sample the result from 2 frames prior, and use that data as well as the current frame's data to determine whether or not to accept the previous frame's data. If they decide to reject the previous frame result, then the "in-between" pixel is computed by interpolating its neighbors from the current frame.
 
Back
Top