# DX11 [DX11] Drawing points with geometry shader

This topic is 2541 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I found out that for drawing points an lines with different sizes geometry shaders are the way to go...

My first draft lookes like this:

... cbuffer Size : register( b3 ) { float size; } ... [maxvertexcount(4)] void GS_POINT( point GS_INPUT input[1], inout TriangleStream<PS_INPUT> OutStream ) { PS_INPUT Out[4]; Out[0].pos = input[0].pos; Out[0].pos.x = Out[0].pos.x - size; Out[0].pos.y = Out[0].pos.y - size; Out[1].pos = input[0].pos; Out[1].pos.x = Out[1].pos.x - size; Out[1].pos.y = Out[1].pos.y + size; Out[2].pos = input[0].pos; Out[2].pos.x = Out[2].pos.x + size; Out[2].pos.y = Out[2].pos.y - size; Out[3].pos = input[0].pos; Out[3].pos.x = Out[3].pos.x + size; Out[3].pos.y = Out[3].pos.y + size; for( uint i=0; i<4; ++i ) { Out.pos = mul( Out.pos, World ); Out.pos = mul( Out.pos, View ); Out.pos = mul( Out.pos, Projection ); OutStream.Append( Out ); } OutStream.RestartStrip(); }

The point is, that i wanted to manipulate the point size not in object space but in pixels, hoever i counldn't find anything like that.
I would be so happy if one of you could tell me how to do that

##### Share on other sites
Do the World/View/Projection multiplications first, and then add 'size' to the result. Note that your XY coordinates will be between -1.0 and +1.0 when on screen, so to add one pixel to the size, you need to add 1.0 / width on X and 1.0 / height on Y, where width and height are the dimensions of your viewport.

##### Share on other sites
Thank you, but 1.0/width and 1.0/height seem to be too small...

The first visual results ( 1 Pixel ) I get when I multiply those values with 4, otherwise no triangle is drawn. Everything is set to screen resolution ( viewport, buffer width, projection matrix ). Is there any other thing i have to take care of?

##### Share on other sites
My mistake, should be 2.0 / width, as the coordinates are between -1 and +1 which has a width of 2.

Try something like this, which should get you a single pixel drawn. Multiply sizes by 2 to get 2 pixels etc.
 const float4 sizes[4] = { float4(0, 0, 0, 0), float4(0, 2/h, 0, 0), float4(2/w, 0, 0, 0), float4(2/w, 2/h, 0, 0) }; for( uint i=0; i<4; ++i ) { Out.pos = mul( Out.pos, World ); Out.pos = mul( Out.pos, View ); Out.pos = mul( Out.pos, Projection ); Out.pos = Out.pos / Out.pos.w; Out.pos += sizes; OutStream.Append( Out ); } 

##### Share on other sites
Thank you verry much!
The code works perfectly well.

One more question i have:
What does this line do?
Out.pos = Out.pos / Out.pos.w;

Isn't the w-component 1 in most cases? I just like to understand the code im using.

##### Share on other sites
For normal perspective projection it will be what Z was before the multiplication with the projection matrix, and the division is what actually brings the coordinates into [-1, 1] (if they're on screen).
The division will always be performed by D3D after your shader is run, but if you do it in the shader W/W = 1 and you output the coordinates exactly as their final values. Also this is what makes it possible to specify the size in pixels even if Z is not constant. If you draw in 2D and always use Z=1 for example you could skip the division.

See for example D3DXMatrixPerspectiveFovLH for how the projection matrix looks. W will be the vector multiplied by the rightmost column.
The Direct3D Transformation Pipeline explains more about how it works.

1. 1
2. 2
3. 3
Rutin
18
4. 4
JoeJ
14
5. 5

• 14
• 10
• 23
• 9
• 32
• ### Forum Statistics

• Total Topics
632632
• Total Posts
3007524
• ### Who's Online (See full list)

There are no registered users currently online

×