# 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.

## 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 on other sites
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 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 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 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 on other sites
Quote:
 Original post by JohnBoltonActually, 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 ;)

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 9
• 9
• 9
• 14
• 12
• ### Forum Statistics

• Total Topics
633295
• Total Posts
3011243
• ### Who's Online (See full list)

There are no registered users currently online

×