search
LoginSignup
2

More than 1 year has passed since last update.

posted at

updated at

油絵風のフィルターをTouchDesignerで使う

TouchDesignerでシェーダを使ってみたかったので、自分のアウトプット用に理解できたところを書こうと思います。
違うところがあればご指摘いただけると嬉しいです、、

こちらの記事を参考にしました

完成したもの

movieout.1.gif

プログラム

vec2 texelsize = vec2(1.0 / resolution.x,1.0 / resolution.y); 

float n = (_Radius+1) * (_Radius+1);

vec3 m0 = vec3(.0),m1 = vec3(.0),m2 = vec3(.0),m3 = vec3(.0),
     s0 = vec3(.0),s1 = vec3(.0),s2 = vec3(.0),s3 = vec3(.0);

//左下
for(int i=-_Radius;i<=0;++i){
    for(int j=-_Radius;j<=0;++j){
        vec3 col = texture(sTD2DInputs[0],uv + vec2(j,i)*texelsize).rgb;
        m0 += col;
        s0 += col * col;
    }
}

//左上
for(int i=-_Radius;i<=0;++i){
    for(int j=0;j<=_Radius;++j){
        vec3 col = texture(sTD2DInputs[0],uv + vec2(j,i)*texelsize).rgb;
        m1 += col;
        s1 += col * col;
    }
}


//右上
for(int i=0;i<=_Radius;++i){
    for(int j=0;j<=_Radius;++j){
        vec3 col = texture(sTD2DInputs[0],uv + vec2(j,i)*texelsize).rgb;
        m2 += col;
        s2 += col * col;
    }
}

//右下
for(int i=0;i<=_Radius;++i){
    for(int j=-_Radius;j<=0;++j){
        vec3 col = texture(sTD2DInputs[0],uv + vec2(j,i)*texelsize).rgb;
        m3 += col;
        s3 += col * col;
    }
}

float sigma_min2 = 1e+2f;
m0 /= n;
s0 = abs(s0 / n - m0 * m0);

float sigma_2 = s0.r + s0.g + s0.b;
if(sigma_2 < sigma_min2){
    sigma_min2 = sigma_2;
    color = vec4(m0,1.);
}

m1 /= n;
s1 = abs(s1 / n - m1 * m1);
sigma_2 = s1.r + s1.g + s1.b;
if(sigma_2 < sigma_min2){
    sigma_min2 = sigma_2;
    color = vec4(m1,1.);
}

m2 /= n;
s2 = abs(s2 / n - m2 * m2);
sigma_2 = s2.r + s2.g + s2.b;
if(sigma_2 < sigma_min2){
    sigma_min2 = sigma_2;
    color = vec4(m2,1.);
}

m3 /= n;
s3 = abs(s3 / n - m3 * m3);
sigma_2 = s3.r + s3.g + s3.b;
if(sigma_2 < sigma_min2){
    sigma_min2 = sigma_2;
    color = vec4(m3,1.);
}


fragColor = TDOutputSwizzle(color);

油絵風のフィルターを実装するために、「kuwahara filter」という空間フィルタリング処理を行いました。

kuwabara filterとは

下記の記事が参考になりました
https://qiita.com/Cartelet/items/5c1c012c132be3aa9608

簡単に手順を説明すると

①各画素毎の周辺を4つの領域に分ける
②それぞれの領域で分散を求める
③4つの領域の中で最も小さい分散の領域を求める
④その領域の平均値を中心の色に適用する

といった感じですかね、、
上記の手順をそのまま順番に適用させていけば出来たので、他の空間フィルタリングも試してみようと思います!!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2