<p>N dot L will be less then zero and must be computed for the diffuse component and is typically clamped to zero. This can be incorporated into the specular highlight calculation to resolve the issue. What you are describing doesn't come up always in descriptions of Blinn-Phong lighting, I assume, because the writers want to keep things simple. But it is a real issue, I wouldn't go so far as to call it a problem with the lightning model though.</p>
<p>A typical way to resolve it is to add this to the specular compuation (or something like it):</p>
<p>specular = specular * (float)(ndotl&gt;0.0);</p>

CC BY-SA 4.0
2024-06-11T13:36:36.390Z
Brilliant, thank you for the practical solution (we were wondering how to do it without branching).
(Plus, the bit of confirmation this is an real issue which does not always get addressed by authors makes us feel more sane.)
Ad N
CC BY-SA 4.0
2024-06-11T14:41:42.277Z
Sadly, this can lead to an abrupt cut-off of the specular contribution between adjacent polygons where the change of `ndotl` sign occurs, which is very noticeable on smooth surfaces. Maybe some sort of windowing function might be used on `ndotl` and the result used as the operand in place of `(float)ndotl` to smooth things out.
Ad N
CC BY-SA 4.0
2024-06-11T11:45:06.013Z
2024-06-11T13:28:26.193Z
2024-06-11T13:28:26.193Z
pmw1234
<p>In our implementation of the empirical <a href="https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_reflection_model" rel="nofollow noreferrer">Blinn-Phong shading model</a>, we are facing a problem with light-bleeding of the specular component.</p>
<p>The model defines the half-vector <span class="math-container">$\vec{h} = \frac{\vec{v} + \vec{l}}{||\vec{v} + \vec{l}||}$</span>, with:</p>
<ul>
<li><span class="math-container">$\vec{v}$</span> the unit view vector</li>
<li><span class="math-container">$\vec{l}$</span> the unit light vector (defined from surface-point to light-source).</li>
</ul>
<p>and the specular component is proportional to <span class="math-container">${(\vec{n} \cdot \vec{h})^+}^p$</span> (with <span class="math-container">$p$</span> as Phong exponent)</p>
<h2>Specular light bleeding situation</h2>
<p>Light bleeding occurs in certain configurations when the light vector <span class="math-container">$\vec{l}$</span> is facing away from the surface (i.e. &gt;90° angle from the normal <span class="math-container">$\vec{n}$</span>).</p>
<p>Such a configuration is illustrated by the diagram below:</p>
<p><a href="https://i.sstatic.net/LRsTrQfd.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/LRsTrQfd.png" alt="enter image description here" /></a></p>
<p>Here, we can see that although the light should not contribute to the surface lighting, the computed half-vector is close to the normal, and thus an important specular contribution will be added by the model.</p>
<p>We followed implementation advices from <em>Fundamental of Computer Graphics</em> and <em>Real-Time Rendering</em>, but we missed any mention of this potential problem:</p>
<ul>
<li>Are we misunderstanding how to implement this shading model?</li>
<li>Or is this an inherent issue, and what would be the canonical approach to address it?</li>
</ul>
<p>Edit bonus question:</p>
<ul>
<li>What tools to draw geometric diagrams would you recommend?</li>
</ul>

<lighting><specular>
Blinn-Phong specular light bleeding on triangles facing-away from light: what is the canonical solution?
Ad N
# Blinn-Phong specular light bleeding on triangles facing-away from light: what is the canonical solution?

(Asked by: username_0 on 2024-06-11)

In our implementation of the empirical [Blinn-Phong shading model](https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_reflection_model), we are facing a problem with light-bleeding of the specular component.

The model defines the half-vector $\vec{h} = \frac{\vec{v} + \vec{l}}{||\vec{v} + \vec{l}||}$, with:

* $\vec{v}$ the unit view vector
* $\vec{l}$ the unit light vector (defined from surface-point to light-source).

and the specular component is proportional to ${(\vec{n} \cdot \vec{h})^+}^p$ (with $p$ as Phong exponent)

## Specular light bleeding situation

Light bleeding occurs in certain configurations when the light vector $\vec{l}$ is facing away from the surface (i.e. >90° angle from the normal $\vec{n}$).

Such a configuration is illustrated by the diagram below:

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

Here, we can see that although the light should not contribute to the surface lighting, the computed half-vector is close to the normal, and thus an important specular contribution will be added by the model.

We followed implementation advices from *Fundamental of Computer Graphics* and *Real-Time Rendering*, but we missed any mention of this potential problem:

* Are we misunderstanding how to implement this shading model?
* Or is this an inherent issue, and what would be the canonical approach to address it?

Edit bonus question:

* What tools to draw geometric diagrams would you recommend?

**Tags:** lighting, specular


---

## 1 answers

### Answer by username_1 on 2024-06-11. Score: 2

N dot L will be less then zero and must be computed for the diffuse component and is typically clamped to zero. This can be incorporated into the specular highlight calculation to resolve the issue. What you are describing doesn't come up always in descriptions of Blinn-Phong lighting, I assume, because the writers want to keep things simple. But it is a real issue, I wouldn't go so far as to call it a problem with the lightning model though.

A typical way to resolve it is to add this to the specular compuation (or something like it):

specular = specular \* (float)(ndotl>0.0);

> **Comments:**
> **username_0**: Brilliant, thank you for the practical solution (we were wondering how to do it without branching). (Plus, the bit of confirmation this is an real issue which does not always get addressed by authors makes us feel more sane.)  
> **username_0**: Sadly, this can lead to an abrupt cut-off of the specular contribution between adjacent polygons where the change of `ndotl` sign occurs, which is very noticeable on smooth surfaces. Maybe some sort of windowing function might be used on `ndotl` and the result used as the operand in place of `(float)ndotl` to smooth things out.  

---

