Advertisement

Problem unrolling loop in compute shader

Started by November 04, 2020 03:40 PM
2 comments, last by MJP 4 years ago

Hey, 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];
}

Can it be your blend radius is not known at compile time, so unrolling is impossible?

Advertisement

It looks like the compiler is choking because of that ‘blendedBiome’ buffer that you declared as a local variable, but didn't initialize. You either need to assign a valid buffer to that variable, or make it a global if you intend it to be an additional bound buffer for your dispatch.

This topic is closed to new replies.

Advertisement