Jump to content
  • Advertisement
Sign in to follow this  
xsirxx

How to take a Normal and store/retrieve unsigned in HLSL?

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

My nvidia 6200 and 6600's dont like bump map format D3DFMT_Q8W8V8U8, and output looks crazy when I use floating point D3DFMT_A16B16G16R16F(64bit i think). So my last idea was to take the normal when I create my normal map and store it as fixed point signed. My shader X2 book uses a formula: Normal = 0.5 * (Normal + 0.5). Then it retrieves it from the texture with: Normal = 2 * (Normal - 1). Although this doesnt help me relieve the artifacts showing up. Is this correct or not? Is there another way of getting around having to use a signed format? Thanks, Brad

Share this post


Link to post
Share on other sites
Advertisement
There may be a better solution, but the usual way to store normals in an RGB texture is this:
    r = x * 0.5f + 0.5f
g = y * 0.5f + 0.5f;
b = z * 0.5f + 0.5f;
And to extract normals is the inverse:
    x = ( r - 0.5f ) * 2.0f;
y = ( g - 0.5f ) * 2.0f;
z = ( b - 0.5f ) * 2.0f;
The basis for this is that the range for the coordinates of a normal is [-1,1] and the range for colors is [0,1]. Actually, the only difference between mine and yours is the location of the parentheses.

Share this post


Link to post
Share on other sites
1) The conversion from signed to unsigned you posted looks about right.

2) To convert from unsigned to signed in a pixel shader: N=2*(N-0.5) [that's what the _bx2 1.x asm modifier does].

3) I don't think those nVidia chips actually support the D3DFMT_A16B16G16R16F format.

4) But AFAIK they *do* support D3DFMT_Q8W8V8U8 and its variants.

5) If resolution of the format is an issue, you could use one of the U16V16 type formats and generate the remaining component of the normal in the shader (as long as the vector is normalised, you _know_ its length is 1). You'll find an explanation of the maths in papers on the nVidia and ATI websites (I'm too tired at the moment - but it's not particularly difficult).


[EDIT: heh, John beat me to it with points 1&2]

Share this post


Link to post
Share on other sites
That sounds right, I actually went another way of going about it, but im gunna try yer method as well.

Is there an errata for Shader X2?

Also, s1CA, I did already try to run D3DFMT_Q8W8V8U8 but it throws some really odd results at me. Alls I see are random pixels all over the place...

Note that if I compress(however u say it) the normal in the signed format, it runs just fine.

Share this post


Link to post
Share on other sites
If 8 bits per components isn't enough (and that might well be your problem), try A2R10G10B10 for your normal map texture. It should be supported with most new cards anyway, and 2 supplementary bits are worth here (but you can't really use the alpha compenent).

Share this post


Link to post
Share on other sites
Quote:
Original post by JohnBolton
Actually, the only difference between mine and yours is the location of the parentheses.


erm.... correct me if I´m wrong, but I think yours is NOT the same as the one xsirxx posted.
(x - 0.5f) * 2.0f isn´t the same as
(x - 1.0f) * 2.0f,
and I´d vote for (x-0.5f)*2.0f to be correct, which would be your equation, JohnBolton.
So this could be the issue, namely that xsirxx conversion from [0; 1] to [-1; 1] is wrong. xsirxx´s conversion would be from [0; 1] to [-2; 0]... If it has already been corrected, just ignore this post ;)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!