shader油画效果
代码参考网络上的Unity Shader脚本,将其转换为glsl语法进行GL渲染。glsl代码如下,可以使用shadertoy直接运行:
#iChannel1"file://./dusk.jpg"
#define Res iResolution.xy
void mainImage(out vec4 fragColor,in vec2 fragCoord)
{
// size 和 _Radius是两个超参数,可以提供我们修改。建议_Radius为2到10之间
vec2 size = 2.0/Res;
float _Radius = 2.0;
vec2 uv = fragCoord/Res;
float n = (_Radius + 1.0)*(_Radius + 1.0);
vec3 m0 = vec3(0.0);
vec3 m1 = vec3(0.0);
vec3 s0 = vec3(0.0);
vec3 s1 = vec3(0.0);
vec3 color = vec3(0.0);
for (float j = -_Radius;j <= 0.0;++j) {
for (float k = -_Radius;k <= 0.0; ++k) {
color = texture2D(iChannel1, uv+vec2(k,j)*size).rgb;
m0 += color;
s0 += color * color;
}
}
for (float j = 0.0;j <= _Radius; ++j) {
for (float k = 0.0;k <= _Radius; ++k) {
color = texture2D(iChannel1, uv + vec2(k, j)*size).rgb;
m1 += color;
s1 += color * color;
}
}
vec4 finalColor = vec4(0.0);
float min_sigma2 = 100.0;
m0 /= n;
s0 = abs(s0 / n - m0 * m0);
float sigma2 = s0.r + s0.g + s0.b;
if (sigma2 < min_sigma2)
{
min_sigma2 = sigma2;
finalColor = vec4(m0, 1.0);
}
m1 /= n;
s1 = abs(s1 / n - m1 * m1);
sigma2 = s1.r + s1.g + s1.b;
if (sigma2 < min_sigma2)
{
min_sigma2 = sigma2;
finalColor = vec4(m1, 1.0);
}
fragColor = finalColor;
}
原图如下:
效果图如下: