【Unity】GPU Instancingで、大量の同一オブジェクトを高速描画しよう
ゲームシーンに、沢山のメッシュオブジェクトを配置して、よりリッチな表現にしたい!
でも、トレードオフで、描画速度が遅くなるなぁ。
そんなとき、役立つのが、GPU Instancingという機能。
この機能を使うと、ゲームシーン内にある、大量の同一オブジェクトを、まとめて描画してくれます。
結果、描画速度のパフォーマンスが上がります。
例えば、草木、石、床板、壁などの複製しているオブジェクトに適用することができます。
適用される「同一オブジェクト」の条件とは、同じメッシュMesh、同じマテリアルMaterialであることです。
なお、後述する方法その2で、「同一マテリアルだけれども、色違い」にするということもできます。
方法その1
マテリアルMaterialのインスペクターにある、Enable GPU Instancingをチェックをオンにします。
そして、各々のオブジェクトのマテリアルにセットするだけです。
別々のマテリアルをセットした場合、個々に描画される
同一マテリアルをセットした場合、まとめて描画される
Window > Analysis > Frame Debuggerで上の描画プロセス情報が見れます。
また、スクリプトにてセットする場合は、同一マテリアルを参照したいので、共有マテリアルSharedMaterialの方にセットします。ここがポイント!
NG)GetComponent ().material = マテリアル
OK)GetComponent
方法その2
「同一マテリアルだけれども、色違い」にする場合の方法です。
以下のようなシェーダーファイルを作成します。赤色がGPU Instancing対応するコードです。
Shader "Custom/SurfaceShaderInstanced"
{
Properties
{
//_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
//fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
//fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
このシェーダーを、作成した
以下スクリプトを作成します。この中で、所望の色をセットしてください。
public class SurfaceShaderInstanced : MonoBehaviour { void Start() { MaterialPropertyBlock props = new MaterialPropertyBlock(); props.SetColor("_Color", new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f))); GetComponent<MeshRenderer>().SetPropertyBlock(props); } }
対象のオブジェクトに、スクリプトとマテリアルをセットします。
これで、方法その2はOK!
ゲームシーンで使っているライティングなどの設定によっては、GPU Instancingの適用条件から外れる場合もあります。
詳細は、Unityのマニュアルサイトを参照ください。
GPU Instancingを上手く使って、リッチなゲームシーンを創りましょう!
次のUnity Tips記事の更新をお楽しみに!
ツイート、いいね~よろしく!
Yuuki Tsuji @ Feelin Games - The Game Creator
https://twitter.com/Feelin_Games