ComputeShader - connect all vertices

hello partypeople,

i’m giving myself some exercises to learn hlsl. Yesterday I was thinking about a ConnectAll ComputeShader.
While the CPU approach is quite straight forward iterating…

FOutput.SliceCount = SpreadMax * (SpreadMax-1);
int k = 0;
for (int i = 0; i < SpreadMax; i++){
	for(int j = 1 + i; j < SpreadMax; j++){
		FOutput[k](k) = FInput[i](i);
		k++;
		FOutput[k](k) = FInput[j](j);
		k++;
	}
}

… I wonder how it is done when everything is threaded and gets calculated at the same time.
Is it even possible to access the other vertices that are running on the other threads? Thats the moment where the dog on the gpu bites his own tail I guess?

- include "particle_struct.fxh"

StructuredBuffer<particle> particles;  // particle input
AppendStructuredBuffer<particle> Output : BACKBUFFER;  // particle output

[numthreads(128,1,1)](numthreads(128,1,1))
void CSConnectAll(uint3 index : SV_DispatchThreadID)
{
	uint size, stride;
	particles.GetDimensions(size, stride);
	
	//getting other particle positions and append them
	Output.Append(particles[index.x](index.x));
}

technique10 Connect
{
	pass P0
	{
		SetComputeShader( CompileShader( cs_5_0, CSConnectAll() ) );
	}
}

(I’m trying this with particles, and yes, I’m aware that the result amount of particles would be n*(n-1) :-).)

But there are also some even more basic questions.
Maybe thats just not a task for the GPU?
Maybe it’s better to create the vertices (and lines) directly in GeometryShader?

And maybe its so simple that I just don’t see it…

Thanks for your help!
jungle!

hi. sry did’t head time to write proper answer before

it’s ok task for gpu, and yes u have to create lines in GeometryShader
in general there are few options u can create every line, then discards ones that are not passed test

Thanks, antokhio,

so when doing this completely in GeometryShader, I have the next question.

For example with this code

[maxvertexcount(2)](maxvertexcount(2))
void GS(line vs2gs input[2](2), inout LineStream<gs2ps> gsout)
{
	gs2ps output = (gs2ps)0;
	output.pos = input[0](0).PosWVP;
	gsout.Append(output);
	output.pos = input[1](1).PosWVP;
	gsout.Append(output);
}

the input-stream (as a LineList) lets me access the position of 2 vertices - but not all of them to connect them all?
My initial idea was to generate “pairs” of vertices in a ComputeShader and then send them to the rendering pipeline.

So, is there a way to get all the vertices diretly in GS? That basically would change my understanding of this stage ;-).

(by the way, any book recommondations to dx11? thinking of this one: http://www.amazon.com/Practical-Rendering-Computation-Direct3D-11/dp/1568817207)

THX!

u need to replace inout LineStream with TriangleStream
since u can’t use linestram to draw triangles u also gonna need to maintain proper input for triangle steam
otherwise u need second geometry shader that will convert linestream to triangle steam.
usually i just take GS quad code and offset the vertices of the quad

since u know a bit programming might u can check this one
https://discourse.vvvv.org/t/12888
can’t figure out how to assign ouputs for the pins
the idea is suppa simple u got spread of textures and spread of binsizes u want to split them across pins… however changing this part to tex in my patch prolly way to go…

the mentioned book is a good one. it´s online…

Thanks again, antokhio,
either I still don’t get it or we missunderstood each other :).
I don’t want to draw triangles; I want to connect every vertex with every vertex - like the good’ol connectall-(3d-vector).

i’ll have a look at your thread!
best!

thx sinus, i’m gonna get it!

here is a bruteforce way that actually worked for me once:
your positions are in a buffer(N), dispatch N*N vertices (with NullGeometry node), draw lines in GS from (i%N) to (i/N)
that way you’ll cover all combinations (any vertex connected to every other vertex)

1 Like

we’re getting closer, but that’s

still the part I dont get. If I could access all the vertices in a loop and iterate through them - okay. but thats not how the GS works…
hmm. :D

i mean - you only read two positions in GS and drawing one line, no loops. and since you dispatch N*N of them (and by that getting all possible pairs), all lines will drawn in the end. twice :D

Instead it’s also possible to build a lookup table.

Saves the double drawing and moves from n^2 to serie 1+2+3+…+n-1 element count.

If your element count doesn’t change it needs to be built only once, and can be easily stored in a buffer just once.

Here is a quick patch example to build this (with small plugin to generate the lut)

ValueConnectAllIndices.zip (10.8 kB)

1 Like

thanks, vux and unc,

i’ll give that one more try later…

@vux: the thing is, since the particle-positions already are in a StructuredBuffer, I didn’t want to pull them back to cpu again. And the other reason for doing this on gpu was learning purpose :).

Since it uses a lookup table, you don’t need to pull them back, just use the table to lookup in your own buffer, which can come from anywhere.

1 Like

okay, now I have working solutions and I want to thank you very much, guys!

the initial idea was to create the particles on gpu and connect them there as well. I’ll try to do the lookup table on gpu as well, then i’m happy :).

THANKS!