Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

構成ごとの Shader 自動生成 #161

Open
1 of 2 tasks
lriki opened this issue Aug 21, 2020 · 0 comments
Open
1 of 2 tasks

構成ごとの Shader 自動生成 #161

lriki opened this issue Aug 21, 2020 · 0 comments
Labels
proposal 実装済みの機能を変更する場合に使用する。

Comments

@lriki
Copy link
Collaborator

lriki commented Aug 21, 2020

Motivation

Instancing 有効、NormalMap 有効、など、構成の組み合わせがかなり増えてきているので、自動的に作りたい。

開発中のタイトル HC4 では背景モデルに対してシェーダを適用したいが、対象は NormalMap 有無など複数の構成を書かなければならず、シェーダ開発が非効率になっている。

Proposal

現状の構成は次の通り。

PS の出力方法 (Phase)

  • Default
  • ShadowCaster -> PS 固定
  • LightDisc -> VS/PS 固定
  • GBufferPrepass -> PS 固定

VS の種類

  • StaticMesh Default
  • StaticMesh Instancing
  • SkinnedMesh Default
  • SkinnedMesh Instancing

Phase が Default のときの PS 種類 (ShadingModel)

  • Default
  • Unlit

PS のオプション

  • NormalMap
  • RoughnessMap

ユーザーカスタマイズを考慮した基本的なシェーダサンプル

方針:VSMain, PSMain は直接書くことにして、オプションの変更はマクロなどで対応する。
Unity のサーフェスシェーダみたいなのを作ることになるとシェーダコンパイラに手を入れる必要があり、かなり重い作業になるため。

struct MyVSOutput
{
	LN_VS_OUTPUT_DATA;	// float3 Pos : SV_POSITION; など
	float4 MyData : TEXCOORD0;
};

struct MyPSInput
{
	LN_PS_INPUT_DATA;
	float4 MyData : TEXCOORD0;
};

MyVSOutput VSMain(LN_VSInput input)
{
	MyVSOutput output;
	LN_ProcessVertex(input, output);	// マクロ。output.Pos などへ代入。スキニングやモーフィングもここで計算する。
	
	output.MyData = /* ユーザー定義データの構築 */;
	
	return output;
}

float4 PSMain(MyPSInput input) : SV_TARGET0
{
	//LN_Surface surface = LN_InitSurface();	// 初期化するだけ
	LN_Surface surface = LN_ProcessSurface(input);	// input.TexUV 等を使って、Albedo など各要素をデフォルト構築する。
	
	surface.Albedo = /* ユーザー定義で模様を付けたりする。デフォルトシェーダでは何もしない。 */;
	
	// surface は Unity の SurfaceShader の Output 相当。
	// LN_ProcessPixel は UE4 の Output ノード相当。
	// LN_ProcessPixel の中で ShadingModel に応じて PBR の計算をしたり、環境光, Fog の適用などが行われる。
	return LN_ProcessPixel(surface);
}

technique Default
{
	pass Pass1
	{
		VertexShader = VSMain;  // VS はほどんと定型になるので、LN_VSDefault とかを用意してもいいかも。
		PixelShader = PSMain;
	}
}

自動生成の方針

  • technique 名が "Default" であるものについてのみ、自動生成を行う。
    • Default 以外はほとんど内部用途なので、がんばって直書きする。
  • 上記構成だけでも、128 個組み合わせができる。実行速度との相談になるが、コンパイルオプション以外の方法で動的に切り替えができそうならそっちを検討する方がよさそう。初期化時間がすごく長くなるので。
    • Instancing 有無は入力頂点の定義を変える必要があるので、コンパイルオプションで。
    • StaticMesh/SkinningMesh は uniform で切り替えられそう。VTF で動かしてるので、そのテクスチャサイズが 0 なら Static、とか if で判断する、でいいかも。
    • ShadingModel はその有無で実行コードがかなり変わる。Unlit なのに PBR 用のコードや uniform が含まれてしまうと、主に C++ 側に初期化時・実行時共に余計なオーバーヘッドが入ってくるので、コンパイルオプションにしたい。
    • NormalMap や RoughnessMap は、青テクスチャや白テクスチャを使うことでデフォルトを表せる。テクスチャレジスタやFetchが増えるが実際に動かしてみたあと、実行速度と相談で。
  • ↑のようにしておくことで、現状の ShadingModel だと組み合わせは 4 パターンで済みそう。

Note

4パターンくらいならまだ手打ちでもなんとかなるので、まずは上記サンプルの形に、ビルトインシェーダを全部直す。

@lriki lriki added the proposal 実装済みの機能を変更する場合に使用する。 label Aug 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal 実装済みの機能を変更する場合に使用する。
Projects
None yet
Development

No branches or pull requests

1 participant