Pages: [1] 2   Go Down
Author Topic: copy back buffer to texture streched? RTT for postprocess?  (Read 7108 times)
August 01, 2008, 01:31:02 pm

This time, I have two questions.

First one is,,,
I don't get the defference between "copy back buffer to texture" and "copy back buffer to texture streched".
This is from wiki

Copy back buffer to texture
Copy the current back buffer to a linked texture channel. This is done pixel perfect. If the texture is to small pixels are skipped. If the texture is to large only part of the texture is filled.

Copy back buffer to texture streched
Copy the current back buffer to a linked texture channel. The backbuffer will be stretched to fit exactly in the attached texture channel.

I think texture size depends on texture that I load.
What is the case "if the texture is to small"?
What benefit does "to texture streched" bring?

Second question,
When I rendertotexture my scene with using "use exact backbuffer size" option, say for postprocess effect, I found the texture got a little blured even if I render that back to fullscreen so that I see the texture in the same resolution with true scene.
I tried to disable texture filtering but made no sense.
Is there any tips for avoiding this?
August 01, 2008, 02:41:14 pm
I've also been having a lot of problems with backbuffer copying in the past. Here is how to do it:

- Don't render below a RenderToTexture to avoid scaling. Just render to the backbuffer (= normal render) and then use "copy back buffer to texture".
- Always put a RenderToTexture below a "copy back buffer to texture". (Never a simple Texture channel.)
- Check "Use exact backbuffer size" and uncheck "Clearscreen" and "Use backbuffer rendering".
- If you render the texture every frame, check "Channel renders every frame" (Makes the difference between main or GPU memory storage and a lot of performance.)
- If you want to retrieve where you did and where you didn't draw, check "Use ARGB" (I always do, can be very useful.)

Copy back buffer to texture will now copy image data exactly the size of the current viewport to the texture. Do note that it will always copy from the the top left of the screen, so your viewport should always be located there. If you use a 16:9 viewport with black bars around for example, place it at the top for render passes that go to a buffer. Place it at the middle for the final render.

Now, the next tricky one. Pixel perfect upsampling. Here is how I do it. I don't use a specific camera to avoid messing with my scene camera. I don't use a pixel perfect square, because, it is not. I use a square primitive, with Z motion set to 2 and scale set to 3. The parent of the motion is the current camera matrix (Using a MatrixOperator.) I attach the pixel size to the HLSL as a vector using 1 divided by the viewport width and 1 divided by the viewport height. In HLSL, there are the following elements:

- The vector input for the pixel size:
float2 pixel_size : CHANNELVECTOR0;

- Some CPU calculations for the transform:
static float2 uv_offset = 0.5 + 0.5 * pixel_size;
static float4x4 uv_matrix = float4x4(0.5, 0.0, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, uv_offset.x, uv_offset.y, 0.0, 1.0);

- The sampler of the backbuffer copy:
texture base_map         : TEXTURE0
   string ResourceType = "2D";

sampler2D base_sampler = sampler_state {
   Texture   = <base_map>;
   MinFilter = NONE;
   MagFilter = NONE;
   MipFilter = NONE;
   AddressU = CLAMP;
   AddressV = CLAMP;

- In the vertex shader:
output.uv_project = mul(output.clip_pos, uv_matrix); // float4

- In the pixel shader:
float4 result = tex2Dproj(base_sampler, input.uv_project);

- In the technique some addition to always draw on top:
ZEnable = FALSE;
ZWriteEnable = FALSE;

And that should do the trick. Pixel perfect to the buffer and pixel perfect back to the screen.
August 03, 2008, 08:51:09 pm
Great post Jos. Thanks for sharing.
August 04, 2008, 02:09:13 am
Thank you very much!
I'll try your unsampling method.
and what about "copy backbuffer to texture stretched" ?
does anyone have an idea?
August 05, 2008, 11:01:16 am
On copy back buffer to texture stretched I can be short. Don't use it. It does a nearest neighbour resize and that really is not what you want. Use the pixel perfect way instead and scale down using shaders if needed. The bloom effect that comes with Quest3D by default can help you on your way with downscaling and blurring HLSL code. It's also a good example of when you would want to scale down. (Before blurring.)
August 11, 2008, 05:05:27 pm

This might be a good add as an article/tutorial to the knowledgebase.

Also, Quest3D might want to evaluate some of this for inclusion into the documentation for the associated channels.  I haven't looked at that documentation, lately, but this seems as though it contains worthwhile information.  That it's being stated implies that the documentation probably doesn't already contain the same information or that there may be gaps in the information.

Just a few thoughts!

noticed and corrected a typo.

August 11, 2008, 10:50:02 pm
There actually is a bit of a gap. The thing is, the upsampling done in the templates generally works fine. But, it doesn't seem to work fine with the HD48x0 series. There will be a pixel offset in the bottom right part of the screen. That's why I had to look into it for our demo. I do 3 full screen upsamples in there and that results in a 3 pixel shift on HD48x0 cards which is very noticable.
August 14, 2008, 02:16:15 am
Thanks Jos.
Your umsampling method works very fine!
I also think this really worth adding to the knowledgebase Grin
August 14, 2008, 03:12:33 pm
It's been my experience that whenever someone on here has a special case usage which requires something extra-special beyond what is included in the templates or tutorials that someone else, or perhaps many someones else, finds themself in need of a solution to either precisely the same problem, or one so similar as not to matter.  Even if it's an identical solution to the one in the tutorials, it's often even worthwhile to see another developer's solution to the problem.  The difference, even if small, may be enough to trigger the correct way to solve one's specific problem, even if the code is only trivially related.  So, even if it's specific, it's probably good to add it.  If you do want to post a tutorial and it's for a specific case, simply specify the specific case, as well as perhaps other related cases you think the solution might work for.

June 22, 2009, 05:47:15 pm

I have been trying to achieve a proper understanding of how to apply post process effects and I came across this post and Jos's method for pixel perfect copying to the buffer and then back to the screen. As useful as it is to use the templates, I prefer to try it myself so that I understand it better.

From looking at the forums there seems to be many different ways to upsample the final image. Some methods use a camera and a square, others don't use a camera at all. Other methods have the effect applied to the editor camera as well as the project camera.

My question is, why are there so many different methods, which one is the best and which one is most efficient? Is it just a personal preference or are some more "correct" than others? Is one method more advanced than others? Which one should I use?

I have tried to implement Jos's elegant solution but it is not working properly (there is a gap on either side of the square). I will post my example once I organise the channel graph.

If anybody can post an example to show me the best and most correct method of upsampling, I would be very grateful.

Many thanks for your time.

June 22, 2009, 05:55:06 pm
Simply use pixel-perfect square (it's one of the primitives), in 4.2.3 it's indeed pixel-perfect. Just attach a texture to it.

Upgrade to PSSM is available for SSAO customers. Check for details.
June 22, 2009, 06:49:39 pm
Hi Viktor,

Thank you Viktor, I will try the pixel perfect square [even though Jos said it was not pixel perfect  Wink.] From looking at your work (which I admire greatly), I see that you use a flat camera. Is that the best way?

Here is my cgr(Quest 3D v4.2.3 and published version). If you press spacebar to swap the texture from the RTT to standard texture, you can see that there is a gap at either side of the upsample square. Do you think this is something to do with the projection matrix of the main camera? Do you approve of my technique?  Red face

Many thanks

* upsampling_test.cgr (5295.9 KB - downloaded 438 times.)
June 22, 2009, 07:28:01 pm
I think it wasn't pixel perfect in 3.6.6 I had the same issue as Jos described.
One important note: right now, I always use a shaders to render texture back to screen. For arbitrary geometry and pixel perfect square I was using VPOS semantic (assuming that it wasn't pixel perfect) and one time, don't remmeber why, I've just used a UV0 set of the pixle perfect square and result was matching one to one with using VPOS and shift by a half a pixel.

Ouchh, need to throw away this VPOS stuff from current techniques, will save a couple of instructions  Grin

I'll take a look at you file.

Upgrade to PSSM is available for SSAO customers. Check for details.
June 22, 2009, 08:19:59 pm
Just change a Square primitive to Pixel-perfect square, it's in the same drop down menu.

Upgrade to PSSM is available for SSAO customers. Check for details.
June 22, 2009, 10:00:07 pm
Simply use pixel-perfect square (it's one of the primitives), in 4.2.3 it's indeed pixel-perfect. Just attach a texture to it.
Glad to hear that's fixed. I only noticed the problem with 3.6.6 on HD48x0 cards, so it's not surprising it took some time to get discovered.
Pages: [1] 2   Go Down
Jump to: