Unity3d Unity Compute着色器,通过SV_DispatchThreadID进行数组索引
我在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#源代码: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)。。
#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
}
}
}