Version: 6000.3
语言: 中文
内置渲染管线中的粒子系统GPU实例化示例
内置渲染管线中的 Autodesk 交互式着色器

在内置渲染管线中使用自定义顶点流进行粒子系统GPU实例化示例

上面的示例仅使用粒子的默认顶点流设置。这包括一个位置、一个法线、一个颜色和一个UV。但是,通过使用自定义顶点流,您可以将其他数据发送到着色器在 GPU 上运行的程序。更多信息
请参阅术语表
,例如速度、旋转和尺寸。

在下一个示例中,着色器旨在显示一种特殊效果,该效果使较快的粒子看起来更亮,而较慢的粒子看起来更暗。有一些额外的代码可以使用速度顶点流根据粒子的速度使粒子变亮。此外,由于此着色器假定效果不会使用纹理表动画,因此自定义流结构中省略了它。

这是完整的着色器:

Shader "Instanced/ParticleMeshesCustomStreams"
{
    Properties
    {
        _MainTex("Albedo", 2D) = "white" {}
    }
    SubShader
    {
        Tags{ "RenderType" = "Opaque" }
        LOD 100
        Pass
        {
            HLSLPROGRAM
#pragma exclude_renderers gles
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing
            #pragma instancing_options procedural:vertInstancingSetup
            #define UNITY_PARTICLE_INSTANCE_DATA MyParticleInstanceData
            #define UNITY_PARTICLE_INSTANCE_DATA_NO_ANIM_FRAME
            struct MyParticleInstanceData
            {
                float3x4 transform;
                uint color;
                float speed;
            };
            #include "UnityCG.cginc"
            #include "UnityStandardParticleInstancing.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
            };
            sampler2D _MainTex;
            float4 _MainTex_ST;
            v2f vert(appdata v)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                o.color = v.color;
                o.texcoord = v.texcoord;
                vertInstancingColor(o.color);
                vertInstancingUVs(v.texcoord, o.texcoord);
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
                UNITY_PARTICLE_INSTANCE_DATA data = unity_ParticleInstanceData[unity_InstanceID];
                o.color.rgb += data.speed;
#endif
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }
            fixed4 frag(v2f i) : SV_Target
            {
                half4 albedo = tex2D(_MainTex, i.texcoord);
                return i.color * albedo;
            }
            ENDHLSL
        }
    }
}

着色器包括UnityStandardParticleInstancing.cginc,其中包含未使用自定义顶点流时的默认实例化数据布局。因此,在使用自定义流时,必须覆盖该标头中定义的一些默认值。这些覆盖必须位于包含之前。上面的示例设置了以下自定义覆盖:

首先,有一行告诉 Unity 使用 UNITY_PARTICLE_INSTANCE_DATA 宏对自定义流数据使用名为“MyParticleInstanceData”的自定义结构:

            #define UNITY_PARTICLE_INSTANCE_DATA MyParticleInstanceData

接下来,另一个定义告诉实例化系统,此着色器中不需要动画帧流,因为此示例中的效果不适用于纹理表动画:

            #define UNITY_PARTICLE_INSTANCE_DATA_NO_ANIM_FRAME

第三,声明自定义流数据的结构:

            struct MyParticleInstanceData
            {
                float3x4 transform;
                uint color;
                float speed;
            };

这些覆盖都位于UnityStandardParticleInstancing.cginc,因此着色器不会对这些定义使用自己的默认值。

编写结构时,变量必须与检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
请参阅术语表
粒子系统通过在场景中生成大量小型 2D 图像并为其设置动画来模拟流体实体(如液体、云和火焰)的组件。更多信息
请参阅术语表
renderer 模块。这意味着您必须选择要在渲染器模块UI中使用的流,并以相同的顺序将它们添加到自定义流数据结构中的变量定义中,以便它们匹配:

渲染器模块UI中显示的自定义顶点流,显示一些实例化流和一些非实例化流
渲染器模块UI中显示的自定义顶点流,显示一些实例化流和一些非实例化流

第一项(位置)是必填项,因此无法删除它。您可以使用加号和减号按钮自由添加/删除其他条目来自定义您的顶点流数据。

列表中后跟 INSTANCED 的条目包含实例数据,因此必须将它们包含在粒子实例数据结构中。直接附加到单词 INSTANCED 的数字(例如,INSTANCED0 中的 0 和 INSTANCED1 中的 1)表示变量必须出现在结构中的顺序,在初始“转换”变量之后。尾随字母(.x .xy .xyz 或 .xyzw)指示变量的类型,并映射到着色器代码中的 float、float2、float3 和 float4 变量类型。

可以从粒子实例数据结构中省略列表中显示但后面没有单词 INSTANCED 的任何其他顶点流数据,因为它不是着色器要处理的实例化数据。此数据属于源meshUnity 的主要图形原语。网格体构成了 3D 世界的很大一部分。Unity 支持三角或四边形多边形网格。Nurbs、Nurms、Subdiv 曲面必须转换为多边形。更多信息
请参阅术语表
,例如 UV、法线和切线。

完成示例的最后一步是将速度应用于顶点着色器 渲染模型时在 3D 模型的每个顶点上运行的程序。更多信息
请参阅术语表
:

#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
                UNITY_PARTICLE_INSTANCE_DATA data = unity_ParticleInstanceData[unity_InstanceID];
                o.color.rgb += data.speed;
#endif

必须将所有实例化代码包装在UNITY_PARTICLE_INSTANCING_ENABLED检查中,以便在不使用实例化时可以编译。

此时,如果要将数据传递给片段着色器,可以将数据写入 v2f 结构体,就像使用任何其他着色器数据一样。

此示例介绍如何修改自定义着色器以与自定义顶点流一起使用,但您可以将完全相同的方法应用于表面着色器为内置渲染管线编写着色器的简化方法。更多信息
请参阅术语表
以实现相同的功能。

内置渲染管线中的粒子系统GPU实例化示例
内置渲染管线中的 Autodesk 交互式着色器