<p>Assuming that the normal was created by differentiating some height field <code>f(u,v)</code>:</p>

<pre><code>N = normalize(df_du, df_dv, 1)
</code></pre>

<p>What you probably want to achieve is to "strengthen" your normals as-if by scaling that height field by a factor C:</p>

<pre><code>g(u,v) = C*f(u,v)
</code></pre>

<p>Then your new normal would be:</p>

<pre><code>M = normalize(dg_du, dg_dv, 1) = normalize(C*N0, C*N1, N2)
</code></pre>

<p>Translating that to GLSL in your shader:</p>

<pre><code>vec3 GetNormal(){
    vec3 n = texture(normalMap,uv).xyz;
    n = n * 2.0 - 1.0;
    n.xy *= C;
    n = normalize(n);
    return  normalize (v_TBN * n);
}
</code></pre>

<p>By constructing a normal map texture that stores only the height-field gradient <code>(df_du, df_dv)</code> without normalization, using the internal format <code>GL_RG8_SNORM</code> for the texture, and making sure that <code>v_TBN</code> is orthonormal, you can simplify it further to:</p>

<pre><code>vec3 GetNormal() {
    vec3 n = normalize(vec3(texture(normalMap,uv).xy, C));
    return v_TBN*n;
}
</code></pre>

CC BY-SA 3.0
2017-07-27T20:27:41.710Z
BTW, you don't need to normalize twice. :)
Nathan Reed
CC BY-SA 3.0
2017-07-27T20:43:53.617Z
@Nathan: sure, but that's what the OP did. I would use a signed RG texture too, or a quternion based pipeline.
Yakov Galka
CC BY-SA 3.0
2017-07-28T10:15:26.930Z
@ybungalobill but can you point out if there is a problem with my approach because it seems to me like that's pretty similar to what I do.Also,performance wise,I would prefer doing less ALU operations in the fragment shader(the target is mobile platform)
Michael IV
CC BY-SA 3.0
2017-07-28T10:27:01.087Z
Oh, I missed that part. See, in principle it's the same. However, to get correct results you need to reorthogonalize the TBN per-fragment. Even without doing it, you can still improve the code performance wise. First, scale the normal maps so that z=1 and use `GL_RG8_SNORM` to store only the xy components. This already saves you half the memory bandwidth and the `n=2n-1` calculation in the shader. Then your function becomes simply `vec3 GetNormal(){ return v_TBN*normalize(vec3(texture(normalMap, uv).xy, C)); }`, and that's already with correct scaling.
Yakov Galka
CC BY-SA 3.0
2017-07-26T19:36:53.900Z
2017-07-28T10:30:17.600Z
2017-07-28T10:30:17.600Z
Yakov Galka
<p>I am working on a normal mapping. I need to have the ability to scale normal vectors to adjust the normal strength of the surface. Currently the way I am doing it basically shows plausible results. But I am still not sure that it's 100% correct and to my surprise I found no info on the web regarding this subject.
So here is how I do that (my lightning is in camera space):</p>

<p><strong>vertex shader:</strong></p>

<pre><code>vec3 N = normalize(normalMatrix * a_normal); 
vec3 T = normalize(normalMatrix * a_tangent.xyz) * nStrength;          
vec3 B = normalize(normalMatrix * (cross(a_normal, a_tangent.xyz) * a_tangent.w) ) * nStrength; 

v_TBN =  mat3(T,B,N);
</code></pre>

<p>normalMatrix - inverse-transpose of model-view matrix.</p>

<p>The shading itself happens in the fragment shader.
The only relevant part which is happening there is transforming normal from
the texture with v_TBN varying:</p>

<p><strong>Fragment shader:</strong>   </p>

<pre><code> vec3 GetNormal(){
    vec3 n = texture(normalMap,uv).xyz;
    n = normalize(n * 2.0 - 1.0);
    return  normalize (v_TBN * n);
 }
</code></pre>

<p>So, as you can see, I scale tangent and bi-tangent vectors with nStrength scalar.That's the most optimal setup I figured out that gives most correct looking effect.Is this the right way to strengthen the normals?                 </p>

CC BY-SA 3.0
2017-07-26T14:24:40.757Z
I don't think there's a "right" way to "strengthen" normals. It's not clear what your intent is behind it. What kind of visual effect are you trying to accomplish here?
Nicol Bolas
CC BY-SA 3.0
2017-07-26T14:26:41.970Z
The desired  'effect' is a stronger bump.What?There are no standard techniques in CG to do that?
Michael IV
CC BY-SA 3.0
2017-07-26T14:31:58.400Z
What do you mean by a "stronger" bump? Again, what do you want it to look like? Be specific. Generally speaking, bump mapping only effectively works for short bumps (relative to the viewing distance). For taller bumps, you need geometry to reproduce it convincingly. Or at the very least, parallax normal mapping.
Nicol Bolas
CC BY-SA 3.0
2017-07-26T14:35:09.953Z
@NicolBolas I need an ability to adjust the strength similar to how it is done in any typical game engine.If you want an example, open Unity,drop a normal map on a surface and tweak its strength in the inspector.That's the effect. My code currently seems to produce similar effect. But,I wanted to know if there is a standard technique to do that because mine is based on trials&errors.
Michael IV
<opengl><normal-mapping>
Correct way to set normal strength
Michael IV
# Correct way to set normal strength

(Asked by: username_0 on 2017-07-26)

I am working on a normal mapping. I need to have the ability to scale normal vectors to adjust the normal strength of the surface. Currently the way I am doing it basically shows plausible results. But I am still not sure that it's 100% correct and to my surprise I found no info on the web regarding this subject.
So here is how I do that (my lightning is in camera space):

**vertex shader:**

```
vec3 N = normalize(normalMatrix * a_normal); 
vec3 T = normalize(normalMatrix * a_tangent.xyz) * nStrength;          
vec3 B = normalize(normalMatrix * (cross(a_normal, a_tangent.xyz) * a_tangent.w) ) * nStrength; 

v_TBN =  mat3(T,B,N);

```

normalMatrix - inverse-transpose of model-view matrix.

The shading itself happens in the fragment shader.
The only relevant part which is happening there is transforming normal from
the texture with v\_TBN varying:

**Fragment shader:**

```
 vec3 GetNormal(){
    vec3 n = texture(normalMap,uv).xyz;
    n = normalize(n * 2.0 - 1.0);
    return  normalize (v_TBN * n);
 }

```

So, as you can see, I scale tangent and bi-tangent vectors with nStrength scalar.That's the most optimal setup I figured out that gives most correct looking effect.Is this the right way to strengthen the normals?

**Tags:** opengl, normal-mapping

> **Comments:**
> **username_1**: I don't think there's a "right" way to "strengthen" normals. It's not clear what your intent is behind it. What kind of visual effect are you trying to accomplish here?  
> **username_0**: The desired  'effect' is a stronger bump.What?There are no standard techniques in CG to do that?  
> **username_1**: What do you mean by a "stronger" bump? Again, what do you want it to look like? Be specific. Generally speaking, bump mapping only effectively works for short bumps (relative to the viewing distance). For taller bumps, you need geometry to reproduce it convincingly. Or at the very least, parallax normal mapping.  
> **username_0**: @username_1 I need an ability to adjust the strength similar to how it is done in any typical game engine.If you want an example, open Unity,drop a normal map on a surface and tweak its strength in the inspector.That's the effect. My code currently seems to produce similar effect. But,I wanted to know if there is a standard technique to do that because mine is based on trials&errors.  

---

## 1 answers

### Answer by username_2 on 2017-07-26. Score: 7 | Accepted answer

Assuming that the normal was created by differentiating some height field `f(u,v)`:

```
N = normalize(df_du, df_dv, 1)

```

What you probably want to achieve is to "strengthen" your normals as-if by scaling that height field by a factor C:

```
g(u,v) = C*f(u,v)

```

Then your new normal would be:

```
M = normalize(dg_du, dg_dv, 1) = normalize(C*N0, C*N1, N2)

```

Translating that to GLSL in your shader:

```
vec3 GetNormal(){
    vec3 n = texture(normalMap,uv).xyz;
    n = n * 2.0 - 1.0;
    n.xy *= C;
    n = normalize(n);
    return  normalize (v_TBN * n);
}

```

By constructing a normal map texture that stores only the height-field gradient `(df_du, df_dv)` without normalization, using the internal format `GL_RG8_SNORM` for the texture, and making sure that `v_TBN` is orthonormal, you can simplify it further to:

```
vec3 GetNormal() {
    vec3 n = normalize(vec3(texture(normalMap,uv).xy, C));
    return v_TBN*n;
}

```

> **Comments:**
> **username_3**: BTW, you don't need to normalize twice. :)  
> **username_2**: @username_3: sure, but that's what the OP did. I would use a signed RG texture too, or a quternion based pipeline.  
> **username_0**: @ybungalobill but can you point out if there is a problem with my approach because it seems to me like that's pretty similar to what I do.Also,performance wise,I would prefer doing less ALU operations in the fragment shader(the target is mobile platform)  
> **username_2**: Oh, I missed that part. See, in principle it's the same. However, to get correct results you need to reorthogonalize the TBN per-fragment. Even without doing it, you can still improve the code performance wise. First, scale the normal maps so that z=1 and use `GL_RG8_SNORM` to store only the xy components. This already saves you half the memory bandwidth and the `n=2n-1` calculation in the shader. Then your function becomes simply `vec3 GetNormal(){ return v_TBN*normalize(vec3(texture(normalMap, uv).xy, C)); }`, and that's already with correct scaling.  

---

