包含此页的版本:
不含此页的版本:
上面的示例仅使用粒子的默认顶点流设置。这包括一个位置、一个法线、一个颜色和一个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中使用的流,并以相同的顺序将它们添加到自定义流数据结构中的变量定义中,以便它们匹配:
第一项(位置)是必填项,因此无法删除它。您可以使用加号和减号按钮自由添加/删除其他条目来自定义您的顶点流数据。
列表中后跟 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 结构体,就像使用任何其他着色器数据一样。
此示例介绍如何修改自定义着色器以与自定义顶点流一起使用,但您可以将完全相同的方法应用于表面着色器:为内置渲染管线编写着色器的简化方法。更多信息
请参阅术语表以实现相同的功能。