尽管计算缓冲区未按预期工作,但模循环
设置
在我的计算着色器中,我有一个存储大量颜色的 StructuredBuffer
。还有一个 int 变量存储颜色总数 ( _colres
)。从另一个脚本,每帧都会将节点树分派到着色器中。节点数量动态变化。因此,包含节点的点缓冲区的固定大小为 8192,节点数量永远不会超过。
问题
当我现在尝试绘制我存储在点缓冲区中的点时,奇怪的是,从索引 [0] 开始,仅显示每第三种颜色(测试最多 12 种颜色 -> [0],[3] ,[6],[9])。
Result[pointsBuffer[id.x].xy] = colorsBuffer[id.x % _colres];
我尝试过的
我改为使用 fmod()
函数,但得到了相同的结果。通过对索引进行硬编码来单独定位存储的颜色已经有效,所以我的猜测是颜色缓冲区不是问题。也许这与点缓冲区中的所有空白空间有关,但我无法弄清楚。
问题
是否存在我忽略的根本问题? 是否有其他一些简单的方法可以循环遍历在这种情况下工作的颜色缓冲区的索引?
详细信息
系统:
在 MacOS Monterey 12.2.1 上使用 HDRP 的 Unity 版本 2021.2.12f1
计算着色器
#pragma kernel DrawPoints
// texture
shared RWTexture2D<float4> Result;
int _texres;
int _colres;
// buffer
StructuredBuffer<float2> pointsBuffer;
StructuredBuffer<float4> colorsBuffer;
[numthreads(64,1,1)]
void DrawPoints (uint3 id : SV_DispatchThreadID)
{
if ((pointsBuffer[id.x].x * pointsBuffer[id.x].y) > 0) Result[pointsBuffer[id.x].xy] = colorsBuffer[id.x % _colres];
}
C# 设置
public differentialGrowth diffGrowth;
int texResolution = 4096;
int colorAmount = 12;
RenderTexture settingRef;
Material target;
ComputeShader shader;
RenderTexture outputTexture;
ComputeBuffer pointsBuffer;
ComputeBuffer colorsBuffer;
int pointsHandle;
void Start()
{
outputTexture = new RenderTexture(settingRef);
outputTexture.enableRandomWrite = true;
outputTexture.Create();
// INIT
pointsHandle = shader.FindKernel("DrawPoints");
shader.SetInt("_texres", texResolution);
shader.SetInt("_colres", colorAmount);
int stride = (3) * 4; // every component as a float (3) * 4 bytes per float
pointsBuffer = new ComputeBuffer(8192, stride);
stride = (4) * 4;
colorsBuffer = new ComputeBuffer(colorAmount, stride);
shader.SetTexture( pointsHandle, "Result", outputTexture );
target.SetTexture("_MainTex", outputTexture);
Color[] testColors = new Color[colorAmount];
testColors[0] = new Color(1, 0, 0, 0); //red _ yes
testColors[1] = new Color(0, 1, 0, 0); //green
testColors[2] = new Color(0, 0, 1, 0); //blue
testColors[3] = new Color(1, 1, 0, 0); //yellow _yes
testColors[4] = new Color(0, 1, 1, 0); //cyan
testColors[5] = new Color(1, 0, 1, 0); //magenta
testColors[6] = new Color(0.5f, 0, 1, 0); //mix6 _yes
testColors[7] = new Color(1, 0.5f, 1, 0); //mix7
testColors[8] = new Color(0.5f, 0, 1, 0); //mix8
testColors[9] = new Color(0.5f, 0.5f, 1, 0); //mix9 _yes
testColors[10] = new Color(0.5f, 0.5f, 1, 0); //mix10
testColors[11] = new Color(0.5f, 0.5f, 1, 0); //mix11
}
void Update()
{
pointsBuffer.SetData(diffGrowth.nodes.Points);
shader.SetBuffer(pointsHandle, "colorsBuffer", colorsBuffer);
shader.SetBuffer(pointsHandle, "pointsBuffer", pointsBuffer);
shader.Dispatch(pointsHandle, 128, 1, 1);
}
private void OnDestroy()
{
if (pointsBuffer != null) pointsBuffer.Dispose();
if (colorsBuffer != null) colorsBuffer.Dispose();
}
}
The Setup
In my compute-shader I have a StructuredBuffer
that is storing an amount of colors. There is also an int variable storing the amount of colors in total ( _colres
). From another script a node tree is dispatched into the shader every frame. The amount of nodes changes dynamically. Because of that the points buffer containing the nodes is at a fixed size of 8192 that the amount of nodes never exceeds.
The Problem
When I'm now trying to draw the points I am storing in the points buffer, oddly enough only every third color is displayed, starting at index [0] (tested for up to 12 colors -> [0],[3],[6],[9]).
Result[pointsBuffer[id.x].xy] = colorsBuffer[id.x % _colres];
What I tried
I used the fmod()
function instead but was presented with the same result. Individually targeting stored colors by hard-coding the index has worked so my guess would be that the colors buffer is not the problem. Maybe it has something to do with all the empty spaces in the pointsbuffer but I could't figure it out.
The Question(s)
Is there a fundamental problem I am overlooking?
Is there some other simple way to cycle through the indices of my colorsbuffer that works in this scenario?
Detailed Information
System:
Unity Version 2021.2.12f1 using the HDRP on MacOS Monterey 12.2.1
Compute-Shader
#pragma kernel DrawPoints
// texture
shared RWTexture2D<float4> Result;
int _texres;
int _colres;
// buffer
StructuredBuffer<float2> pointsBuffer;
StructuredBuffer<float4> colorsBuffer;
[numthreads(64,1,1)]
void DrawPoints (uint3 id : SV_DispatchThreadID)
{
if ((pointsBuffer[id.x].x * pointsBuffer[id.x].y) > 0) Result[pointsBuffer[id.x].xy] = colorsBuffer[id.x % _colres];
}
C# Setup
public differentialGrowth diffGrowth;
int texResolution = 4096;
int colorAmount = 12;
RenderTexture settingRef;
Material target;
ComputeShader shader;
RenderTexture outputTexture;
ComputeBuffer pointsBuffer;
ComputeBuffer colorsBuffer;
int pointsHandle;
void Start()
{
outputTexture = new RenderTexture(settingRef);
outputTexture.enableRandomWrite = true;
outputTexture.Create();
// INIT
pointsHandle = shader.FindKernel("DrawPoints");
shader.SetInt("_texres", texResolution);
shader.SetInt("_colres", colorAmount);
int stride = (3) * 4; // every component as a float (3) * 4 bytes per float
pointsBuffer = new ComputeBuffer(8192, stride);
stride = (4) * 4;
colorsBuffer = new ComputeBuffer(colorAmount, stride);
shader.SetTexture( pointsHandle, "Result", outputTexture );
target.SetTexture("_MainTex", outputTexture);
Color[] testColors = new Color[colorAmount];
testColors[0] = new Color(1, 0, 0, 0); //red _ yes
testColors[1] = new Color(0, 1, 0, 0); //green
testColors[2] = new Color(0, 0, 1, 0); //blue
testColors[3] = new Color(1, 1, 0, 0); //yellow _yes
testColors[4] = new Color(0, 1, 1, 0); //cyan
testColors[5] = new Color(1, 0, 1, 0); //magenta
testColors[6] = new Color(0.5f, 0, 1, 0); //mix6 _yes
testColors[7] = new Color(1, 0.5f, 1, 0); //mix7
testColors[8] = new Color(0.5f, 0, 1, 0); //mix8
testColors[9] = new Color(0.5f, 0.5f, 1, 0); //mix9 _yes
testColors[10] = new Color(0.5f, 0.5f, 1, 0); //mix10
testColors[11] = new Color(0.5f, 0.5f, 1, 0); //mix11
}
void Update()
{
pointsBuffer.SetData(diffGrowth.nodes.Points);
shader.SetBuffer(pointsHandle, "colorsBuffer", colorsBuffer);
shader.SetBuffer(pointsHandle, "pointsBuffer", pointsBuffer);
shader.Dispatch(pointsHandle, 128, 1, 1);
}
private void OnDestroy()
{
if (pointsBuffer != null) pointsBuffer.Dispose();
if (colorsBuffer != null) colorsBuffer.Dispose();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论