基礎知識
撮影際、強い光源からの光が多くのレンズで生成されたレンズ群を通過する際に反射や散乱が発生し、他の入射光と同じ方向を保っていない光がフレアを生成することがあります。
もともと技術的な欠陥で画像が歪んでいたのですが、意外と特殊効果が出て立体感が増し、雰囲気を盛り上げることができました。写真の世界では、いくつかの効果を生み出すために特別なフィルターが作られています。同様に、これらの効果はゲームでシミュレートされ、画質を向上させ、雰囲気を高めます。次の章では、レンズフレアによって生成されるいくつかの効果を紹介し、それを実装します。
このセクションでは、Lens Flare効果の一つ、Streak効果を紹介します。
図の中心に、顕著な長いフレアがあります
撮影界にはStreak Filtersという特別なフィルターがあります。ストリークフィルターは、輝点を中心に一連の平行線を放射し、放射効果をもたらします。
(写真のまぶしさによるStreak効果)
ゲーム業界で、Streakはよく見られた効果として、輝点のハイライトを表示して雰囲気を引き立たせます。
(Mass Effect 2のLens Flare Streak効果)
このセクションでは、Dual Blurアルゴリズムのアイデアに基づいた比較的単純な方法を使用してそれを実現します。Dual Blurアルゴリズムでは、ブラー効果は、ダウンサンプリングで画像を縮むことと、アップサンプリングで画像を拡大することを繰り返してぼかし効果を取得します。このように、周囲のピクセルも当ピクセルの色の一部を取得したようになって、色のぼかし効果も実現されています。この考え方に従って、一方向にアップ・ダウンサンプリングを繰り返すことを選択できます。
Unityの実装
アップおよびダウンサンプリング
まず、アップサンプリングとダウンサンプリングのプロセスを実装するには、ハイライトポイントを一方向に伸ばす必要があるため、選択したサンプリングポイントは一方向にのみ配置する必要があります。ダウンサンプリングを実行する場合、サンプリング範囲を適切に拡大すると、縮小された画像の色のピクセル数ができるだけ多くなり、重みの制御により、明るさの減衰がより自然になります。アップサンプリングを実行する場合は、数回デバッグしてサンプリングポイントを適度な範囲内で維持し、色が暗すぎないようにします。
// Downsampler
half4 frag_down(v2f_img i) : SV_Target
{
const float dx = _MainTex_TexelSize.x;
float u0 = i.uv.x - dx * 5;
float u1 = i.uv.x - dx * 3;
float u2 = i.uv.x - dx * 1;
float u3 = i.uv.x + dx * 1;
float u4 = i.uv.x + dx * 3;
float u5 = i.uv.x + dx * 5;
half3 c0 = tex2D(_MainTex, float2(u0, i.uv.y));
half3 c1 = tex2D(_MainTex, float2(u1, i.uv.y));
half3 c2 = tex2D(_MainTex, float2(u2, i.uv.y));
half3 c3 = tex2D(_MainTex, float2(u3, i.uv.y));
half3 c4 = tex2D(_MainTex, float2(u4, i.uv.y));
half3 c5 = tex2D(_MainTex, float2(u5, i.uv.y));
return half4((c0 + c1 * 2 + c2 * 3 + c3 * 3 + c4 * 2 + c5) / 12, 1);
}
// Upsampler
half4 frag_up(v2f_img i) : SV_Target
{
const float dx = _MainTex_TexelSize.x * 3;
float u0 = i.uv.x - dx;
float u1 = i.uv.x;
float u2 = i.uv.x + dx;
half3 c0 = tex2D(_MainTex, float2(u0, i.uv.y)) / 4;
half3 c1 = tex2D(_MainTex, float2(u1, i.uv.y)) / 2;
half3 c2 = tex2D(_MainTex, float2(u2, i.uv.y)) / 4;
half3 c3 = tex2D(_HighTex, i.uv);
return half4(lerp(c3, c0 + c1 + c2, _Stretch), 1);
}
しきい値を適用してハイライトをフィルタリングする
円形の発光点の場合、望ましい効果は、円の中心を通過する水平ビームが最も高い輝度と最も長い長さを持ち、垂直方向に沿って減少することです。Y軸に沿って周囲のピクセルをサンプリングすることを選択します。これにより、エッジピクセルがブレンドによってこぼれる明るさが少なくなります。
half4 frag_prefilter(v2f_img i) : SV_Target
{
const float dy = _MainTex_TexelSize.y;
half3 c0 = tex2D(_MainTex, float2(i.uv.x, i.uv.y - dy));
half3 c1 = tex2D(_MainTex, float2(i.uv.x, i.uv.y + dy));
half3 c = (c0 + c1 ) / 2;
c = max(0, c - _Threshold);
return half4(c, 1);
}
重畳
同様のアイデアを使用して複数のピクセルをサンプリングし、それらを混合してピクセルの色を取得すると、遷移がスムーズになります。
half4 frag_composite(v2f_img i) : SV_Target
{
float dx = _MainTex_TexelSize.x * 1.5;
float u0 = i.uv.x - dx;
float u1 = i.uv.x;
float u2 = i.uv.x + dx;
half3 c0 = tex2D(_MainTex, float2(u0, i.uv.y)) / 4;
half3 c1 = tex2D(_MainTex, float2(u1, i.uv.y)) / 2;
half3 c2 = tex2D(_MainTex, float2(u2, i.uv.y)) / 4;
half3 c3 = tex2D(_HighTex, i.uv);
half3 cf = (c0 + c1 + c2) * _Color * _Intensity * 10;
return half4(cf + c3, 1);
}
自己照明球を使用し、鏡面反射光を適用して、効果を取得します。
平行光の強度を上げて、効果を得ます。
興味のある方は参考してください:
HDRPバージョンのStreak効果(https://github.com/CyberDeck/Unity-HDRP-LensFlares)
(このプロジェクトの効果)
URPバージョンのStreak効果(https://github.com/ColinLeung-NiloCat/UnityURP-BillboardLensFlareShader)
(このプロジェクトの効果)
まとめ
Streak効果の実現から、画像ぼかしアルゴリズムのアイデアの美しさを徐々に理解することができます。色をぼかし、自然な遷移を形成します。 いくつかのトリックと相まって、多くの効果を達成することができます。
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析と最適化ソリューション及びコンサルティングサービスを提供している会社でございます。
今なら、UWA GOTローカルツールが15日間に無償試用できます!!
よければ、ぜひ!
UWA公式サイト:https://jp.uwa4d.com
UWA GOT OnlineレポートDemo:https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ:https://blog.jp.uwa4d.com