LoginSignup
12
5

More than 1 year has passed since last update.

GLSLでモデルさんにリアルタイムでかけたエフェクトまとめ

Last updated at Posted at 2022-12-19

1.はじめに

TouchDesignerアドベントカレンダー19日目の記事です。
会社でモデルさんのスチールの撮影現場でリアルタイムでエフェクトかけていくみたいなことをやりました。
制作期間もあまりなくすごい勢いで作りました。
採用されなかったもの含めせっかく作ったのでこの記事でエフェクトの実装部分についてまとめていきます!
ゴリゴリではなくこれからShaderをやってみたい初学者向けな密度かと思います…!
僕もComputeShaderの勉強込みで作りました。
モデルはKIRARIさんという方です。

2.ComputeShader

今回ComputeShaderを使って4種類ほどエフェクトを作りました。
基本は以下の構成です。
TouchDesigner 2022.29850_ C__Users_22033_Desktop_テックラボ_2022_Coloso_effect_chromaley.toe_ 2022_12_19 10_33_21.png
顔と背景を抜いた素材とEdgeTOPで輪郭を抽出した素材、そしてNoiseTOPの三つがGLSLMultiTOPに入力として入ってます。
LevelTOPBlurTOPはエフェクトのかかり具合の調整用です。
これらの素材をこねくり回しバリエーションを作っていきました。
元となる考え方はどのエフェクトも同じです。

コードを書く前にGLSLTOP,GLSLMultiTOPでComputeShaderを扱うためにパラメーターのModeを切り替えます。
ComputeShaderことはじめについては@satoruhigaさんが詳しく記事にまとめてくださっております。
https://qiita.com/satoruhiga/items/13df5e749e0a05850cb3

炎っぽいエフェクト

output.0.gif

今回スチール撮影のため必要なかったのですが、NoiseTOPTransformabsTime.secondsを入れることで気軽にアニメーションさせられます。
実装は以下全文になります。
主に見るところはvec4 effectに入ってくる数式です。
バッファに書き込んだ前フレームをNoiseTOPの濃淡の分X軸を左右に揺らしつつ、Y軸上方に減算しています。

uniform float uTime;
uniform ivec2 uResolution;
uniform float uIsEffect;

layout (local_size_x = 1, local_size_y = 1) in;
void main()
{
	vec2 uv = vec2(float(gl_GlobalInvocationID.x) / uResolution.x, float(gl_GlobalInvocationID.y) / uResolution.y);
    // ノイズテクスチャ
	vec4 noise = texelFetch(sTD2DInputs[2], ivec2(gl_GlobalInvocationID.xy), 0);
    // EdgeTOP入力
	vec4 edge = texelFetch(sTD2DInputs[1], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
    // バッファに書き込んだ前フレームをノイズでズラしていく
	vec4 effect = imageLoad(sTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.x+(noise.r-0.5)*15,gl_GlobalInvocationID.y-noise.r*10));
    // 顔と背景抜いたモデルさん入力
	vec4 color = texelFetch(sTD2DInputs[0], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
    // 最終アウトプットのエフェクト作成
	vec4 outCol = edge*noise.r*2 + (effect*0.9);

	// エフェクトのオンオフ
	if(uIsEffect == 0){
		outCol = color;
	}
	color.a = 1.0;
	imageStore(sTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.xy), TDOutputSwizzle(outCol));
}

ウェーブエフェクト

輪郭をNoiseテクスチャーの濃淡の分X軸をズラしてウェーブしてるように見せています。
以下エフェクトで使用しているsin関数はnoiseに数値を掛けて大きくなった値を-1~1の中に丸める意味で使用しています。

vec4 edge = texelFetch(sTD2DInputs[1], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
vec4 effect = imageLoad(sTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.x+sin(exp(noise.r*5))*noise.r*20,gl_GlobalInvocationID.y));
vec4 color = texelFetch(sTD2DInputs[0], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
vec4 outCol = edge+(effect*0.9);

垂れるエフェクト

輪郭をX軸をウェーブさせながらY軸に加算してエフェクトを垂らしています。

vec4 edge = texelFetch(sTD2DInputs[1], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y-noise.r),0);
vec4 effect = imageLoad(sTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.x-sin(exp(noise.r*5))*uv.s*15,gl_GlobalInvocationID.y+exp(noise.r)*10));
vec4 color = texelFetch(sTD2DInputs[0], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
vec4 outCol = edge+tan(effect*0.9);

格子エフェクト

fract関数で格子にしています。
uvを引き延ばしてから戻すイメージです。
こちらはNoiseテクスチャ不使用。

vec4 edge = texelFetch(sTD2DInputs[1], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
vec4 effect = imageLoad(sTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y+sin(fract(uv.t*40)-0.5)*20));
vec4 color = texelFetch(sTD2DInputs[0], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
vec4 outCol = edge+(effect*0.9);

格子エフェクト応用

サイズ変更と格子をX軸にも適用して斜めにズラしただけです。
これだけでも印象が変わりますね。

vec4 edge = texelFetch(sTD2DInputs[1], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
vec4 effect = imageLoad(sTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.x+sin(fract(uv.t*10)-0.5)*50,gl_GlobalInvocationID.y+sin(fract(uv.t*10)-0.5)*20));
vec4 color = texelFetch(sTD2DInputs[0], ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y),0);
vec4 outCol = edge+(effect*0.9);

3.まとめ

以上簡単ではありますが作ったエフェクトについてまとめました。
今年は細々したものを作っていたため記事何にしようか迷いました。
個人の活動としてはVJをやったりARを開発したり色々挑戦ができて面白い一年でしたが来年は何か一つ大きなテーマを持って開発に取り組もうかなと思います。
ここまで読んでいただきありがとうございました!
皆様良いお年を!

12
5
0

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
  3. You can use dark theme
What you can do with signing up
12
5