<p>I generate a normal GBuffer in my engine, and I store it using a R16G16B16A16_SNORM format like this:</p>
<pre><code>input.normal = normalize(input.normal);
input.tangent = normalize(input.tangent);
float3 binormal = normalize(cross(input.tangent, input.normal));

float3 normal = (normalMap.Sample(SampleType, input.tex).rgb * 2.0) - 1.0f;
float3x3 texSpace = float3x3(input.tangent, binormal, input.normal);
float3 finalNormal = normalize(mul(normal, texSpace));

output.normals = float4(finalNormal.rgb, 1.0f);
</code></pre>
<p>But when debugging the frame in RenderDoc, I notice that the 3rd component of the frame (Z, or blue channel) is always 0.0</p>
<p><a href="https://i.sstatic.net/yPsQI.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/yPsQI.jpg" alt="enter image description here" /></a></p>
<p>As you can see, both the blue and alpha components come back as zero, even though the alpha is explicitly set to 1.0 in the shader. The frame visually contains information in the blue channel, so why is it coming up as 0.0?</p>

CC BY-SA 4.0
2021-10-25T19:39:03.627Z
If you compute $sqrt(0.86633^2+0.49866^2)$ the result is 0.99959 which is what you would expect for a normalized direction vector. So something seems to be up with which texel is being picked by the debugger.  Also, if you tell directx that the format is snorm then doesn't it take care of the *2-1 bit on behalf of the shader so the hlsl code can skip it.
pmw1234
CC BY-SA 4.0
2021-10-26T16:49:52.310Z
@pmw1234 Thanks I wasn't aware of the * 2.0 - 1.0 part, first time using a SNORM texture format. I submitted an issue on the renderdoc github maybe they can figure it out.
H3XXX
<c++><hlsl><directx>
16 bit SNORM format not correctly storing Z component?
H3XXX
# 16 bit SNORM format not correctly storing Z component?

(Asked by: username_0 on 2021-10-25)

I generate a normal GBuffer in my engine, and I store it using a R16G16B16A16\_SNORM format like this:

```
input.normal = normalize(input.normal);
input.tangent = normalize(input.tangent);
float3 binormal = normalize(cross(input.tangent, input.normal));

float3 normal = (normalMap.Sample(SampleType, input.tex).rgb * 2.0) - 1.0f;
float3x3 texSpace = float3x3(input.tangent, binormal, input.normal);
float3 finalNormal = normalize(mul(normal, texSpace));

output.normals = float4(finalNormal.rgb, 1.0f);

```

But when debugging the frame in RenderDoc, I notice that the 3rd component of the frame (Z, or blue channel) is always 0.0

[![enter image description here](https://i.sstatic.net/yPsQI.jpg)](https://i.sstatic.net/yPsQI.jpg)

As you can see, both the blue and alpha components come back as zero, even though the alpha is explicitly set to 1.0 in the shader. The frame visually contains information in the blue channel, so why is it coming up as 0.0?

**Tags:** c++, hlsl, directx

> **Comments:**
> **username_1**: If you compute $sqrt(0.86633^2+0.49866^2)$ the result is 0.99959 which is what you would expect for a normalized direction vector. So something seems to be up with which texel is being picked by the debugger.  Also, if you tell directx that the format is snorm then doesn't it take care of the *2-1 bit on behalf of the shader so the hlsl code can skip it.  
> **username_0**: @username_1 Thanks I wasn't aware of the * 2.0 - 1.0 part, first time using a SNORM texture format. I submitted an issue on the renderdoc github maybe they can figure it out.  

---

## 0 answers

