<p>It depends. On a desktop, if the <code>Gaussian</code> function is always called with the same arguments, the shader compiler will probably optimize it so it's evaluated only once. On a mobile platform though, the compiler has less time to do optimizations and might miss it. Either way, you can confirm by looking at the generated assembly.</p>

<p>Note that Aras Pranckevičius of Unity wrote a GLSL optimizer to address the problem of sub-optimal compilers on mobile: <a href="https://github.com/aras-p/glsl-optimizer" rel="nofollow">https://github.com/aras-p/glsl-optimizer</a></p>

<p>That being said, regarding your sample code, I would definitely at least expose <code>(1.0 / sqrt(2.0 * 3.141592 * deviation))</code> as a uniform.</p>

CC BY-SA 3.0
2016-08-07T12:03:08.463Z
2016-08-07T12:03:08.463Z
Julien Guertault
<p>The shader compiler will very likely perform common-subexpression consolidation, and compute that function once, and reuse it each time it appears in the shader. </p>

<p>You might think that, since <code>deviationScale</code> and all the other args are constants, it is possible it gets constant-folded entirely and never executes at runtime at all. But this is incorrect, as sqrt() and exp() are not compile-time constexpr functions.  The compiler cannot assume any specific implementation (and associated numerical properties) of these math functions, and so the entire function will not get optimized out, and it will not get re-used across threads either, as this is precluded by the shading language's programming model.</p>

<p>Your best move is to pre-calculate the entire expression and stash it in a uniform, if it is important that this be optimal.</p>

CC BY-SA 3.0
2016-08-09T23:14:06.840Z
2016-08-09T23:14:06.840Z
GroverManheim
<p>I am running this fragment shader on every pixel on screen. I am trying to make it as efficient as possible. BTW I am running open gl es 2.0.</p>

<p>The code segment below is only a sample from the code, there are about 56 different calls to Gaussian() spread across different functions. I am wondering wether it would be valuable to replace the calls to Gaussian() with there appropriate resulting float value.</p>

<p>I know a lot of times stuff like this is pre-calculated on compilation of the shader, or calculated only once because the gpu realizes it is the same calculation for all fragments.</p>

<p>So would it be worthwhile for me to manually calculate each of these and replace them with their values?</p>

<pre><code>uniform float scalar;
varying float scalart;
float deviationScale = 1.2;
float finalScalar = 1.1;
float Gaussian(float x, float deviation)
{
    return (1.0 / sqrt(2.0 * 3.141592 * deviation)) * exp(-((x * x) / (2.0 * deviation)));
}
vec3 blurS5()
{
    vec3 blr = vec3(0.0);
    blr += texture2D(s_texture, (v_texcoord + vec2(2.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(2.0, 2.0 * deviationScale) ;
    blr += texture2D(s_texture, (v_texcoord + vec2(1.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(1.0, 2.0 * deviationScale) ;

    blr += texture2D(s_texture, (v_texcoord + vec2(0.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(0.0, 2.0 * deviationScale) ;

    blr += texture2D(s_texture, (v_texcoord + vec2(-1.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(-1.0, 2.0 * deviationScale) ;
    blr += texture2D(s_texture, (v_texcoord + vec2(-2.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(-2.0, 2.0 * deviationScale) ;
    return blr;

}

void main()
{
        if (scalar == 2.)
        {
            gl_FragColor = vec4(blurS5(), 1.0);
        }
        else if (scalar == 3.)
        {
            gl_FragColor = vec4(blurS9(), 1.0);
        }
        //There are waaayyy more of these
}
</code></pre>

<shader><fragment-shader><gaussian-blur>
Will the gaussian kernels in this fragment shader be computed for every fragment?
J.Doe
# Will the gaussian kernels in this fragment shader be computed for every fragment?

(Asked by: username_0 on 2016-08-06)

I am running this fragment shader on every pixel on screen. I am trying to make it as efficient as possible. BTW I am running open gl es 2.0.

The code segment below is only a sample from the code, there are about 56 different calls to Gaussian() spread across different functions. I am wondering wether it would be valuable to replace the calls to Gaussian() with there appropriate resulting float value.

I know a lot of times stuff like this is pre-calculated on compilation of the shader, or calculated only once because the gpu realizes it is the same calculation for all fragments.

So would it be worthwhile for me to manually calculate each of these and replace them with their values?

```
uniform float scalar;
varying float scalart;
float deviationScale = 1.2;
float finalScalar = 1.1;
float Gaussian(float x, float deviation)
{
    return (1.0 / sqrt(2.0 * 3.141592 * deviation)) * exp(-((x * x) / (2.0 * deviation)));
}
vec3 blurS5()
{
    vec3 blr = vec3(0.0);
    blr += texture2D(s_texture, (v_texcoord + vec2(2.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(2.0, 2.0 * deviationScale) ;
    blr += texture2D(s_texture, (v_texcoord + vec2(1.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(1.0, 2.0 * deviationScale) ;

    blr += texture2D(s_texture, (v_texcoord + vec2(0.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(0.0, 2.0 * deviationScale) ;

    blr += texture2D(s_texture, (v_texcoord + vec2(-1.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(-1.0, 2.0 * deviationScale) ;
    blr += texture2D(s_texture, (v_texcoord + vec2(-2.0 * scalart, 0.0))).xyz *  finalScalar * Gaussian(-2.0, 2.0 * deviationScale) ;
    return blr;

}

void main()
{
        if (scalar == 2.)
        {
            gl_FragColor = vec4(blurS5(), 1.0);
        }
        else if (scalar == 3.)
        {
            gl_FragColor = vec4(blurS9(), 1.0);
        }
        //There are waaayyy more of these
}

```

**Tags:** shader, fragment-shader, gaussian-blur


---

## 2 answers

### Answer by username_1 on 2016-08-07. Score: 4

It depends. On a desktop, if the `Gaussian` function is always called with the same arguments, the shader compiler will probably optimize it so it's evaluated only once. On a mobile platform though, the compiler has less time to do optimizations and might miss it. Either way, you can confirm by looking at the generated assembly.

Note that Aras Pranckevičius of Unity wrote a GLSL optimizer to address the problem of sub-optimal compilers on mobile: <https://github.com/aras-p/glsl-optimizer>

That being said, regarding your sample code, I would definitely at least expose `(1.0 / sqrt(2.0 * 3.141592 * deviation))` as a uniform.


---

### Answer by username_2 on 2016-08-09. Score: 2

The shader compiler will very likely perform common-subexpression consolidation, and compute that function once, and reuse it each time it appears in the shader.

You might think that, since `deviationScale` and all the other args are constants, it is possible it gets constant-folded entirely and never executes at runtime at all. But this is incorrect, as sqrt() and exp() are not compile-time constexpr functions. The compiler cannot assume any specific implementation (and associated numerical properties) of these math functions, and so the entire function will not get optimized out, and it will not get re-used across threads either, as this is precluded by the shading language's programming model.

Your best move is to pre-calculate the entire expression and stash it in a uniform, if it is important that this be optimal.


---

