🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Problem unrolling loop in compute shader

Started by
2 comments, last by MJP 3 years, 7 months 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];
}
Advertisement

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

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