1
\$\begingroup\$

I'm pretty new to compute shaders and shader writing in general. I'm trying to write a compute shader for a procedural generation project I'm working on, it's purpose is to blend biomes together. The function works by taking a sample of points around the point it's trying to calculate, and counting up how many points of each biome are in the sample, then it uses this info to blend the biomes at the given point.

The problem is that I have to loop through all of the sample points, and I keep getting the error “forced to unroll loop, but unrolling failed.” I've tried various different things to try and fix such as using the [loop] attribute, in which case I get “can't unroll loops marked with loop attribute”, and I've tried using the [unroll()] attribute to specify the amount of iterations the loop goes through, but I get the unrolling failed message again. I was wondering if anyone could suggest a solution? Here is my code:

#pragma kernel CSMain

struct BlendInputData
{
    int x;
    int z;
    int i;
    int blendRadius;
    int biomeIndexIterat;
    int xSize;
    int zSize;
};

StructuredBuffer<BlendInputData> inputData;
StructuredBuffer<int> biomeList;
RWStructuredBuffer<float4> outputData;

static int blendRadius = inputData[0].blendRadius;
static int biomeIndexIterat = inputData[0].biomeIndexIterat;
static int xSize = inputData[0].xSize;
static int zSize = inputData[0].zSize;


int MeshIndexToBiomeIndex(int meshIndex)
{
    int biomeIndex = meshIndex;
    biomeIndex += (2 * blendRadius * blendRadius) + (blendRadius * xSize);
    biomeIndex += floor((meshIndex / (xSize + 1)) + 1) * 2 * blendRadius;
    return biomeIndex;
};

float Vector2Distance(int xOne, int yOne, int xTwo, int yTwo)
{
    float distance = sqrt(pow(xOne - xTwo, 2) + pow(yOne - yTwo, 2));
    return distance;
};

[numthreads(1, 1, 1)]

void CSMain(uint3 id : SV_DispatchThreadID)
{
    RWStructuredBuffer<float> blendedBiome;
    int x = inputData[id.x].x;
    int z = inputData[id.x].z;
    int i = inputData[id.x].i;
    int index = MeshIndexToBiomeIndex(i) - biomeIndexIterat - blendRadius;
    for (int sampleZ = -blendRadius; sampleZ <= blendRadius; sampleZ++)
    {
        for (int sampleX = -blendRadius; sampleX <= blendRadius; sampleX++)
        {
            int iterator = 1 - (floor(Vector2Distance(x, z, sampleX + x, sampleZ + z) / blendRadius));
            int biome = biomeList[index];
            blendedBiome[biome] += iterator;
            index++;
        }
        index += (biomeIndexIterat / blendRadius) - (2 * blendRadius) - 1;
    }
        
    float denominator = pow(blendedBiome[0], 2) + pow(blendedBiome[1], 2) + pow(blendedBiome[2], 2) + pow(blendedBiome[3], 2);
    blendedBiome[0] = pow(blendedBiome[0], 2) / denominator;
    blendedBiome[1] = pow(blendedBiome[1], 2) / denominator;
    blendedBiome[2] = pow(blendedBiome[2], 2) / denominator;
    blendedBiome[3] = pow(blendedBiome[3], 2) / denominator;
    
    outputData[id.x].x = blendedBiome[0];
    outputData[id.x].y = blendedBiome[1];
    outputData[id.x].z = blendedBiome[2];
    outputData[id.x].w = blendedBiome[3];
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Note this similar problem in HLSL. May have to do with the data structure you're using. \$\endgroup\$
    – Engineer
    Nov 4 '20 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.