<p>Let's consider the simplest case, where our texture is 2x2, with alpha values <span class="math-container">$a_{0,0}, a_{1,0}, a_{0,1}, a_{1,1}$</span>. With bilinear filtering, the alpha at <span class="math-container">$uv$</span> coordinate <span class="math-container">$(x,y)$</span> is</p>
<p>lerp(lerp(<span class="math-container">$a_{0,0}$</span>,<span class="math-container">$a_{1,0}$</span>,<span class="math-container">$x$</span>),lerp(<span class="math-container">$a_{0,1}$</span>,<span class="math-container">$a_{1,1}$</span>,<span class="math-container">$x$</span>),<span class="math-container">$y$</span>),</p>
<p>which works out to:</p>
<p>lerp(<span class="math-container">$x a_{1,0} + (1-x) a_{0,0}$</span>, <span class="math-container">$x a_{1,1} + (1-x) a_{0,1}$</span>,<span class="math-container">$y$</span>)</p>
<p>= <span class="math-container">$y(x a_{1,1} + (1-x) a_{0,1}) + (1-y) (x a_{1,0} + (1-x) a_{0,0})$</span>,</p>
<p>Expanding this out, it's a polynomial of the form:</p>
<p><span class="math-container">$b+cx+dy+exy$</span>.</p>
<p>Solving when this is equal to some threshold generally produces hyperbolas, but in degenerate cases can produce lines.</p>
<p>In the image below, the texture specifies the colors at each grid line intersection. Within each grid square we have an example of interpolating a 2x2 texture, and the edge produced by comparing with a threshold is a segment of line or hyperbola.</p>
<p><a href="https://i.sstatic.net/1xTDJ.png" rel="noreferrer"><img src="https://i.sstatic.net/1xTDJ.png" alt="enter image description here" /></a></p>
<p>I had originally assumed the lerp of the lerps would produce a polynomial of the form <span class="math-container">$b+cx+dy$</span>, which solving against a threshold can only produce lines, so it was surprising to see nonlinear curves in the result.</p>

CC BY-SA 4.0
2022-03-12T19:04:30.057Z
2022-03-12T19:04:30.057Z
TomKern
<p>I'm trying to understand what causes the blobby edges when using alpha testing to create transparency with 1-bit alpha channels. The edges appear pixelated, but with rounded corners and diagonal lines. <a href="https://i.sstatic.net/q097z.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/q097z.jpg" alt="blobby edge effect on plant leaf" /></a> [Image from http://wiki.polycount.com/wiki/File:Alphatest_8bit_vs_1bit.jpg]</p>
<p>My theory is that the fragment shader is sampling from the alpha channel using bicubic interpolation then comparing with the alpha threshold. (I would expect straighter edges with bilinear interpolation). Is this correct? Is something special done to prevent overshoot artifacts?</p>

CC BY-SA 4.0
2022-03-11T10:18:20.740Z
I think it's bilinear interpolation. You should check what interpolation you have chosen, the standard choices are nearest, linear, anisotropic. Try switching to nearest: https://www.khronos.org/opengl/wiki/Sampler_Object#Anisotropic_filtering
lightxbulb
CC BY-SA 4.0
2022-03-12T16:53:22.547Z
This isn't for a project of mine, but rather to try to explain a common artifact in video games to my students. I first noticed it in Hitman 3, and switching from anisotropic to trilinear filtering seemed to keep it around. I'll see if I can replicate the issue myself to better understand it.
TomKern
CC BY-SA 4.0
2022-03-12T18:16:04.833Z
I don't think this is an artifact, I believe it is intended, since most would consider the nearest neighbour version a lot more jarring. Trilinear is just linear interpolation between bilinearly interpolated samples on two mip levels, so it definitely will be present there too. As for reproducing it try to resample the above black and white image using bilinear interpolation.
lightxbulb
<interpolation><transparency>
What causes blobby edges with alpha testing?
TomKern
# What causes blobby edges with alpha testing?

(Asked by: username_0 on 2022-03-10)

I'm trying to understand what causes the blobby edges when using alpha testing to create transparency with 1-bit alpha channels. The edges appear pixelated, but with rounded corners and diagonal lines. [![blobby edge effect on plant leaf](https://i.sstatic.net/q097z.jpg)](https://i.sstatic.net/q097z.jpg) [Image from http://wiki.polycount.com/wiki/File:Alphatest\_8bit\_vs\_1bit.jpg]

My theory is that the fragment shader is sampling from the alpha channel using bicubic interpolation then comparing with the alpha threshold. (I would expect straighter edges with bilinear interpolation). Is this correct? Is something special done to prevent overshoot artifacts?

**Tags:** interpolation, transparency

> **Comments:**
> **username_1**: I think it's bilinear interpolation. You should check what interpolation you have chosen, the standard choices are nearest, linear, anisotropic. Try switching to nearest: https://www.khronos.org/opengl/wiki/Sampler_Object#Anisotropic_filtering  
> **username_0**: This isn't for a project of mine, but rather to try to explain a common artifact in video games to my students. I first noticed it in Hitman 3, and switching from anisotropic to trilinear filtering seemed to keep it around. I'll see if I can replicate the issue myself to better understand it.  
> **username_1**: I don't think this is an artifact, I believe it is intended, since most would consider the nearest neighbour version a lot more jarring. Trilinear is just linear interpolation between bilinearly interpolated samples on two mip levels, so it definitely will be present there too. As for reproducing it try to resample the above black and white image using bilinear interpolation.  

---

## 1 answers

### Answer by username_0 on 2022-03-12. Score: 6

Let's consider the simplest case, where our texture is 2x2, with alpha values $a\_{0,0}, a\_{1,0}, a\_{0,1}, a\_{1,1}$. With bilinear filtering, the alpha at $uv$ coordinate $(x,y)$ is

lerp(lerp($a\_{0,0}$,$a\_{1,0}$,$x$),lerp($a\_{0,1}$,$a\_{1,1}$,$x$),$y$),

which works out to:

lerp($x a\_{1,0} + (1-x) a\_{0,0}$, $x a\_{1,1} + (1-x) a\_{0,1}$,$y$)

= $y(x a\_{1,1} + (1-x) a\_{0,1}) + (1-y) (x a\_{1,0} + (1-x) a\_{0,0})$,

Expanding this out, it's a polynomial of the form:

$b+cx+dy+exy$.

Solving when this is equal to some threshold generally produces hyperbolas, but in degenerate cases can produce lines.

In the image below, the texture specifies the colors at each grid line intersection. Within each grid square we have an example of interpolating a 2x2 texture, and the edge produced by comparing with a threshold is a segment of line or hyperbola.

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

I had originally assumed the lerp of the lerps would produce a polynomial of the form $b+cx+dy$, which solving against a threshold can only produce lines, so it was surprising to see nonlinear curves in the result.


---

