天天看点

unity-shader-GPU-Instancing

title: unity-shader-GPU-Instancing

categories: Unity3d-Shader

tags: [unity, shader, 性能, 渲染管线]

date: 2019-05-28 19:14:20

comments: false

unity-shader-GPU-Instancing

前篇

  • 官方资料
    • GPU instancing - https://docs.unity3d.com/Manual/GPUInstancing.html
  • U3D优化批处理-GPU Instancing了解一下 - https://zhuanlan.zhihu.com/p/34499251
  • Unity中基于Gpu Instance进行大量物体渲染的实现与分析(一) - https://blog.csdn.net/leonwei/article/details/73274808

提示

合批优先级

翻译自官网: https://docs.unity3d.com/Manual/GPUInstancing.html

在合批的时候, static batching 优先于 instancing. 如果你把 go 标记成 static batching, unity 会成功的进行合批, 会禁止 instancing, 即使它使用了一个 instancing shader. 如果发生这种情况, inspector 窗口会有个 建议你禁止 static batching 的警告信息. 做法是打开 player settings (edit -> project settings -> player), 打开对应平台的 other settings, 展开 rendering, 取消勾选 static batching.

instancing 优先于 dynamic batching. 如果 unity 可以 instance 一个 mesh, 那么它会禁止 dynamic batching 那个 mesh.

合批的优先级是: static batching > instancing > dynamic batching.

编写 instancing shader

  • shader
    Shader "test/GpuInstancing2"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _Color ("Color", Color) = (1, 1, 1, 1)
            _Intensity ("Intensity", float) = 1
        }
        SubShader
        {
            Tags { "RenderType"="Opaque" }
            LOD 100
    
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                // INSTANCE 编译宏
                #pragma multi_compile_instancing
    
                #include "UnityCG.cginc"
    
                struct appdata {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                };
    
                struct v2f {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if you want to access instanced properties in fragment Shader.
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
    
                UNITY_INSTANCING_BUFFER_START(Props) // uniform 变量定义域, Props 参数可以是任意字符串
                UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
                UNITY_DEFINE_INSTANCED_PROP(float, _Intensity)
                UNITY_INSTANCING_BUFFER_END(Props)
    
                v2f vert (appdata v) {
                    v2f o;
                    UNITY_SETUP_INSTANCE_ID(v);
                    UNITY_TRANSFER_INSTANCE_ID(v, o); // necessary only if you want to access instanced properties in the fragment Shader.
                    
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                    return o;
                }
    
                fixed4 frag (v2f i) : SV_Target {
                    UNITY_SETUP_INSTANCE_ID(i); // necessary only if any instanced properties are going to be accessed in the fragment Shader.
    
                    //访问每个 Instance 独有的属性. 这个宏会使用 Instance ID作为索引到 Uniform数组 中去取当前 Instance 对应的数据
                    float4 val = UNITY_ACCESS_INSTANCED_PROP(Props, _Color) * UNITY_ACCESS_INSTANCED_PROP(Props, _Intensity); 
                    fixed4 col = tex2D(_MainTex, i.uv) * val;
                    return col;
                }
                ENDCG
            }
        }
    }
               
  • 效果
    unity-shader-GPU-Instancing

继续阅读