Unity3d Unity Compute着色器,通过SV_DispatchThreadID进行数组索引

Unity3d Unity Compute着色器,通过SV_DispatchThreadID进行数组索引,unity3d,hlsl,directx-11,compute-shader,directcompute,Unity3d,Hlsl,Directx 11,Compute Shader,Directcompute,我在GPU上的Compute Shader中有一个数组索引问题,我已经用了好几个星期了 我试图使用SV_DispatchThreadID的x值作为粒子阵列的索引(如web上的一些示例所示) 它正在工作。。。但threadID变量(在主函数中)总是返回0,3,6,9,12,15。。。不是0,1,2,3,4 我在CPU端的调度调用是:调度(64,1,1) 我已经尝试了许多调度配置(32,16,1),(128,1,1),。。。有许多纽琴科的配置(1,1,1),(32,32,1),(16,16,1)。。

我在GPU上的Compute Shader中有一个数组索引问题,我已经用了好几个星期了

我试图使用SV_DispatchThreadID的x值作为粒子阵列的索引(如web上的一些示例所示)

它正在工作。。。但threadID变量(在主函数中)总是返回0,3,6,9,12,15。。。不是0,1,2,3,4

我在CPU端的调度调用是:调度(64,1,1)

我已经尝试了许多调度配置(32,16,1),(128,1,1),。。。有许多纽琴科的配置(1,1,1),(32,32,1),(16,16,1)。。。但总是一样的结果。。。threadID从来都不是井然有序的

如何获取有序索引?:(…总是得到像0,3,6,9这样的索引

有什么建议吗

非常感谢

这是我的CS内核和C#源代码:

#pragma内核CSMain
浮动dt;
浮动时间;
浮点数;
uint最大粒子数=1024;
浮动最大值;
结构粒子
{
整数指数;
浮动3位;
漂浮速度;
浮子大小;
浮动年龄;
浮动标准值;
int型;
};
rW结构缓冲颗粒;
[numthreads(1,1,1)]
void CSMain(uint3 Gid:SV_GroupID,uint3 DTid:SV_DispatchThreadID,uint3 GTid:SV_GroupThreadID,uint GI:SV_GroupIndex)
{
uint索引=DTid.x;
如果(索引<最大粒子数)
{
粒子p=粒子[指数];
p、 position.y=p.index;//只需给出一个y位置来检查索引是否正确
粒子[指数]=p;
}
}
创建ComputeBuffer和其他东西的C代码:

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class SimpleEmitter : MonoBehaviour 
{
   struct Particle 
    {
        public int          index;
        public Vector3      position;
        public Vector3      velocity;
        public float        size;
        public float        age;
        public float        normAge;
        public int          type;
    }

    public ComputeShader computeShader;
    public Material material;
    public int maxParticles = 1000000;
    public float maxAge = 3.0f; 
    public float particleSize = 0.5f;

    private ComputeBuffer particles;
    private int particleSizeOf;

    void Start () 
    {   
        Particle p = new Particle();
        particleSizeOf = Marshal.SizeOf(p);

        Particle[] pInitBuffer = new Particle[maxParticles];

        for (int i = 0; i < maxParticles; i++) 
        {
            p = new Particle();
            p.index = i;
            p.type = 0;            
            p.age = 0;
            p.normAge = 0.1f;
            p.size = particleSize * 0.5f + Random.value * particleSize;                     
            p.velocity = new Vector3(0, 0, 0);

            pInitBuffer[i] = p;
        }

        particles = new ComputeBuffer(maxParticles, particleSizeOf, ComputeBufferType.Default);
        particles.SetData(pInitBuffer);

        computeShader.SetBuffer(0, "particles", particles);
    }

    void Update() 
    {       
        computeShader.SetFloat("dt", Time.deltaTime);
        computeShader.SetFloat("time", Time.time);
        computeShader.SetFloat("pi", Mathf.PI);     
        computeShader.SetInt("maxParticles", maxParticles);                
        computeShader.SetFloat("maxAge", maxAge);

        computeShader.Dispatch(0, 64, 1, 1);            
    }

    public void OnPostRender() 
    {
        material.SetPass(0);
        material.SetFloat("maxAge", maxAge);
        material.SetBuffer("particles", particles);

        Graphics.DrawProcedural(MeshTopology.Triangles, maxParticles, 0);
    }

    void OnDisable() 
    {
        particles.Release();
    }
}
使用UnityEngine;
使用系统集合;
使用System.Runtime.InteropServices;
公共类SimpleMitter:单行为
{
结构粒子
{
公共整数指数;
公共向量3位置;
公共矢量3速度;
公众浮点数;
公众浮动年龄;
公共浮动标准;
公共int类型;
}
公共计算机hader ComputeShader;
公共材料;
公共整数最大粒子数=1000000;
公共浮点数最大值=3.0f;
公共浮点数=0.5f;
私有计算机缓冲粒子;
私人内部参与;
无效开始()
{   
粒子p=新粒子();
particleSizeOf=Marshal.SizeOf(p);
粒子[]pInitBuffer=新粒子[maxParticles];
对于(int i=0;i
这里是顶点、几何体和像素着色器:

Shader "Custom/SimpleRS" 
{
    Properties 
    {
        _ParticleTexture ("Diffuse Tex", 2D) = "white" {}
        _Ramp1Texture ("G_Ramp1", 2D) = "white" {}
    }

    SubShader 
    {
        Pass 
        {
            Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
            Blend OneMinusDstColor One
            Cull Off 
            Lighting Off 
            ZWrite Off 
            Fog { Color (0,0,0,0) }


            CGPROGRAM
            #pragma target 5.0
            #pragma vertex VSMAIN
            #pragma fragment PSMAIN
            #pragma geometry GSMAIN
            #include "UnityCG.cginc" 

            struct Particle 
            {
                int    index;
                float3 position;
                float3 velocity;
                float  size;
                float  age;
                float  normAge;
                int    type;

            };

            StructuredBuffer<Particle>  particles;

            Texture2D                   _ParticleTexture;           
            SamplerState                sampler_ParticleTexture;

            Texture2D                   _Ramp1Texture;
            SamplerState                sampler_Ramp1Texture;

            float maxAge;
            float maxRad;

            struct VS_INPUT
            {
                uint vertexid           : SV_VertexID;
            };
            //--------------------------------------------------------------------------------
            struct GS_INPUT
            {
                float4 position         : SV_POSITION;
                float size              : TEXCOORD0;
                float age               : TEXCOORD1;
                float type              : TEXCOORD2;
            };
            //--------------------------------------------------------------------------------
            struct PS_INPUT
            {
                float4 position         : SV_POSITION;
                float2 texcoords        : TEXCOORD0;
                float size              : TEXCOORD1;
                float age               : TEXCOORD2;
                float type              : TEXCOORD3;
            };
            //--------------------------------------------------------------------------------
            GS_INPUT VSMAIN( in VS_INPUT input )
            {
                GS_INPUT output;

                output.position.xyz = particles[input.vertexid].position;
                output.position.w = 1.0;                
                output.age = particles[input.vertexid].normAge;
                output.size = particles[input.vertexid].size;
                output.type = particles[input.vertexid].type;
                return output;
            }
            //--------------------------------------------------------------------------------
            [maxvertexcount(4)]
            void GSMAIN( point GS_INPUT p[1], inout TriangleStream<PS_INPUT> triStream )
            {           
                float4 pos = mul(UNITY_MATRIX_MVP, p[0].position);

                float halfS = p[0].size * 0.5f;
                float4 offset = mul(UNITY_MATRIX_P, float4(halfS, halfS, 0, 1));

                float4 v[4];
                v[0] = pos + float4(offset.x, offset.y, 0, 1);
                v[1] = pos + float4(offset.x, -offset.y, 0, 1);
                v[2] = pos + float4(-offset.x, offset.y, 0, 1);
                v[3] = pos + float4(-offset.x, -offset.y, 0, 1);

                PS_INPUT pIn;
                pIn.position = v[0];
                pIn.texcoords = float2(1.0f, 0.0f);

                    pIn.size = p[0].size;
                    pIn.age = p[0].age;
                    pIn.type = p[0].type;                       

                triStream.Append(pIn);

                pIn.position =  v[1];
                pIn.texcoords = float2(1.0f, 1.0f);
                triStream.Append(pIn);

                pIn.position =  v[2];
                pIn.texcoords = float2(0.0f, 0.0f);
                triStream.Append(pIn);

                pIn.position =  v[3];
                pIn.texcoords = float2(0.0f, 1.0f);
                triStream.Append(pIn);                  
            }
            //--------------------------------------------------------------------------------
            float4 PSMAIN( in PS_INPUT input ) : COLOR
            {
                float4 color = _ParticleTexture.Sample( sampler_ParticleTexture, input.texcoords );
                float4 tint = _Ramp1Texture.Sample(sampler_Ramp1Texture, float2(min(1.0, input.age),0));
                color *= tint;

                if (input.age == 0) discard;

                return color;
            }
            //--------------------------------------------------------------------------------
            ENDCG
        }
    } 
}
Shader“自定义/简化程序”
{
性质
{
_粒子结构(“漫反射纹理”,2D)=“白色”{}
_Ramp1Texture(“G_Ramp1”,2D)=“白色”{}
}
子阴影
{
通过
{
标记{“队列”=“透明”“忽略投影”=“真实”“渲染类型”=“透明”}
混合一个颜色一个
剔除
熄火
注销
雾{颜色(0,0,0,0)}
CGP程序
#布拉格目标5.0
#布拉格顶点VSMAIN
#pragma片段PSMAIN
#布拉格几何
#包括“UnityCG.cginc”
结构粒子
{
整数指数;
浮动3位;
漂浮速度;
浮子大小;
浮动年龄;
浮动标准值;
int型;
};
结构缓冲颗粒;
纹理2d_颗粒结构;
采样器状态采样器\颗粒结构;
纹理2 d_ramp1纹理;
采样器状态采样器斜坡1结构;
浮动最大值;
浮点最大值;
结构与输入
{
uint vertexid:SV_vertexid;
};
//--------------------------------------------------------------------------------
结构GS_输入
{
浮动4位置:SV_位置;
浮子尺寸:TEXCOORD0;
浮动年龄:TEXCOORD1;
浮子类型:TEXCOORD2;
};
//--------------------------------------------------------------------------------
结构PS_输入
{
浮动4位置:SV_位置;
浮动2 texcoords:TEXCOORD0;
浮子尺寸:TEXCOORD1;
浮动年龄:TEXCOORD2;
浮子类型:TEXCOORD3;
};
Shader "Custom/SimpleRS" 
{
    Properties 
    {
        _ParticleTexture ("Diffuse Tex", 2D) = "white" {}
        _Ramp1Texture ("G_Ramp1", 2D) = "white" {}
    }

    SubShader 
    {
        Pass 
        {
            Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
            Blend OneMinusDstColor One
            Cull Off 
            Lighting Off 
            ZWrite Off 
            Fog { Color (0,0,0,0) }


            CGPROGRAM
            #pragma target 5.0
            #pragma vertex VSMAIN
            #pragma fragment PSMAIN
            #pragma geometry GSMAIN
            #include "UnityCG.cginc" 

            struct Particle 
            {
                int    index;
                float3 position;
                float3 velocity;
                float  size;
                float  age;
                float  normAge;
                int    type;

            };

            StructuredBuffer<Particle>  particles;

            Texture2D                   _ParticleTexture;           
            SamplerState                sampler_ParticleTexture;

            Texture2D                   _Ramp1Texture;
            SamplerState                sampler_Ramp1Texture;

            float maxAge;
            float maxRad;

            struct VS_INPUT
            {
                uint vertexid           : SV_VertexID;
            };
            //--------------------------------------------------------------------------------
            struct GS_INPUT
            {
                float4 position         : SV_POSITION;
                float size              : TEXCOORD0;
                float age               : TEXCOORD1;
                float type              : TEXCOORD2;
            };
            //--------------------------------------------------------------------------------
            struct PS_INPUT
            {
                float4 position         : SV_POSITION;
                float2 texcoords        : TEXCOORD0;
                float size              : TEXCOORD1;
                float age               : TEXCOORD2;
                float type              : TEXCOORD3;
            };
            //--------------------------------------------------------------------------------
            GS_INPUT VSMAIN( in VS_INPUT input )
            {
                GS_INPUT output;

                output.position.xyz = particles[input.vertexid].position;
                output.position.w = 1.0;                
                output.age = particles[input.vertexid].normAge;
                output.size = particles[input.vertexid].size;
                output.type = particles[input.vertexid].type;
                return output;
            }
            //--------------------------------------------------------------------------------
            [maxvertexcount(4)]
            void GSMAIN( point GS_INPUT p[1], inout TriangleStream<PS_INPUT> triStream )
            {           
                float4 pos = mul(UNITY_MATRIX_MVP, p[0].position);

                float halfS = p[0].size * 0.5f;
                float4 offset = mul(UNITY_MATRIX_P, float4(halfS, halfS, 0, 1));

                float4 v[4];
                v[0] = pos + float4(offset.x, offset.y, 0, 1);
                v[1] = pos + float4(offset.x, -offset.y, 0, 1);
                v[2] = pos + float4(-offset.x, offset.y, 0, 1);
                v[3] = pos + float4(-offset.x, -offset.y, 0, 1);

                PS_INPUT pIn;
                pIn.position = v[0];
                pIn.texcoords = float2(1.0f, 0.0f);

                    pIn.size = p[0].size;
                    pIn.age = p[0].age;
                    pIn.type = p[0].type;                       

                triStream.Append(pIn);

                pIn.position =  v[1];
                pIn.texcoords = float2(1.0f, 1.0f);
                triStream.Append(pIn);

                pIn.position =  v[2];
                pIn.texcoords = float2(0.0f, 0.0f);
                triStream.Append(pIn);

                pIn.position =  v[3];
                pIn.texcoords = float2(0.0f, 1.0f);
                triStream.Append(pIn);                  
            }
            //--------------------------------------------------------------------------------
            float4 PSMAIN( in PS_INPUT input ) : COLOR
            {
                float4 color = _ParticleTexture.Sample( sampler_ParticleTexture, input.texcoords );
                float4 tint = _Ramp1Texture.Sample(sampler_Ramp1Texture, float2(min(1.0, input.age),0));
                color *= tint;

                if (input.age == 0) discard;

                return color;
            }
            //--------------------------------------------------------------------------------
            ENDCG
        }
    } 
}