Я использую вычислительный шейдер в единстве для генерации значений плотности для алгоритма марширующего куба, а для некоторых он пропускает вычисления для каждого 17-го значения в буфере и оставляет его равным 0.
Код для установите буфер вычислений:
public ComputeBuffer Generate(float radius,int width,float resolution,float[] planetCentre,float[] pos)
{
int threadGroups = (int)Mathf.Ceil(((width) + 1) / 8);
densityDebug = new float[((width) + 1) * ((width) + 1) * ((width) + 1)];
ComputeBuffer densityBuffer = new ComputeBuffer(((width) + 1) * ((width) + 1) * ((width) + 1), sizeof(float));
int kernelHandle = shader.FindKernel("CSMain");
shader.SetBuffer(kernelHandle, "densityBuffer", densityBuffer);
shader.SetFloat("resolution", resolution);
shader.SetInt("densityWidth", (width) + 1);
shader.SetFloat("radius", radius);
shader.SetFloats("planetCentre", planetCentre);
shader.SetFloats("pos", pos);
shader.Dispatch(kernelHandle, threadGroups, threadGroups, threadGroups);
densityBuffer.GetData(densityDebug);
return densityBuffer;
}
и код шейдера:
RWStructuredBuffer<float> densityBuffer;
int densityWidth;
float radius;
float3 planetCentre;
float3 pos;
float resolution;
int flattenedIndex(int x, int y, int z)
{
return (x * (densityWidth) * (densityWidth)) + (y * (densityWidth)) + z;
}
[numthreads(8,8,8)]
void CSMain (int3 id : SV_DispatchThreadID)
{
if (id.x >= densityWidth || id.y >= densityWidth || id.z >= densityWidth)
{
return;
}
float dSphere = pow(pos.x + (id.x * resolution) - planetCentre.x, 2) + pow(pos.y + (id.y * resolution) - planetCentre.y, 2) + pow(pos.z + (id.z * resolution) - planetCentre.z, 2) - pow(radius, 2);
densityBuffer[flattenedIndex(id.x, id.y, id.z)] = dSphere;
}
Это происходит независимо от значений, но, например, ширина обычно устанавливается равной 16. Поэтому , 3 группы потоков используются. Я совершенно новичок в вычислении шейдеров, поэтому это может быть что-то очень простое.