Jump to content
  • Advertisement
Sign in to follow this  
Wh0p

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!