How do I output 1 float in 2 channels with HLSL

Started by
6 comments, last by RDragon1 14 years, 10 months ago
In my pixel shader I have a float valued from 0 - 1. I would like to output it over two color channels of the render target to get more than one byte of precision. But I cannot figure out the best way to do it. This code: output.Depth.xy = depth; simply places the same value in both color channels. So, what is the correct way of doing it? Is it necessary to use bit shifts or is there a simpler way?
Advertisement
The correct way of doing this is to use a float render target, such as D3DFMT_R32F (for D3D9).

If for some reason you have to use 1 byte per channel, you can assign the depth as is to one channel and frac(depth*256) to the second.
To only render depth you could turn off color writing and use a depth replace fragment shader
Thank you!

Unfortunately I can't use the float rendertarget. I am using multiple render targets to render output color and a depth/distance value at the same time. And they are required to be of the same type.

And I am still a bit lost.

I want to store the high-precision float in two bytes, and then in my second draw, when the value comes in as a texture, I need to put the float value back together again. How do I do this?

// store the float
float distanceFromViewer = 0.6053; // high-precision number for testing
output.DistanceFromViewer.x = distanceFromViewer;
output.DistanceFromViewer.y = frac(distanceFromViewer*256);

// re-assemble the float from texture:
float4 depthMapInfo = tex2D(DepthMapSampler, input.ScreenPosition);
float distanceFromViewer = ???

The things I try seem to give the incorrect result...
Quote:Original post by captain_crunch
Thank you!

Unfortunately I can't use the float rendertarget. I am using multiple render targets to render output color and a depth/distance value at the same time. And they are required to be of the same type.


They are required to be the same bit depth, not the same type.

IE. You can use an R32F target and A8R8G8B8 target together since they are both 32 bit.

I have another precision-related problem in the same shader.

The DistanceToViewer value that I read in from the texture gets compared to one that I compute in the vertex shader. So these two numbers need to be the same precision.

But it seems I lose the last decimals somewhere on the way from the vertex shader to the pixel shader.

// vertex shader output:
float DistanceFromViewer : TEXCOORD2;

output.DistanceFromViewer = 0.6503; // test value

Now, when I read this value in the pixel shader, the last decimal is lost, so the number is 0.650!

float distanceFromViewer = input.DistanceFromViewer;

How can this be?
I got it working now with the 16-bit render target.

The second problem was just PIX confusing me. It only shows 3 decimals in the variable and register watch window. After I multiplied with 10000 I could see the missing digits.

Thanks everybody!
Quote:Original post by captain_crunch
...
I am using multiple render targets to render output color and a depth/distance value at the same time.
...


Why aren't you using the depth buffer to output the depth value?

This topic is closed to new replies.

Advertisement