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
}
#1 楼
这取决于。在台式机上,如果始终使用相同的参数调用Gaussian
函数,则着色器编译器可能会对其进行优化,因此仅执行一次评估。但是,在移动平台上,编译器执行优化的时间更少,可能会错过它。无论哪种方式,您都可以通过查看生成的程序集来确认。请注意,Unity的ArasPranckevičius编写了GLSL优化程序来解决移动设备上次优编译器的问题:https://github.com / aras-p / glsl-optimizer
话虽如此,关于您的示例代码,我肯定至少要公开统一的
(1.0 / sqrt(2.0 * 3.141592 * deviation))
。#2 楼
着色器编译器很可能会执行公共子表达式合并,并对该函数进行一次计算,并在每次出现在着色器中时重新使用它。您可能会认为,由于
deviationScale
和所有其他args是常量,因此有可能将其完全折叠为常数,并且从不在运行时执行。但这是不正确的,因为sqrt()和exp()不是编译时constexpr函数。编译器无法假定这些数学函数的任何特定实现(以及关联的数值属性),因此整个函数也不会得到优化,并且也不会在线程间重复使用,因为着色语言的编程排除了这种情况。模型。最好的方法是预先计算整个表达式并将其存储在统一的范围内(如果重要的是要使其最佳)。