妹でもわかるUnrealEngine4

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

ディフュージョンフィルタを作る(3) さらにふんわり加工で

f:id:una_unagi:20171108231123p:plain
ディフュージョンフィルタ3号機

f:id:una_unagi:20171108231131p:plain
元の状態

「さらに改良することで、かなりふんわりさせることに成功した」


/* 初期値。ループの中で増やしていく */
float4 total = SceneTextureLookup(uv, 14, true);
float total_alpha = 1;

/* ループ開始。表示中のピクセルから縦横に調べる */
/* 範囲が広い方が光を綺麗に広げられるけど、その分重くなる */
for(int y_loop = -6; y_loop <= 6; y_loop++){
for(int x_loop = -6; x_loop <= 6; x_loop++){

/* ピクセルの色を取得 */
/* 2を掛けるのは処理を重くせずボカシの範囲を広げるため。数字が大きいと光る範囲が狭い時に違和感大 */
float4 col = SceneTextureLookup(uv + float2(x_loop, y_loop)*invSize*2, 14, true);

/* RGBの数字を元に明るさを算出 */
float light = col.x * 0.3 + col.y * 0.6 + col.z * 0.1;

/* 距離を調べる(ここはもっと高速化できそう) */
float d = distance(float2(0,0),float2(x_loop, y_loop));

/* 距離が遠くなるほど影響力を弱くする */
/* 距離を変換して、中心が1.0で、遠ざかるほど0に近づく数字にする */
float d2 = ((7 - d) / 7);

/* 1は何度かけても1だけど、0.1*0.1だと0.01になる。という理屈で遠ざかるほど数字が急激下がる */
float alpha = light * pow(d2,3);

if ((light > 0.7)&&(d <= 6)){
total += col * alpha;
total_alpha += alpha;
}
}
}

/* 足しに足したRGBを最後に割って、色を混ぜ合わせた状態にしたものを返り値にする */
return total / total_alpha;

「これならだいぶ実用的なはず」

妹「ふんわりっていうか、なんかぼんやりしてるね。机の上の……なんか置いてあるやつとか」

「そのへんは原理的にそうなっちゃうと思う。ディフュージョンフィルタに対する理解が間違ってる可能性もあるけど。あと高速化はほとんど考慮してないから、速度の問題は気になる」

妹「例えばどのへんが?」

ピクセル間の距離をいちいち計算してるのがちょっと。多分二次元配列とかにした方が速い。けどそれをやると中身がわかりにくくなるから」

妹「あ、これはわかりやすい方なんだ」

「めちゃくちゃに最適化した状態よりはたぶん……あとは同じピクセルの明るさを何度も計算してるのも気に入らないけど、これはエンジン改造でもしないと対処がむずかしいのでは」

妹「どのぐらいの明るさからぼかすかっていう基準の問題もありそうな」

「それもパラメータ化して、後から変更できた方が便利そう」