<p>I achieved similar result to theirs. First, the target texture for mip generation is base texture size + two margins, each equals 0.125 of base size.</p>

<p>Then during generation of base mip level, there are two cases:</p>

<ul>
<li>inside the square, then just sample original texture,</li>
<li>beyond the central square, then blur the original texture with varying sigma, which depends on distance of current fragCoord from central square borders. While blurring texcoord is clamped to central square borders.</li>
</ul>

<p>How to compute distance: <a href="https://gamedev.stackexchange.com/a/44496/91268">https://gamedev.stackexchange.com/a/44496/91268</a></p>

<p>Gaussian one pass blur I used: <a href="https://www.shadertoy.com/view/XdfGDH" rel="nofollow noreferrer">https://www.shadertoy.com/view/XdfGDH</a></p>

<p>Here are code fragments:</p>

<pre><code>vec2 coord = gl_FragCoord.xy;
vec2 minCorner = margin;
vec2 maxCorner = filteredMipRes - margin;
if(insideBox(coord, minCorner, maxCorner) &gt; 0.5)
{
    fragColor = textureLod(sourceTexture, tc, 0.0).rgb;
}
else
{
    vec2 center = filteredMipRes / 2.0;
    vec2 d = max(abs(coord - center) - baseTextureRes / 2.0, vec2(0.0));
    float dist = sqrt(d.x * d.x + d.y * d.y);
    sigma = max(dist*2.0, 0.5);
    fragColor = blur(sigma);
}
</code></pre>

<p>Rest of mipmaps are just equally gaussian blurred, each based on one level higher mip.</p>

CC BY-SA 4.0
2018-11-17T16:23:10.853Z
2018-11-17T16:38:56.010Z
2018-11-17T16:38:56.010Z
mdkdy
<p>I have ported their WebGL demo in DX shader model 4, but I have not implemented such texture preprocessing. Instead, I use some abstract pattern (like a comuflage) that is twice wider and higher. So, in a reflected area only internal part is rendered if roughness is low, and with a greater roughness, mip-map with lower resolution is taken. That spreads pattern in zone of reflection realistically.
It could be some starting point for your implementation.  </p>

<p>It is possible to make some "texture expansion" like in article, but some special code to do this is needed. This is "special", it modifies Gaussian. </p>

<p>But in many cases, reflected pattern could be very simple, and such expansion can be eailly created by artist and mip chain generated. Again -good for start point.  </p>

CC BY-SA 4.0
2018-07-13T17:24:53.467Z
2018-07-13T17:24:53.467Z
Artem
<p>Actually by referencing to this presentation <a href="https://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf" rel="nofollow noreferrer">https://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf</a>, I use the &quot;Form Vector&quot; to intersect with the texture and it works well. This also helps to get rid of the annoying margin in prefiltering.</p>
<p>However, I'm still stuck on the texture prefiltering section for not knowing how to properly choose prefilter kernel size and select lod at runtime.</p>

CC BY-SA 4.0
2022-07-28T07:15:12.150Z
2022-07-28T07:15:12.150Z
Martin Z He
<p>I'm implementing <a href="https://drive.google.com/file/d/0BzvWIdpUpRx_d09ndGVjNVJzZjA/view" rel="noreferrer">Real-Time Polygonal-Light Shading with Linearly Transformed Cosines</a> from Siggraph 2016.</p>

<p>I'm stuck on the texture prefiltering (section <strong>5.3</strong>).</p>

<p>As I understand they use <code>Gaussian Blur</code> on the texture, but clamp and normalize kernel to fragments that intersect the original texture.</p>

<p>But how do they create the margin? I have tried proper Gaussian with 2D kernel and 2 pass Gaussian but neither seems similar to what is in the paper.</p>

<p>Also how should weight of Gaussian be chosen? </p>

<p>Or maybe I'm totally wrong and it is something more than simple Gaussian?</p>

<texture><pbr><filtering><gaussian-blur>
Texture prefiltering for Linearly Transformed Cosines
Derag
# Texture prefiltering for Linearly Transformed Cosines

(Asked by: username_0 on 2018-04-21)

I'm implementing [Real-Time Polygonal-Light Shading with Linearly Transformed Cosines](https://drive.google.com/file/d/0BzvWIdpUpRx_d09ndGVjNVJzZjA/view) from Siggraph 2016.

I'm stuck on the texture prefiltering (section **5.3**).

As I understand they use `Gaussian Blur` on the texture, but clamp and normalize kernel to fragments that intersect the original texture.

But how do they create the margin? I have tried proper Gaussian with 2D kernel and 2 pass Gaussian but neither seems similar to what is in the paper.

Also how should weight of Gaussian be chosen?

Or maybe I'm totally wrong and it is something more than simple Gaussian?

**Tags:** texture, pbr, filtering, gaussian-blur


---

## 3 answers

### Answer by username_1 on 2018-11-17. Score: 1 | Accepted answer

I achieved similar result to theirs. First, the target texture for mip generation is base texture size + two margins, each equals 0.125 of base size.

Then during generation of base mip level, there are two cases:

* inside the square, then just sample original texture,
* beyond the central square, then blur the original texture with varying sigma, which depends on distance of current fragCoord from central square borders. While blurring texcoord is clamped to central square borders.

How to compute distance: <https://gamedev.stackexchange.com/a/44496/91268>

Gaussian one pass blur I used: <https://www.shadertoy.com/view/XdfGDH>

Here are code fragments:

```
vec2 coord = gl_FragCoord.xy;
vec2 minCorner = margin;
vec2 maxCorner = filteredMipRes - margin;
if(insideBox(coord, minCorner, maxCorner) > 0.5)
{
    fragColor = textureLod(sourceTexture, tc, 0.0).rgb;
}
else
{
    vec2 center = filteredMipRes / 2.0;
    vec2 d = max(abs(coord - center) - baseTextureRes / 2.0, vec2(0.0));
    float dist = sqrt(d.x * d.x + d.y * d.y);
    sigma = max(dist*2.0, 0.5);
    fragColor = blur(sigma);
}

```

Rest of mipmaps are just equally gaussian blurred, each based on one level higher mip.


---

### Answer by username_2 on 2018-07-13. Score: 0

I have ported their WebGL demo in DX shader model 4, but I have not implemented such texture preprocessing. Instead, I use some abstract pattern (like a comuflage) that is twice wider and higher. So, in a reflected area only internal part is rendered if roughness is low, and with a greater roughness, mip-map with lower resolution is taken. That spreads pattern in zone of reflection realistically.
It could be some starting point for your implementation.

It is possible to make some "texture expansion" like in article, but some special code to do this is needed. This is "special", it modifies Gaussian.

But in many cases, reflected pattern could be very simple, and such expansion can be eailly created by artist and mip chain generated. Again -good for start point.


---

### Answer by username_3 on 2022-07-28. Score: 0

Actually by referencing to this presentation <https://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf>, I use the "Form Vector" to intersect with the texture and it works well. This also helps to get rid of the annoying margin in prefiltering.

However, I'm still stuck on the texture prefiltering section for not knowing how to properly choose prefilter kernel size and select lod at runtime.


---

