本日はMRGT枠です。
前回に引き続きGraphicsToolsStandardShaderで影を受け取る機能を追加します。
〇MRGTとは?
MixedRealityGraphicsTools(MRGT)はMicrosoftによってオープンソースな形で開発、提供されているMixedRealityデバイス向けのSDKである第三世代のMixedRealityToolkit(MRTK3)で提供されるグラフィック関連のパッケージを指します。
MRTKのコア機能に当たるGraphicsToolsStandardShaderは多くの機能をサポートしていますが、もともとがHoloLensで使用される想定であったことと軽量化のためにほかのオブジェクトとの影の相互関係の機能がありません。
今回は影を受けるようにしていきます。
〇GraphicsToolsLighting.hlsl
MRGTのGraphicsToolsStandardShaderではUnityのシェーダー本体のファイルであるGraphicsToolsStandard.shaderを中心にいくつかの機能ごとに割り振った.hlslファイルをIncludeして構成されています。
代表的なものはGraphicsToolsInput.hlslファイルで、ここでは変数の定義や頂点シェーダー、フラグメントシェーダーで使用される構造体が定義されています。
struct Attributes
{
・・・
UNITY_VERTEX_INPUT_INSTANCE_ID
};
/// <summary>
/// Vertex attributes interpolated across a triangle and sent from the vertex shader to the fragment shader.
/// </summary>
struct Varyings
{
・・・
}
同様にライティングに関する機能もGraphicsToolsLighting.hlslという別のhlslファイルに定義されており、こちらもIncludeして使用しています。
#include "GraphicsToolsCommon.hlsl" #include "GraphicsToolsStandardInput.hlsl" #include "GraphicsToolsLighting.hlsl"
シェーダー内でライトを使用する場合GTMainLightとしてGTGetMainLight()を取得しています。
GTMainLight light = GTGetMainLight();
GTGetMainLight()はGraphicsToolsLighting.hlslで定義されている関数でURPの場合はURPで提供されているLighting.hlsl"のGetMainLight()を継承しています。
ビルドインの場合も一般的なライト情報を取得してGTMainLight構造体にデータを格納しています。
GTMainLight GTGetMainLight()
{
GTMainLight light;
#if defined(_DIRECTIONAL_LIGHT) || defined(_DISTANT_LIGHT)
#if defined(_DISTANT_LIGHT)
light.direction = _DistantLightData[0].xyz;
light.color = _DistantLightData[1].xyz;
#else
#if defined(_URP)
Light directionalLight = GetMainLight();
light.direction = directionalLight.direction;
light.color = directionalLight.color;
#if defined(_RECEIVESHADOW)
light.shadowAttenuation = GetMainLight(shadowCoord).shadowAttenuation;
#endif
#else
light.direction = _WorldSpaceLightPos0.xyz;
light.color = _LightColor0.rgb;
#endif
#endif
#endif
return light;
}
GTMainLight構造体ではdirection(方向)、color(色)を格納しています。
struct GTMainLight
{
half3 direction;
half3 color;
};
RealtimeLighting.hlslで定義されているこのGetMainLightの処理を追うとここでshadowCoordを引数として用いてUnityのリアルタイムシャドウに関する処理も用意されています。
Light GetMainLight(float4 shadowCoord)
{
Light light = GetMainLight();
light.shadowAttenuation = MainLightRealtimeShadow(shadowCoord);
return light;
}
以前行ったほかのオブジェクトの影を受けるシェーダーのチュートリアルでは、GetMainLight(input.shadowCoord)として頂点シェーダーで処理して取得したshadowCoordを引数として渡すことで影の情報をhalf4 light.shadowAttenuationに格納していました。
そのためGraphicsToolsStandardShaderで影を受け取る機能を実装するためには次の手順を踏む必要があります。
頂点シェーダーからフラグメントシェーダーへ渡す構造体(一般的にv2f)にshadowCoordを定義
GTMainLightの構造体に影のデータとしてshadowAttenuationを定義
GraphicsToolsLighting.hlslのGTGetMainLight()に引数としてshadowCoordを定義
GraphicsToolsLighting.hlslのGTGetMainLight()で引数として定義したshadowCoordをRealtimeLighting.hlslで定義されているGetMainLight(shadowCoord)として処理を渡す。
次回から進めていきます。