Unityで始めるコンピュータ・グラフィックス (2) シェーダー入門
三角形を好きな色に塗る
デフォルト・エラー・シェーダー
前回はピンクの三角形が表示されました. これは実はエラー時に表示されるシェーダーです. のでこれが出たらシェーダーの処理で何かしらの失敗が起きていることが分かります.
マテリアルの適用
何をするかというとマテリアルを適用すればよいだけです.
Assets以下にMaterialsというフォルダを作ります. Materials以下で右クリックして
Create -> Materials
を作成します. 名前はTriangle.matとでもしておきましょう(.matはあってもなくても良いです). URP(Universal Render Pipeline)の場合Universal Render Pipeline/Litというシェーダーが付いたマテリアルが作成されます.
これをTriangleコンポーネントが追加された空のゲームオブジェクトに追加しましょう.
Playボタンで実行すると以下のように白っぽい色で描画されます.
色を変える
Triangle.matのSurface InputのBase Mapの右横にあるカラーピッカから色を変更してみましょう. 白い部分をクリックするとカラー・ピッカーが別窓で表示されます.
黄色っぽい色に変えると以下のように表面の色が変わります.
Playモードでも変更できます. この場合リアルタイムに色が変わるのが確認できます.
シェーダーで塗りつぶす
今度はカスタム・シェーダーを作って同じように色を付けてみましょう.
HLSLの場合のシェーダーのボイラープレートは以下を参照しましょう.
SingleColorシェーダーを作成して, 二番目のURPUnlitShaderBasicシェーダーの内容をコピペします(あるいは以下のSingleColor.shaderをコピペしても良いです). これをTriangle.matのシェーダーに指定すればいいだけです.
シェーダーは以下のように定義します.
Shader "Custom/SingleColor"
{
Properties
{ }
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
};
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
return OUT;
}
// 今回のキモはこれだけ!
half4 frag(/* Varyingsを渡すこともできる */) : SV_Target
{
half Red = 1;
half Green = 1;
half Blue = 1;
half Alpha = 1;
half4 customColor = half4(Red, Green, Blue, Alpha);
return customColor;
}
ENDHLSL
}
}
}
割とだらだらと長いですがfragという関数の定義だけを見ればいいです.
halfですがこれは16ビット浮動小数点数ということです. half4なのでhalfを四つ組み合わせたものです. Colorという特別な型はないので, half4を使ってRGBAによる色を定義しています.
この場合すべて1に設定しましたので白色になります.
Alphaは1で固定して, RGBの部分を変えると赤とか青, そして緑といった単色で塗りつぶすことがもできます.
Appendix
マテリアルの役割
実際に色を付けるのはシェーダーの役割です. ではマテリアルは何をするのでしょうか. マテリアルはシェーダーのためのパラメータをまとめたものと考えると分かりやすいです. 特にどのように描画するか, つまり見た目を変化させるために使われます.
単純な色から表面の質感, テクスチャといった様々な情報を渡すことができます.
References
URPなどの基本となるSRPの基本的なことが書いてある.
Creating a simple render loop in a custom render pipeline
Discussion