рдпрджрд┐ рдЖрдк рдбреЙрдЯреНрд╕ рдлреЛрд░рдо рдХреЗ рдЖрд╕рдкрд╛рд╕ рдШреВрдорддреЗ рд╣реИрдВ , рддреЛ рдЖрдк рд╡рд╣рд╛рдВ рдЙрд╕реА рддрд░рд╣ рдХреА рдкреЛрд╕реНрдЯ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ рд▓реЗрдЦрдХ рдиреЗ рдПрдХ рд▓рд╛рдЦ рдПрдирд┐рдореЗрдЯреЗрдб рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓рд┐рдЦрд╛ рдерд╛, рдФрд░ рдЕрднреА рднреА рдХреЗрд╡рд▓ 60fps рдорд┐рд▓рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдбреЙрдЯреНрд╕ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд░реЗрдВрдбрд░ рдмрдирд╛рдпрд╛ , рдЬреЛ рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдЕрдЪреНрдЫрд╛ рд╣реИ , рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдорд┐рд▓рд┐рдпрди рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИред рдореИрдВ рдЙрддреНрд╕реБрдХ рдерд╛редрдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдлреЛрд░реНрдХ рдХрд┐рдпрд╛ рдФрд░ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдПрдХреЗрдбреЗрдорд┐рдпрд╛ рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЙрд╕рдХреЗ рд╕рд╛рде рдереЛрдбрд╝рд╛ рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛, рджреЗрдЦрд╛ рдХрд┐ рдХреИрд╕реЗ рд╡рд╣ рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ, рдПрдХ рд╕реМ, рдлрд┐рд░ рд╣рдЬрд╛рд░реЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рд╡рд╣ рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдмрд┐рд▓реНрдХреБрд▓ рддреИрдпрд╛рд░ рдирд╣реАрдВ рдерд╛ред рдЗрд╕рдореЗрдВ рдХреБрдЫ рдкрд╣рд▓реБрдУрдВ рдХрд╛ рдЕрднрд╛рд╡ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреАрдЫреЗ рд╕реЗ рд╕рд╛рдордиреЗ рддрдХ рдЫрдВрдЯрд╛рдИред рдореИрдВрдиреЗ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╣реИрдХ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ред рдЬрдм рдореИрдВрдиреЗ рдХреЛрдб рдкрдврд╝рд╛, рддреЛ рдореИрдВрдиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдирдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЭреЗ рд╕рд┐рд░реНрдл рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреИрд╕реЗ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдкрд╣рд▓реЗ рд╣реА рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рд╕рдордЭ рдЧрдпрд╛ рдерд╛редрдореВрд▓ рдмрд╛рддреЗрдВ
рдпрджрд┐ рдореИрдВ рдЗрд╕ рдкреНрд░рддрд┐рдкрд╛рджрди рддрдХрдиреАрдХ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рддреЛ рдореБрдЭреЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдПрдХ рдЕрд▓рдЧ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ред рдкреБрд╕реНрддрдХрд╛рд▓рдп ComputeBuffers рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЙрдиреНрд╣реЗрдВ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рд╢реЗрдбреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬреАрдкреАрдпреВ рдореЗрдВ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рди рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рдПрдХ рдирд┐рдпрдорд┐рдд рд╢реЗрдбрд░ рдореЗрдВ рдХреНрдпрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╕реНрдХреНрд░реАрди рдкрд░ рдХреБрдЫ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЙрди рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж shader рдЗрди рд╕рд╛рдордЧреНрд░рд┐рдпреЛрдВ рддрдХ рдкрд╣реБрдБрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЖрдк рд╕реНрдерд┐рддрд┐, рд░реЛрдЯреЗрд╢рди, рд╕реНрдХреЗрд▓, uv-рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ, рд░рдВрдЧ - рдЬреЛ рднреА рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдиреАрдЪреЗ рдЗрд╕ рднрдпрд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рдВрд╢реЛрдзрд┐рдд рдПрдХ shader рд╣реИ: Shader "Instanced/ComputeBufferSprite" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader {
Tags{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
}
Cull Back
Lighting Off
ZWrite On
Blend One OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma exclude_renderers gles
#pragma vertex vert
#pragma fragment frag
#pragma target 4.5
#include "UnityCG.cginc"
sampler2D _MainTex;
StructuredBuffer<float4> transformBuffer;
StructuredBuffer<float4> uvBuffer;
StructuredBuffer<float4> colorsBuffer;
struct v2f{
float4 pos : SV_POSITION;
float2 uv: TEXCOORD0;
fixed4 color : COLOR0;
};
float4x4 rotationZMatrix(float zRotRadians) {
float c = cos(zRotRadians);
float s = sin(zRotRadians);
float4x4 ZMatrix =
float4x4(
c, -s, 0, 0,a
s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
return ZMatrix;
}
v2f vert (appdata_full v, uint instanceID : SV_InstanceID) {
float4 transform = transformBuffer[instanceID];
float4 uv = uvBuffer[instanceID];
v.vertex = mul(v.vertex - float4(0.5, 0.5, 0,0), rotationZMatrix(transform.z));
float3 worldPosition = float3(transform.x, transform.y, -transform.y/10) + (v.vertex.xyz * transform.w);
v2f o;
o.pos = UnityObjectToClipPos(float4(worldPosition, 1.0f));
o.uv = v.texcoord * uv.xy + uv.zw;
o.color = colorsBuffer[instanceID];
return o;
}
fixed4 frag (v2f i) : SV_Target{
fixed4 col = tex2D(_MainTex, i.uv) * i.color;
clip(col.a - 1.0 / 255.0);
col.rgb *= col.a;
return col;
}
ENDCG
}
}
}
рд╡реИрд░рд┐рдПрдмрд▓ рд╡реЗрд░рд┐рдПрдмрд▓ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдордмрдлрд╝рд░, рдпреВрд╡рд╛рдлрд╝рд░ рдФрд░ рдХрд▓рд░реНрд╕рдмрдлрд╝рд░ "рдПрд░реЗрдЬрд╝" рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдХрдореНрдкреНрдпреВрдЯреНрдпреВрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ (рдЕрднреА рдХреЗ рд▓рд┐рдП) рдпрд╣ рд╕рдм рдЪрд╛рд╣рд┐рдПред рдпрд╣рд╛рдБ рдПрдХрд▓ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдореЛрдиреЛрдмреАрд╣реЙрд░ рд▓рд┐рдкрд┐ рд╣реИ:public class ComputeBufferBasic : MonoBehaviour {
[SerializeField]
private Material material;
private Mesh mesh;
private ComputeBuffer transformBuffer;
private ComputeBuffer uvBuffer;
private ComputeBuffer colorBuffer;
private readonly uint[] args = {
6, 1, 0, 0, 0
};
private ComputeBuffer argsBuffer;
private void Awake() {
this.mesh = CreateQuad();
this.transformBuffer = new ComputeBuffer(1, 16);
float scale = 0.2f;
this.transformBuffer.SetData(new float4[]{ new float4(0, 0, 0, scale) });
int matrixBufferId = Shader.PropertyToID("transformBuffer");
this.material.SetBuffer(matrixBufferId, this.transformBuffer);
this.uvBuffer = new ComputeBuffer(1, 16);
this.uvBuffer.SetData(new float4[]{ new float4(0.25f, 0.25f, 0, 0) });
int uvBufferId = Shader.PropertyToID("uvBuffer");
this.material.SetBuffer(uvBufferId, this.uvBuffer);
this.colorBuffer = new ComputeBuffer(1, 16);
this.colorBuffer.SetData(new float4[]{ new float4(1, 1, 1, 1) });
int colorsBufferId = Shader.PropertyToID("colorsBuffer");
this.material.SetBuffer(colorsBufferId, this.colorBuffer);
this.argsBuffer = new ComputeBuffer(1, this.args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
this.argsBuffer.SetData(this.args);
}
private static readonly Bounds BOUNDS = new Bounds(Vector2.zero, Vector3.one);
private void Update() {
Graphics.DrawMeshInstancedIndirect(this.mesh, 0, this.material, BOUNDS, this.argsBuffer);
}
private static Mesh CreateQuad() {
Mesh mesh = new Mesh();
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(0, 0, 0);
vertices[1] = new Vector3(1, 0, 0);
vertices[2] = new Vector3(0, 1, 0);
vertices[3] = new Vector3(1, 1, 0);
mesh.vertices = vertices;
int[] tri = new int[6];
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;
mesh.triangles = tri;
Vector3[] normals = new Vector3[4];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;
mesh.normals = normals;
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(1, 0);
uv[2] = new Vector2(0, 1);
uv[3] = new Vector2(1, 1);
mesh.uv = uv;
return mesh;
}
}
рдЖрдЗрдП рдЗрд╕ рдХреЛрдб рдХреЛ рдХреНрд░рдо рдореЗрдВ рд▓реЗрддреЗ рд╣реИрдВред рд╕рд╛рдордЧреНрд░реА рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдирдИ рд╕рд╛рдордЧреНрд░реА рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдКрдкрд░ рдмрддрд╛рдП рдЧрдП рд╢реЗрдбрд░ рдХреЛ рд╕реЗрдЯ рдХрд░реЗрдВред рдЗрд╕реЗ рдПрдХ рдмрдирд╛рд╡рдЯ / рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВред рдореИрдВ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдЬреЛ рдХрд┐ 4x4 рд╕реНрдкреНрд░рд╛рдЗрдЯ рдЗрдореЛрдЬреА рдЖрдЗрдХрди рд╣реИред
рдпрд╣рд╛рдБ рдореЗрд╖ CreateQuad () рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдИ рдЧрдИ рдЬрд╛рд▓реА рд╣реИред рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдЪрддреБрд░реНрднреБрдЬ рд╣реИ рдЬреЛ рджреЛ рддреНрд░рд┐рдХреЛрдгреЛрдВ рд╕реЗ рдмрдирд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж рддреАрди ComputeBuffer рд╡реИрд░рд┐рдПрдмрд▓ рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдмрд╛рдж рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕рд╛рдордЧреНрд░реА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВрдЧреЗред рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдЙрд╕реА рддрд░рд╣ рдирд╛рдорд┐рдд рдХрд┐рдпрд╛ рдЬреИрд╕реЗ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрдбрдмрдлрд░ рдЪрд░ рдореЗрдВ рдЫрд╛рдпрд╛рджрд╛рд░ред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИредArgs рдФрд░ argsBuffer рд╡реИрд░рд┐рдПрдмрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ Graphics.DrawMeshInstancedIndirect () рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдкреНрд░рд▓реЗрдЦрди рдпрд╣рд╛рдБ рд╣реИ ред рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд╛рдВрдЪ рдпреВрдЗрдВрдЯ рд╡реИрд▓реНрдпреВ рд╡рд╛рд▓реЗ рдмрдлрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рджреЛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИрдВред рдкрд╣рд▓рд╛ рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИ, рдФрд░ рд╣рдорд╛рд░реА рдЪрддреБрд░реНрднреБрдЬ рдХреЗ рд▓рд┐рдП рдпрд╣ 6 рд╣реИред рджреВрд╕рд░рд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЪрддреБрд░реНрднреБрдЬ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд┐рддрдиреА рдмрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдпрд╣ рд╕рд┐рд░реНрдл 1 рд╣реИред рдореИрдВ рдЗрд╕реЗ рдЕрдзрд┐рдХрддрдо рд╢реЗрдпрд░реНрдб рджреНрд╡рд╛рд░рд╛ рдЗрдВрдбреЗрдХреНрд╕ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрдбрдмрдлрд╝рд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдореВрд▓реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдВред рдЙрд╕рдХреЗ рдЬреИрд╕рд╛:for(int i = 0; i < count; ++i) {
CallShaderUsingThisIndexForBuffers(i);
}
рд╕рдЬрдЧ () рд╡рд┐рдзрд┐ рдХреЗрд╡рд▓ рд╕рд╛рдордЧреНрд░реА рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП ComputeBuffers рддреИрдпрд╛рд░ рдХрд░ рд░рд╣реА рд╣реИред рд╣рдо 0.2f рдХреЗ рдкреИрдорд╛рдиреЗ рдХреЗ рд╕рд╛рде рдФрд░ рд░реЛрдЯреЗрд╢рди рдХреЗ рдмрд┐рдирд╛ рдмрд┐рдВрджреБ (0, 0) рдкрд░ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВред рдпреВрд╡реА рдХреЗ рд▓рд┐рдП, рд╣рдо рдирд┐рдЪрд▓реЗ рдмрд╛рдПрдБ рдХреЛрдиреЗ (рдЪреБрдВрдмрди рдЗрдореЛрдЬреА) рдореЗрдВ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдлрд┐рд░ рд╣рдо рд╕рдлреЗрдж рд░рдВрдЧ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рдЖрд░реНрдЧреНрд╕ рд╕рд░рдгреА argsBuffer рдкрд░ рд╕реЗрдЯ рд╣реИредрдЕрдкрдбреЗрдЯ () рдореЗрдВ, рд╣рдо рдмрд╕ Graphics.DrawMeshInstancedIndirect () рдХрд╣рддреЗ рд╣реИрдВред (рдореБрдЭреЗ рдЕрднреА рддрдХ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрдпрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ BOUNDS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреЗрд╡рд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред)рдЕрдВрддрд┐рдо рдЪрд░рдг рдПрдХ рдСрд░реНрдереЛрдЧреЛрдирд▓ рдХреИрдорд░рд╛ рдХреЗ рд╕рд╛рде рдПрдХ рджреГрд╢реНрдп рддреИрдпрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдПрдХ рдФрд░ GameObject рдмрдирд╛рдПрдБ рдФрд░ ComputeBufferBasic рдШрдЯрдХ рдЬреЛрдбрд╝реЗрдВред рдЪрд▓реЛ рдЙрд╕реЗ рджрд┐рдЦрд╛рддреЗ рд╣реБрдП shader рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╛рдордЧреНрд░реА рд╕реЗрдЯ рдХрд░реЗрдВред рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рддреЗ рд╣реИрдВ:рдЕрд░реЗ рд╣рд╛рдВ! ComputeBuffer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛редрдпрджрд┐ рдЖрдк рдПрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдмрд╣реБрдд рдХреБрдЫ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
рдЕрдм рдЬрдм рд╣рдордиреЗ рд╕реАрдЦрд╛ рд╣реИ рдХрд┐ ComputeBuffers рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдХреИрд╕реЗ рд░реЗрдВрдбрд░ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рд╣рдо рдмрд╣реБрдд рдХреБрдЫ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдПрдХ рдФрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмрдирд╛рдИ рдЧрдИ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдорд╛рддреНрд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ рдФрд░ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕реНрдерд┐рддрд┐, рдкреИрдорд╛рдиреЗ, рд░реЛрдЯреЗрд╢рди рдФрд░ рд░рдВрдЧ рдХреЗ рд╕рд╛рде рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:public class ComputeBufferMultipleSprites : MonoBehaviour {
[SerializeField]
private Material material;
[SerializeField]
private float minScale = 0.15f;
[SerializeField]
private float maxScale = 0.2f;
[SerializeField]
private int count;
private Mesh mesh;
private ComputeBuffer transformBuffer;
private ComputeBuffer uvBuffer;
private ComputeBuffer colorBuffer;
private uint[] args;
private ComputeBuffer argsBuffer;
private void Awake() {
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = -1;
this.mesh = CreateQuad();
float4[] transforms = new float4[this.count];
float4[] uvs = new float4[this.count];
float4[] colors = new float4[this.count];
const float maxRotation = Mathf.PI * 2;
for (int i = 0; i < this.count; ++i) {
float x = UnityEngine.Random.Range(-8f, 8f);
float y = UnityEngine.Random.Range(-4.0f, 4.0f);
float rotation = UnityEngine.Random.Range(0, maxRotation);
float scale = UnityEngine.Random.Range(this.minScale, this.maxScale);
transforms[i] = new float4(x, y, rotation, scale);
float u = UnityEngine.Random.Range(0, 4) * 0.25f;
float v = UnityEngine.Random.Range(0, 4) * 0.25f;
uvs[i] = new float4(0.25f, 0.25f, u, v);
float r = UnityEngine.Random.Range(0f, 1.0f);
float g = UnityEngine.Random.Range(0f, 1.0f);
float b = UnityEngine.Random.Range(0f, 1.0f);
colors[i] = new float4(r, g, b, 1.0f);
}
this.transformBuffer = new ComputeBuffer(this.count, 16);
this.transformBuffer.SetData(transforms);
int matrixBufferId = Shader.PropertyToID("transformBuffer");
this.material.SetBuffer(matrixBufferId, this.transformBuffer);
this.uvBuffer = new ComputeBuffer(this.count, 16);
this.uvBuffer.SetData(uvs);
int uvBufferId = Shader.PropertyToID("uvBuffer");
this.material.SetBuffer(uvBufferId, this.uvBuffer);
this.colorBuffer = new ComputeBuffer(this.count, 16);
this.colorBuffer.SetData(colors);
int colorsBufferId = Shader.PropertyToID("colorsBuffer");
this.material.SetBuffer(colorsBufferId, this.colorBuffer);
this.args = new uint[] {
6, (uint)this.count, 0, 0, 0
};
this.argsBuffer = new ComputeBuffer(1, this.args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
this.argsBuffer.SetData(this.args);
}
private static readonly Bounds BOUNDS = new Bounds(Vector2.zero, Vector3.one);
private void Update() {
Graphics.DrawMeshInstancedIndirect(this.mesh, 0, this.material, BOUNDS, this.argsBuffer);
}
private static Mesh CreateQuad() {
}
}
рдПрдХрд▓ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд╣реИрдВред рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдЕрдм рд╣рдо рдХреНрд░рдордмрджреНрдз рдЪрд░ рдЧрдгрдирд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдПрдХреНрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рд╕рд░рдгрд┐рдпреЛрдВ рдХреА рддреИрдпрд╛рд░реА рдХрд░ рд░рд╣реЗ рд╣реИрдВ ред рд╣рдордиреЗ рджреВрд╕рд░реЗ рдирдВрдмрд░ рдХреЛ рднреА рдЖрд░реНрдЧреНрд╕ рдПрд░реЗ рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ, рдЗрд╕реЗ рдЧрд┐рдирдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░реЗрдВ редрдЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдХрд┐рд╕реА рднреА рдорд╛рди рдХреЛ рдЧрд┐рди рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдЙрдиреНрд╣реЗрдВ рд╕рд┐рд░реНрдл рдПрдХ рдбреНрд░реЙ рдХреЙрд▓ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдЧрд╛редрдпрд╣рд╛рдВ 10,000 рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╣реИрдВредрдорд┐рдирд╕реНрдХреЗрд▓ рдФрд░ рдореИрдХреНрд╕рд╕реНрдХреЗрд▓ рдЕрдиреБрдХреНрд░рдорд┐рдд рдЪрд░ рдХреНрдпреЛрдВ рд╣реИрдВ? рдЬрдм рдореИрдВрдиреЗ 600,000 рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛, рддреЛ рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдЧрддрд┐ 60fps рд╕реЗ рдХрдо рд╣реЛ рдЧрдИ рд╣реИред рдпрджрд┐ рд╕реНрд░реЛрдд рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдПрдХ рдорд┐рд▓рд┐рдпрди рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ, рддреЛ рдпрд╣ рдХреЛрдб рд╡рд┐рдлрд▓ рдХреНрдпреЛрдВ рд╣реЛрддрд╛ рд╣реИ?рдпрд╣ 600,000 рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╣реИред рдпрд╣ рдзреАрд░реЗ-рдзреАрд░реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИредрдореИрдВрдиреЗ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдХрд┐ рд╢рд╛рдпрдж рдпрд╣ рд▓рд╛рд▓рдЪ рдХреЗ рдХрд╛рд░рдг рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдорд┐рдиреАрд╕реНрдХреЗрд▓ рдФрд░ рдореИрдХреНрд╕рд╕реЗрд▓ рдХреЛ рдХреНрд░рдордмрджреНрдз рд░реВрдк рд╕реЗ рдорд╛рдкрджрдгреНрдб рдмрдирд╛рдпрд╛ рдФрд░ 0.01 рдФрд░ 0.02 рдЬреИрд╕реА рдЫреЛрдЯреА рд╕рдВрдЦреНрдпрд╛рдПрдБ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреАрдВред рдФрд░ рддрднреА рдореИрдВ 60fps (рд╕рдВрдкрд╛рджрдХ рдХреЗ рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рджреНрд╡рд╛рд░рд╛ рдЬрдЬ) рдкрд░ рдПрдХ рд▓рд╛рдЦ рд╕реНрдкреНрд░рд┐рдЯ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ред рд╢рд╛рдпрдж рдХреЛрдб рдЕрдзрд┐рдХ рд╕рдХреНрд╖рдо рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд▓рд╛рдЦ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд┐рд╕рдХреЛ рд╣реИ? рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдореЗрдВ, рдЗрд╕ рд╕рдВрдЦреНрдпрд╛ рдХреА рдПрдХ рдЪреМрдерд╛рдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдПрдХ рд▓рд╛рдЦ рдЫреЛрдЯреЗ рд╕реНрдкреНрд░рд╛рдЗрдЯредрдкреНрд░реЛрдлрд╛рдЗрд▓рд░
рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдпрд╣ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдХреЛрдб рдЯреЗрд╕реНрдЯ рдмрд┐рд▓реНрдб рдореЗрдВ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред :рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рддреЗрдЬ рд╣реИред Graphics.DrawMeshInstancedIndirect () рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ 0 рдПрдордПрд╕ред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдореИрдВ рдЗрддрдирд╛ рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдБ рдХрд┐ Gfx рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПредрдЗрддрдирд╛ рд╢реАрдШреНрд░ рдирд╣реА
рд╣рд╛рд▓рд╛рдВрдХрд┐ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд╣реИ, рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЧреЗрдо рдореЗрдВ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓рд╛рдкрддрд╛ рдкрд╣рд▓реВ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреА рдЫрдВрдЯрд╛рдИ рд╣реИред рдФрд░ рдпрд╣ рдЕрдзрд┐рдХрд╛рдВрд╢ CPU рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рд▓реЗ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмрдврд╝рддреЗ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде, ComputeBuffers рдХреЛ рд╣рд░ рдлреНрд░реЗрдо рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЕрднреА рдмрд╣реБрдд рдХрд╛рдо рдмрд╛рдХреА рд╣реИред рдореБрдЭреЗ рдЙрдореНрдореАрдж рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рдордХрд╛рдЬреА рдврд╛рдВрдЪреЗ рдореЗрдВ рдПрдХ рдорд┐рд▓рд┐рдпрди рд╣рд╛рд╕рд┐рд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдореИрдВ 2 рдПрдордПрд╕ рд╕реЗ рдХрдо рдореЗрдВ 300,000 рдЬреИрд╕реА рдХреЛрдИ рдЪреАрдЬ рд╣рд╛рд╕рд┐рд▓ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ред рдбреЙрдЯреНрд╕ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдорджрдж рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдЕрдиреНрдп рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╖рдп рд╣реИред