UE4.14.0 Forward Shadingのエンジン改造でセルシェードやってみた
-
Upload
com044 -
Category
Engineering
-
view
790 -
download
1
Transcript of UE4.14.0 Forward Shadingのエンジン改造でセルシェードやってみた
UE4.14.0(Preview)でForward Shadingを触ってみた
正式版!
自己紹介
● Twitter: com04● ゲームプログラマー● 趣味UE4歴: 2年ちょい● お金貰ってニート中(有給消化)● スライドは後で公開します
やってみた
● 4.14でForward Shadingが正式採用されたので試してみた
– (というのを書いてたら、Epic Games Japanの岡田さんがForward Shading+VRのスライドを書かれました)
● UE4.14で広がるVRの可能性http://www.slideshare.net/EpicGamesJapan/ue414vr
Forward Shadingの有効化
● 「プロジェクト設定」ウィンドウ→「エンジン」→「Rendering」→「Forward Shading」チェックボックスをONに
● 再起動を促されるので、エディターを再起動。
有効になったかチェック
● ビューポートの左上にある項目で「バッファを可視化」→「概要」にする
有効になったかチェック
● Deferred ShadingGバッファが確認できる
● Forward ShadingGバッファが見れない
有効になった!
● これだけ!簡単!
で?
● ぼくは何がやりたい?
やりたい!
● Forward Shading出来るのなら、セルシェード(セルルック)の実装いい感じに出来るんじゃ?
その前に
● セルシェード(セルルック)に関しては、おぎまふさん( @ogimafu )が詳しいです。つよい。いつか倒したい
– 【UE4】セルっぽいルックを頑張ってみる その1(概要) - 開発日誌http://ogimafu.blogspot.jp/2015/03/ue4.html
– 【第3回UE4札幌Meetup!!!】 UE4で実装するセル表現http://www.slideshare.net/TomohiroOgiwara/ue4meetup-63696087
マテリアル出力追加したい
● マテリアル出力のパラメーターを追加してシェーディング時に使用したい場合、
– Deferred ShadingだとGバッファを拡張してシェーディング情報を保存する枠を確保しないといけない
– Forward ShadingだとGバッファが無く、すぐにシェーディングされるのでそのままの流れで使える!Gバッファ追加しなくていい!
そもそものレンダリングフロー
● Deferred Shading– メッシュの描画命令→
Gバッファにシェーディングに必要な情報をレンダリングして保存→(ほぼ)全部のメッシュの描画命令が出た後にGバッファの情報を使用してスクリーンベースでシェーディング(陰影付)
● Forward Shading– メッシュの描画命令→
そのままシェーディング
詳しく喋ると1晩かかるのでググって!
やってみた!
● マテリアルのBPで影の色を指定出来るように!
やった事
● マテリアルの出力を拡張。セルシェード用のパラメーターを追加。– マテリアル単位で影色の指定出来るように。
● セルシェード用のパラメーターを、シェーダーのシェーディング計算部分に流すように←ココ!
● シェーダーをいい感じに弄る
エンジン改造
● UE 4.14.0のエンジンのソースコード落としてきて環境を整える– [UE4] エンジンのソースコード取得とビルド手順のまとめ
UE4.6改訂版 – historiahttp://historia.co.jp/archives/1327
– エンジン改造 - UE4 Document@com04http://com04.sakura.ne.jp/unreal/wiki/index.php?%A5%A8%A5%F3%A5%B8%A5%F3%B2%FE%C2%A4
事前情報:エンジンコードでのフラグ
● ソースコードでForward ShadingがONかどうか取得
● シェーダーコードでForward Shading時のdefine
● シェーダーコードで、Forward Shadingの時、Gバッファがdisableになってる
static IConsoleVariable* CVarForwardShading = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ForwardShading"));const bool bForwardShading = CVarForwardShading ? (CVarForwardShading->GetInt() != 0) : false;
#define FORWARD_SHADING
#define USES_GBUFFER // これがdisableになってる
事前情報:シェーダーの流れ
● Forward Shading時のシェーダーの流れ● FPixelShaderInOut_MainPS(BasePassPixelShader.usf)
– GetForwardDirectLighting(ForwardLightingCommon.usf)● GetDynamicLighting(DeferredLightingCommon.usf)
– SurfaceShading(ShadingModels.usf)
● シェーダーコードは”UnrealEngine/Engine/Shaders”あたり● ライティング計算はDeferredと同じ物を使ってる。
マテリアル出力に追加~シェーダーで取得
● マテリアル出力に追加~シェーダー内でその値取得まで● この場で喋ってたら眠くなりそうなので纏めておいた
– UE4でマテリアル出力にピンを追加(UE4.14.0)http://qiita.com/com04/items/6dc75c647ce97ba72ba4
● 変更箇所多いけど無心で書き加えていくだけ。
シェーダー内での受け渡し枠
● Engine/Shaders/DeferredShadingCommon.usf– シェーダー内のパラメーター渡し用にFGBufferDataに変数追加
– 初期化しないとエラーが出るので、DecodeGBufferDataに追加して対処。
// 583行目辺り#if FORWARD_SHADING
GBuffer.ShadowColor = float3(0,0,0);#endif
// 350行目辺りfloat StoredSpecular;
#if FORWARD_SHADING // ここからfloat3 ShadowColor;
#endif // ここまで
シェーダー内での受け渡し
● Engine/Shaders/BasePassPixelShader.usf– FGBufferData::ShadowColorに、マテリアルから渡されて
きたパラメーターを突っ込む// 671行目辺り
GBuffer.Depth = MaterialParameters.ScreenPosition.w;#if FORWARD_SHADING // ここから
GBuffer.ShadowColor = GetMaterialShadowColor(PixelMaterialInputs);#endif // ここまで
影色の適用
● 色計算部分。LightAccumulator_Add関数を丸々コピー&ペーストでLightAccumulator_AddMeetupを作成。(LightAccumulator.usf)– 引数にShadowColorを追加
– カラー計算をShadowColorとTotalLightで補間するように
void LightAccumulator_AddMeetup(inout FLightAccumulator In,float3 TotalLight, float3 ShadowColor, float3 ScatterableLight,float3 CommonMultiplier,const bool bNeedsSeparateSubsurfaceLightAccumulation)
// In.TotalLight += TotalLight * CommonMultiplier;In.TotalLight += lerp(ShadowColor, TotalLight, CommonMultiplier);
影色の適用
● 呼び出し元を差し替えるGetDynamicLighting(DeferredLightingCommon.usf)// accumulate surface{ float3 SurfaceLighting = SurfaceShading(GBuffer, LobeRoughness, LobeEnergy, L, V, N, Random);#if FORWARD_SHADING float light = ((NoL * SurfaceAttenuation) > 0.5f) ? 1.0f : 0.0f; // とりあえず2値化 LightAccumulator_AddMeetup(LightAccumulator, SurfaceLighting, GBuffer.ShadowColor*(1.0/PI), (1.0/PI), light, bNeedsSeparateSubsurfaceLightAccumulation);#else LightAccumulator_Add(LightAccumulator, SurfaceLighting, (1.0/PI), LightColor * (NoL * SurfaceAttenuation), bNeedsSeparateSubsurfaceLightAccumulation);#endif}
Indirect Lightを消す
● エディター上のPostProcessのSettings
– 「Global Illumination」-「Indirect Lighting Intensity」を0.0に
● Indirectが有効だと周囲の色味でシェーディングされるのでセルルックっぽくなくなる。左が有効、右が無効。
できた!
● これだけ!● Gバッファーとか何にも弄らなくていい!● 多分ぼくが見たセルシェードの中で一番扱いやすいかも。● 今回弄ってないけど、やるべき項目
– スペキュラも段階付けるとかしないと。● Engine\Shaders\ShadingModels.usf
– StandardShading辺りのハズ…– ドロップシャドウ周り
● 頑張ればライティング値からテクスチャルックアップの陰影付も出来るかも。
以上です!
● セルルックとか特殊なシェーディング楽しいよ!● エンジン改造楽しいよ!(沼