Edited at

LumberyardのShaderを覗いてみた

More than 1 year has passed since last update.


LumberyardのShaderシステムを調べてみようと、ざっくりとShaderコードを読んでみました。


前置き

 Lumberyardに関してはほとんどまだ何も作業した事が無く、知識も皆無に等しいのですが、素人が参加できるチャンスは今しかないかと思ったので、アドカレに参加してみました。

 初心者丸出しですが、少しでも賑やかしになれば幸いです。色々間違った事を書いているかもしれませんが、その辺はご容赦ください。


LumberyardのShaderシステム

 マニュアルをざっと斜め読みしたところ、LumberyardではUE4の様なノード形式のマテリアルエディタは存在しないみたいで、ユーザーが手軽に独自のマテリアルを組めるわけではなさそうです。

 とは言え、かなりの種類のShader Typeが用意されているので一般的なPBRな画作りをするには十分すぎる機能が揃っているようです。


Shaderコードを覗く

 Lumberyardで使用されるShaderコードは以下のフォルダに配置されているようです。

C:/Amazon/Lumberyard/(Version)/dev/Engine/Shaders/

 このフォルダにShaders.slnというVisualStudioのソリューションファイルがあるので、これをVisual Studioで読み込むことで、IDEでファイルを扱うこともできます。

 拡張子.extのファイルはマテリアルエディタで選択するShaderのプロパティを定義したファイルで、HWScripts/CryFXにShaderのソースコードが格納されています。LumberyardのベースになったCryEngineの名前が残ってるんですね。

 ファイルの中身を見ていくとCommon.cfiに共通の処理が詰め込まれています。これを一通り見るとどんなレンダリングをしてるかがざっと把握できそうです。

 AAA級のゲームエンジンのShaderのキモを誰でも見られる時代になったのは凄いことだと思います。けっこう秘伝のタレ的なものもあるものなので、勉強になります。

#define PI 3.1415

割りと大雑把なPI定義。3.1416の方が良くね?とかどうでも良いツッコミ

DecodeGBuffer/EncodeGBuffer関数を見ると、GBufferはABCの3枚を使用している。

ライティングモデルによって若干の違いはあるみたいですが、

A.xyzにNormal、A.wにlighting modelのフラグなど

B.xyzにalbedo、B.wにocclusion

C.xにSmoothness,C.yzwにReflectance、UE4で言うRoughnessとSpecular/Metallicに相当します。

ざっくり言うとAは法線、Bはカラー、Cは質感情報が格納されるといった感じです。

まだ詳しくは見られていませんが、PBRライティングは、Shader内ではSmoothness=表面の滑らかさ、Reflectance=表面の反射率で計算されているようです。

ライティングモデルはGBufferAのwを2bit使用していて、

#define LIGHTINGMODEL_STANDARD 0

#define LIGHTINGMODEL_TRANSMITTANCE 1

#define LIGHTINGMODEL_POM_SS 2

標準、透過、表面化散乱の3種類のモデルが使用できるみたいです。

Lumberyardではカラーを格納する際にはカラー値の平方根を格納して、取り出すときに2乗して戻しています。暗い部分の精度を高くする工夫でしょう。

GBufferに情報を詰め込むときには色々工夫をするのですが、よくやるのは8bitのチャンネルにbit単位で情報を詰め込むやり方です。とはいえ、Shaderで読み書きするときには浮動小数点で0~1の値です。これを0~255の整数値にしてbit演算して戻すといった面倒くさくてわかりにくい処理を実装する必要があるのですが、この辺のコードなんかもとても勉強になります。

GetLuminanceでRGBの要素に掛ける係数が、0.2126, 0.7152, 0.0722。よく0.299, 0.587, 0.114を使ってるのを見かけますがNTSCの輝度計算値なので、sRGBモニターの場合は前者を使うのが良いみたいです。僕も最近まで後者を使ってました。

RGBMのEncode/Decodeなんかもありますが、HDR警察怖いので特に言及しませんw

Deferred Lightingなので、ベースパスでまずGBufferに法線、カラー、質感の情報を書き込み、その後のライティングパスでGBuffer情報を使ってライティングをするわけです。

Reflectanceの求め方や、Specular Colorをどう処理してるかなど、まだまだわからない部分が多いですが、おいおい調べて行きたいと思います。CryEngineのドキュメントとか見ると書いて有りそうな気はしますが。


まとめ

 LumberyardのShaderコードのごく一部から上っ面だけ撫でてみましたがいかがでしょうか。画像もない記事で興味のない人には全くおもしろくない内容だったかもしれません。

 できればカスタムのShaderを組み込むやり方を調べたり、ポストプロセスについても調べて行きたいと思っています。