Jump to content
  • Advertisement
Sign in to follow this  
mmurphy

DX11 [DX11] Progressively adapting vertex position

This topic is 2603 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 am attempting to make a simulation of something related to what is known to some people as a "Sky Guy" (those giant things outside of a used car dealership, such as http://blog.chron.com/carsandtrucks/files/legacy/Sky%20guy.gif ). Anyway, I am finding it difficult to figure out how to change the vertex position at the top end of the object, while keeping the bottom one fixed. I was thinking that I would be able to do this in the tesselation or geometry shader stages, however, I can't seem to figure out how this might be possible. Could anyone clue me into how to do this?

Share this post


Link to post
Share on other sites
Advertisement
I would assign each vertex a value that corresponds to the distance from the root of the whole thing. Then use a constant value in the vertex shader to determine where to begin displacing the object into another direction. If the vertex value is less than the "strobe" value, then simply transform them as normal. If it is greater than the strobe value, then rotate it by x amount in the direction you want - but you need to make sure that the rotation is performed with respect to the point where the vertex value transitions from negative to positive.

That last part could either be done directly with trigonometry in the vertex shader, or you could generate a rotation matrix on the CPU for a given "strobe" value.

Share this post


Link to post
Share on other sites
I think I would approach this more as a physics problem than rendering. Treat the tube guy as a cloth, for example a spring system. Then fix the bottom ring of vertices and flip gravity (to make it rise). To make it move add some small sideways forces or model turbulence.

I recall that the game "Gunstringer" has a "sky guy" boss. Maybe you can look at that and get some ideas.

Edit: Found a video of the wavvy tube man in Gunstringer. Skip to to 6:15.

Share this post


Link to post
Share on other sites

That last part could either be done directly with trigonometry in the vertex shader


Would you happen to be able to provide an example of how to do this? I have been trying to figure it out in my spare time over the last few days but I can't seem to nail this down.

Share this post


Link to post
Share on other sites

[quote name='Jason Z' timestamp='1318272900' post='4871154']
That last part could either be done directly with trigonometry in the vertex shader


Would you happen to be able to provide an example of how to do this? I have been trying to figure it out in my spare time over the last few days but I can't seem to nail this down.
[/quote]

You can do it also with a simple rotation matrix - it doesn't have to be manual trigonometry. If you have h = the height of the curving point, then you can take the vertex's object space position (x,y,z) and change it to (x,y-h,z). Then apply the desired rotation (such as a 20 degree rotation about the x-axis), which produces (x',(y-h)',z'). Then just add the value of h again to push the vertex back up to the appropriate height: (x',(y-h)'+h,z').

Note that this is working in object space, so then any additional rotations or translations for the world transform can be applied next. This is very much similar to skeletal animation, except that you are defining the bone weights dynamically based on a program supplied constant value.

(sorry for the slow response...)

Share this post


Link to post
Share on other sites

You can do it also with a simple rotation matrix - it doesn't have to be manual trigonometry. If you have h = the height of the curving point, then you can take the vertex's object space position (x,y,z) and change it to (x,y-h,z). Then apply the desired rotation (such as a 20 degree rotation about the x-axis), which produces (x',(y-h)',z'). Then just add the value of h again to push the vertex back up to the appropriate height: (x',(y-h)'+h,z').

Note that this is working in object space, so then any additional rotations or translations for the world transform can be applied next. This is very much similar to skeletal animation, except that you are defining the bone weights dynamically based on a program supplied constant value.

(sorry for the slow response...)


"h" because the max height of the curving point (apex), the current height of vert or the max height of the object? I just want to be clear because I believe I may have misunderstood you (I am sure you explained it fine, this is new territory to me so I still trying to grasp everything).

I attempted with the current height of the vert, though this did not turn out as well as I initially thought it would. Though I understand why. Disregarding object space at the moment, What this will end up doing is essentially cancel out the rotation applied from the rotation matrix.


float4 position = input.Pos;

position.y -= input.InputHeight;

position = mul( float4( position.xyz, 1.0f), RotationMatrix);
position.y += input.InputHeight;

output.Pos = mul( float4( position.xyz, 1.0f), ViewProjMatrix);




(sorry for the slow response...)


No worries at all, it is the quality that matters. As someone who has taken a look at Hieroglyph 3 and has a copy of your book, I know that it is something I can always count on.

Share this post


Link to post
Share on other sites
From what I can tell, if your input.InputHeight variable is a constant for the whole mesh, then that code snippet should work. You are more or less trying to rotate a portion of your mesh based on its object space location (specifically its height in this case). If a vertex is above the input.inputHeight variable, then you want to rotate it by an amount relative to its distance from input.inputHeight.

After just writing that paragraph I realized that a shearing matrix might work better for the effect you are trying to get - but a rotation should do fine as well. If you can post your shader code along with a screen shot then I'm sure we can work out the kinks.

No worries at all, it is the quality that matters. As someone who has taken a look at Hieroglyph 3 and has a copy of your book, I know that it is something I can always count on.[/quote]
Thanks for the comment - I really appreciate it! If you have any feedback (good or bad), please let me know - I'm always interested to hear what works or doesn't on the book.

Share this post


Link to post
Share on other sites
I was using input.Height as just the height per vertex (so the local y value ... which I could have used position.y for this was going to be more an identifier also ... just more as general testing for the time being).

I tried making it the max height, though I just got a straight line, no matter how many sections I have in it (the image below shows three sections, but I have tested it with seven also).

Both of the these images are the same object, just from and side angle with a 20 degree x rotation.

Front: http://img818.imageshack.us/img818/1670/frontx.png
Side: http://img42.imageshack.us/img42/4139/backlm.png

My complete shader code is


cbuffer MatrixCB : register( b0 )
{
matrix WorldViewProjMatrix;
matrix WorldMatrix;
matrix ViewProjMatrix;
matrix RotationMatrix;
}

cbuffer DisplayColorCB: register (b1)
{
float4 DisplayColor;
}

struct VS_INPUT
{
float4 Pos : POSITION;
float InputHeight : INPUTHEIGHT;
};

struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
};

VS_OUTPUT VS( VS_INPUT input )
{
VS_OUTPUT output = (VS_OUTPUT)0;

float4 position = input.Pos;

position.y -= input.InputHeight;

position = mul( float4( position.xyz, 1.0f), RotationMatrix);
position.y += input.InputHeight;

output.Pos = mul( float4( position.xyz, 1.0f), ViewProjMatrix);

return output;
}

float4 PS( VS_OUTPUT input ) : SV_Target
{
return DisplayColor;
}


Thank you for the help

Share this post


Link to post
Share on other sites
The way that I am envisioning it is that InputHeight should be a constant value provided in a constant buffer, along with the DisplayColor variable. Its value should range from the minimum vertex y-value to the maximum vertex y-value. Double check to make sure that the value is within this range - wherever that value falls within your height range is where the bend should occur.

Just to debug and make sure you are properly selecting the desired vertices, you could just use a static branch to determine the color of the vertices. If it is above then color it red, and below color it green. That should let you ensure that your value scales are all set up the way they should be. Once you are sure about the selection, then applying the rotation should be easier to test out.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!