Sign in to follow this  
captain_crunch

How do I output 1 float in 2 channels with HLSL

Recommended Posts

captain_crunch    781
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?

Share this post


Link to post
Share on other sites
ET3D    810
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.

Share this post


Link to post
Share on other sites
captain_crunch    781
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...

Share this post


Link to post
Share on other sites
adt7    751
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.

Share this post


Link to post
Share on other sites
captain_crunch    781
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?

Share this post


Link to post
Share on other sites
captain_crunch    781
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!

Share this post


Link to post
Share on other sites
RDragon1    1205
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?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this