In this lesson you'll be using a programmable vertex shader to animate the vertices of the model. Animating vertices using the fixed function pipeline would require either updating the vertex positions stored in the vertex buffer, or changing tranformation matrices for each vertex. Because smooth animation would require making these changes for every frame, both of these approaches are prohibitively slow for most applications; if, however, the animation is performed in a programmable vertex shader, the animation can be performed during the transformation process at minimal expense. As before, the given solutions are just suggested implementations, and your answers may vary.
The vertex animation goal contains a single task: Use the Time variable to modify geometry.
Extra Credit: Use sin(float3) to create a rippling skull.
Preparation
Open Goal2.fx. If you have the SDK installed, the .fx file is located at:
(SDK root)\Samples\C++\Direct3D\Tutorials\HLSLWorkshop\
Description
The default render technique is HemisphereDiffuseSpecular, which uses the full hemispheric lighting equation developed in the previous lesson:
Preparation
Locate Goal 2A in the code and follow the instructions.
Description
You can put the current time in seconds in any float variable with the TIME semantic like the Time variable declared above. Offset is just the vertex's model space coordinate, and can be used to distinguish different vertices so that any motion generated at one vertex is not the same as all vertices (that is, it can be used to offset the sine evaluation so that each point is at a different point in the sine equation).
One good method of animating things is using sine or cosine. This can be used to generate waves or other interesting interference patterns.
A couple of HLSL features will be very useful for this task. First, most of the intrinsic functions are defined for both scalar and vector types (that is, if you pass a vector to the sine function it will return a vector containing the sine of each vector component). Second, a single component scalar type will automatically be promotion cast to multiple component types when the function returns.
You probably do not want to add or subtract too large a value per vertex. Multiplying the result of sine or cosine by 0.1 is a good start for the skull model.
Solution
In particular, this task doesn't have any right or wrong implementations. Here are a few values which give interesting results:
return sin(Time); return sin(Time * Offset) * 0.1; return sin(Time + Offset) * 0.1; return float3( sin(Time + Offset.x), sin(3*Time + Offset.x), 0) * 0.5; return (Normal*(sin(Time)+1))*0.5; // For this solution, you'll need to pass "Normal" into the function
The computed value is added to the vertex's transformed position inside the vertex shader, resulting in a periodic animation:
This completes Goal 2. Feel free to try the extra credit problem or move on to Goal 3 when ready.