2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

前書き

この記事は、2023のUnityアドカレの12/16の記事です。
今年は、完走賞に挑戦してみたいと思います。Qiita君ぬい欲しい!

はじめに

ゲーム内に存在するオブジェクトの色や質感を調節するためのMaterialです。普段何気なく使っていますが、これは一体全体何者なのでしょうか?特にGraphicsAPIを少しでもかじったことのある方なら尚更謎に感じるかと思います。

image.png

描画するということ

Unityでシーンのオブジェクトを表示するときには隠蔽されていますが、実際にはこのような処理がなされています。

  1. 現在の「状態」が存在する
  2. 頂点シェーダプログラムをセットする
  3. ピクセルシェーダプログラムをセットする
  4. 定数バッファをbスロット(番号指定)にセットする
  5. テクスチャや構造化バッファをtスロットにセットする
  6. テクスチャサンプラーをsストッロにセットする
  7. RenderTargetをセットする
  8. 描画コマンドの発行

(DX12やVulkanでは○○をセットの部分は、RootSignetureやDescriptorTableなどに固めてセットしたりもします)

マテリアルの「マ」の字も出てきません。

マテリアルの役割

マテリアルは、上記の機能の一部がセットで提供しています。

  • 頂点シェーダプログラムの指定
  • ピクセルシェーダプログラムの指定
  • 定数バッファとスロット(名前)の指定
  • テクスチャとスロット(名前)の指定

頂点/ピクセルシェーダプログラムの指定

UnityのShaderは頂点シェーダとピクセルシェーダとそれぞれのバリアントのセットとなっています。

class Shader
{
    // シェーダキーワードで引けるようになっている
    Dictionary<HashSet<string>, ShaderProgram> VertexShaderVariants;
    Dictionary<HashSet<string>, ShaderProgram> PixelShaderVariants;
}

MaterialにはShaderとShaderKeywordsが設定できますが、これにより、個別のシェーダプログラムが解決できるわけです。

定数バッファとスロット(名前)の指定

Materialに保存されている、Float、Vector、Integerは実は定数バッファの個別の中身(フィールド)です。描画時に、これらのMaterialパラメータが定数バッファにPackされてセットされます。

基本指定のないものは$Globalという名のスロットに差し込まれます。これは、Shader側でグローバル変数のように書かれているものです。(バラバラに書かれていても、1つの定数バッファとして受け付けます)

他にも、UnityParMateralという定数バッファを利用できます。これは、Shader側でパラメータ名をUnityParMateralという名前の定数バッファとして書いておくと自動でそこにアサインされます。また、この仕組みはSRPBatcherと呼ばれています。$GlobalにはMaterial由来のパラメータだけでなく、Shader.SetGlobalFloatなどで設定されるグローバル値もPackされるので、ドローコールごとに作成とGPUへの転送が必要です。一方で、UnityParMateralは、マテリアルの値が変更されたときにだけ更新すればよいので、GPU側に置きっぱなしでよいのです。だから速いと。

Material由来ではありませんが、UntityParDrawUnityParFrameという定数バッファもあります。

テクスチャとスロット(名前)の指定

Materialのテクスチャパラメータはそのまま、Shader内で対応するTextureのスロットにセットされます。サンプラーはUnityではTextureとセットみたいな扱いになっているので、TextureをセットするときそのTextureにくっついていたサンプラーを一緒にセットします。

また、StructuredBufferという汎用バッファはMaterialが対応していないのでセットすることはできません。

まとめ

ということで、これがMaterialの正体でした。ザックリいうと、描画コマンドを呼び出すときにセットすべきオオブジェクト群と、Shaderプログラムを解決するための情報がセットで保存されているということですね。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?