UE4,5 プロジェクトファイル内の外部シェーダーファイル(usf, ush, hlsl)をインクルードする為の設定。

# はじめに
MaterialやらNiagaraなどでカスタムシェーダーを書くときに下記のような小さな小窓にコードを書くのは大変辛いので、プロジェクト内のディレクトリに置いたファイルを参照できるように設定します。IDEも使えるようになるので作業効率が格段に上がります。
今回はプラグインを使った方法と使わない方法の2種類をご紹介します。
（今回の方法はMaterialのみの対応です。~~Niagaraは調査中~~ **←解決。最後に記述**）
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/95f49319-0de4-2eed-8320-78bce5e938a8.png">

# Pluginを使った簡単な方法
## 1. Pluginをインストールする。
[HLSL Material](https://www.unrealengine.com/marketplace/ja/product/hlsl-material)

## 2. インストールするとMaterialのメニューに`HLSL Material Function Library`という項目が追加されるのでそれを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/ac288ed1-a46a-d95a-776c-35575b6137aa.png)

## 3. 作成されたアセットを開いて、FileでHLSLファイルを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/9bcf2d65-95f2-146a-3f9d-0624e664f118.png)

## 4. 選択したHLSLファイルにてファンクションを作成。
```c++:sample.hlsl
void UVTestFunction(out float2 Tile, float2 UV)
{
	Tile =  floor(UV.xy * 5) / 5;  
}
```
:::note info
ファンクションは必ずVoid型。
ファンクション名がノード名に。
ファンクションの引数が、ノードの入力ピンに。上記の例だと`UV`
ファンクションの引数(out)が、ノードの出力ピンに。上記の例だと`Tile`
:::

## 5. 作成したファンクションを使う
適当なマテリアルでファンクションのノードを使う。ノード名はファンクション名。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/f10aced9-9a12-ee1f-6a7e-d59a60356728.png)

## 6. 備考
+ 標準でライブアップデートがオンになっています。
+ `アセット名+_GeneratedFunctions`というフォルダが自動生成されその中にHLSLファンクションに対応したマテリアルファンクションが作成されますが、変更してはいけません。（ファンクション名を変更するたびに生成されるので必要ないもの削除はOK）
+ アセットの編集UIでも作成したファンクションを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/2b06a05f-0f97-865d-f5b0-1f0a96f93ae0.png)


***

# 普通の方法
## 0. プロジェクトをC++のプロジェクトにする。
既存のプロジェクトは`Tools > New C++ Class`で適当なクラスを作成してC++のプロジェクトにする。（そのクラスはこの目的では使いません）

## 1. プロジェクトフォルダの直下に *Shaders* というフォルダを作成。
そのフォルダにシェーダーのファイルを入れます。

:::note warn
注意
拡張子は`usf`または`ush`
:::

## 2. "プロジェクト名".Build.csに`RenderCore`への依存関係を追加。
```diff_cpp:ProjectName.Build.cs
- PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore"});
+ PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" , "RenderCore"});
```

## 3. プロジェクトの開始ファンクションを追加する
方法は下記参照。

https://qiita.com/takaf51/items/dacee69820c6333afacf

## 4. `void StartupModule()`に下記を追加
```c++:ProjectName.cpp
{
	FString ShaderDir = FPaths::Combine(FPaths::ProjectDir(), "Shaders");
	AddShaderSourceDirectoryMapping("/Project", ShaderDir);
}
```

## 5. ビルドしてエディタを再起動
#$ 6. Shadersフォルダに保存したシェーダーファイルを利用する。
`Custom`ノードの`Code`に`#include "/Project/シェーダーファイル名"`で外部ファイルを読み込みます。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/315a571a-755b-f70b-2a4f-1c3c054de336.png" />

:::note alert 

`"/Project/シェーダーファイル名"`部分の`Project`自分のプロジェクト名に変更しないように！
`Project`のままで。
:::

### Niagara
`Custom Hlsl`ノードのプロパティで参照ファイルパスを設定可能。ただし、**5.1以上**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/97d14488-5d56-be40-296b-e7017d47a150.png)

:::note info
**`Custom Hlsl`ノード の追加方法**
`Scratch Pad Module`を追加
ノードグラフに`Custom Hlsl`ノードを追加
:::

## 参考Youtube（英語）
[Writing HLSL Code OUTSIDE The Custom Node in UE4](https://www.youtube.com/watch?v=V3BVsYV7ge0&t=242s)