Forum

Sample and sort surounding pixels in compute shader

Hi
Having a particle system here where i want to sample from a heightmap.
In the following compute shader I tried that code for sampling all surrounding pixels of the current particle position in texture space.

I sample the values in an array.

Then I want to sort which is the lowest value.
For this I iterated through the array and if the array value is smaller then the previous array value, it should write that as current pixel index.

According to the pixel index i apply the velocity to the particle.

theoreticaly that should work or? In real-world scenario it does not work and i dont know why… particles move strange / shader is stuck in first index so all particles move to the top left

//==============================================================================
//COMPUTE SHADER ===============================================================
//==============================================================================

[numthreads(128, 1, 1)](numthreads(128, 1, 1))
void CSConstantForce( uint3 index : SV_DispatchThreadID )
{
float array8;
float3 pos_world = Outputindex.x.pos.xyz;
float2 pos_tex = ((pos_world.xy * float2( 1,-1 ) ) + 0.5);
int samples = 7;
float col = heightTex.SampleLevel(linearSampler,(pos_tex),0).r;
float dx;
float prev_dx=1.0;
float directionIndex=0;
float px = 1/resolution.x;

//sample values of surrounding 8 pixels starrting with top left clockwise
array0 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x-px, pos_tex.y+px),0).r;
array1 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x, pos_tex.y+px),0).r;
array2 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x+px, pos_tex.y+px),0).r;
array3 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x+px, pos_tex.y),0).r;
array4 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x+px, pos_tex.y-px),0).r;
array5 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x, pos_tex.y-px),0).r;
array6 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x-px, pos_tex.y-px),0).r;
array7 = heightTex.SampleLevel(linearSampler,float2(pos_tex.x-px, pos_tex.y),0).r;
for (int i = 0; i <= samples; i ++){
dx=arrayi;
if (dx<prev_dx) {
directionIndex=i;
prev_dx=dx;
}
}
//now you have the Index of the direction fom surrounding heigth value and can set velocity accordingly
Outputindex.x.vel.x = 0;
Outputindex.x.vel.y = 0;

if (directionIndex==0)
{
	Output[index.x](index.x).vel.x = -px;
	Output[index.x](index.x).vel.y = +px;	
}
if (directionIndex==1)
{
	Output[index.x](index.x).vel.x = 0;
	Output[index.x](index.x).vel.y = +px;	
}
if (directionIndex==2)
{
	Output[index.x](index.x).vel.x = px;
	Output[index.x](index.x).vel.y = px;	
}
if (directionIndex==3)
{
	Output[index.x](index.x).vel.x = px;
	Output[index.x](index.x).vel.y = 0;	
}
if (directionIndex==4)
{
	Output[index.x](index.x).vel.x = px;
	Output[index.x](index.x).vel.y = -px;	
}
if (directionIndex==5)
{
	Output[index.x](index.x).vel.x = 0;
	Output[index.x](index.x).vel.y = -px;	
}
if (directionIndex==6)
{
	Output[index.x](index.x).vel.x = -px;
	Output[index.x](index.x).vel.y = -px;	
}
if (directionIndex==7)
{
	Output[index.x](index.x).vel.x = -px;
	Output[index.x](index.x).vel.y = 0;	
}

}

that’s looks a bit complicated, however the problem you are describing sounds, like u are’t sample from the texture or your dispatch is wrong, in any case i had something similar with a texture in compute.

ok try dig in to pipet example i think you’r texture coords are wrong, look here:

int TotalCount=1;
bool UVSpace=0;
[numthreads(64, 1, 1)](numthreads(64, 1, 1))
void CS( uint3 DTid : SV_DispatchThreadID){
	if(DTid.x>=(uint)TotalCount)return;
	float2 TexCd=uv[DTid.x](DTid.x);
	if(!UVSpace)TexCd=TexCd*0.5*float2(1,-1)+0.5;
	int2 R;tex.GetDimensions(R.x,R.y);
	TexCd.xy+=0.5/R;
	Out[DTid.x](DTid.x) = tex.SampleLevel(s0,TexCd,0);
}

u have to take texcoord from thread ID
i’m not sure how this done properly you might need to dispatch your texture res…
the blur CS is also a good example from the NODE workshop

CS_Blur.rar (3.9 kB)

Hi Tekcor
I did that a while ago , i did it without using array , i think it’s what you are trying to achieve.
particle-water

Awesome thank you guys that helped a lot.

I am hoping to come up with a model for rivers and lakes on terrain height maps soon