Rendering animation with vertex shader in DirectX 8
Summary: This article discusses animation rendering of objects and contours in Microsoft DirectX 8, and provides an example application. View the Toon.exe sample code in MSDN Online Code Center (English). Download the Toon.exe sample file. (242 KB) Introduction "Animation Rendering" does not have a specific definition. It is generally referring to the style of non-photo real style, the effect is similar to cartoons and comic books. Typically, it uses a large single color block and the object outline. In the architecture discussed here, rendering can be divided into two problems:
Rendering the object "body" in a certain style. (Interestingly, in most cases people don't want the color strip, but here we have to highlight it.) Rendering the edge of the contour as a thick black line. Rendering Objects We carry out a method of calculation to diffuse light (using a one-way light source in this example). However, we don't enter the results into the resulting color, but the light value as a texture coordinate of simple light pattern. This texture can be dyed using the desired material color color colors loaded into the diffuse iterator. The following is the vertex shader program: input: v0 = location
; v1 = method
; C0 = (0, 0.5, xxx, xxx) useful constant
; C1-4 = WORLDVIEW matrix
; C5-9 = WorldViewProjection Matrix
; c9 = light / material color
; C10 = light direction (in the observation space)
VS.1.0; shader version 1.0
M4X4 OPOS, V0, C5; Computing Projection Location
M3X3 R1, V1, C1; R1 = Observation Spatial Method
DP3 R2, -R1, C10; R2 = diffuse light calculation
MAX R2, R2, C0.X; fix R2 to 0
MOV OT0.X, R2; Texture Coordinate 0 is (R2, 0.5)
Mov OT0.Y, C0.Y
MOV OD0, C9; Diffuse color = C9 is simplified, and the light calculation is carried out in the view space. In the object space, it is obvious to optimize, so that the shader does not have the second matrix multiplication (in the view space we want to perform the back-to-directional transformation to provide the light source direction). The key step is to load the results of the illumination to the "U" component of the texture coordinate. This will effectively turn the coordinates into a one-dimensional lookup form, depending on it, according to it we can accurately obtain the required texture strips. Finally, we load the colors of the material (or see it as a light) to the diffuse iterator, we will use it to modulate the intensity value read from the texture. If we are willing, you can read this value from the vertex element. But for simplification, we assume that this object has only a single color, so it is only necessary to use a constant. Note how to compress a plurality of useful constants into a C0 constant registration item. Since we want to make it a "V" component in the texture coordinates (placed in the middle of the texture, avoid certain boundary sampling problems), then we load zero to c0.x, to limit its lighting point, will 0.5 loading to c0.y. Rendering the contour to render the object profile, we need to detect the edges of the contour. If the two masks adjacent to a side have different directionality, for example, one is the backward face and the other is not, then this edge is part of the contour. For smoothing objects, if the normal of the vertex is perpendicular to the view vector pointing to the vertex, it can be approximately processed as the vertex on the outline. In other words, if the point of the screen spatial position is zero, it is assumed that the vertex is on the outline. In this way, we can use the vertex shader to calculate the orthogonal view vector and the vertex method. The value equal to or near zero indicates that we are located or close to the outline. Roughly said that points value indicates the distance from our contour boundary. In order to bold the contour boundary to produce a good "cartoon" effect, we set a threshold, as long as it is lower than this value, it is considered to be part of the contour, the higher the threshold, the thicker the edge. Since we want to get outlined, test this threshold for each pixel. It is good to have an Alpha test mechanism to perform this test. If we load it into the alpha channel of the diffuse iterator (from [-1, -1] to [0,1]), then we can exclude the point on the outline via the Alpha test, and then put the remaining Pixel rendering is pure black. The following is the vertex shader program: input: v0 = position; v1 = method
; c0 = useful constant (0, xxx, xxx, xxx)
; C1-4 = WORLDVIEW matrix
; C5-9 = WorldViewProjection Matrix
VS.1.0; shader version 1.0
M4X4 R0, V0, C1; R0 = Observation Space Location
M3X3 R1, V1, C1; R1 = Observation Spatial Method
M4X4 OPOS, V0, C5; Computing Projection Location
DP3 R2.X, R0, R0; orthogonal R0 (location)
RSQ R2.x, R2.x
Mul R0, R0, R2.x
DP3 R3.x, R0, -R1; calculation point
Mad OD0.W, R3.x, C0.Y, C0.Y; Zoom to [0, 1], and perform alpha processing
MOV OD0.XYZ, C0.X; Radix RGB is 0 Please note that the output position is calculated by direct conversion of the WORLD View Projection Merge Matrix, rather than by the viewing space of the projection matrix to be incremented. The reason is that we must ensure that the method of performing the position calculation is "completely" as the method used for the object rendering, otherwise the ghost effect may be generated. The pixel pipe for performing this processed is set to copy the diffuse color and perform an Alpha test, so the code should be: m_pd3ddevice-> setrenderstate (D3DRS_ALPHESTENABLE, TRUE); m_pd3ddevice-> setrenderstate (D3DRS_ALPHAFUNC, D3DCMP_LESS);
m_pd3ddevice-> setrenderstate (D3DRS_ALPHAREF, M_DWSILHOTTEAMOUNT);
We can control the thickness of the silhouette edge by changing the Alpha test reference value, ie m_dwsilhouetteamount. Limit this technique to have some restrictions. Especially for objects having large area flat surfaces or by the inlaid surface, the rendering effect is generally not ideal, because the normal direction changes in these faces is not large or there is no change, and the entire object is dyed into a single color. Mark the large area as "outline". Sometimes this effect may comply with our expectations, but in general, it can only be said to be a strong man. Using a more complex point light source solution, the problem of single coloring of the object can be eliminated to a certain extent. However, there is still difficult to apply contour rendering techniques described herein. However, if it is a basic sleek object, the effect is very good. The sample application "TOON" sample application demonstrates this technology to simple grid applications in the sample application framework in Microsoft® DirectX® 8 SDK. To compile this sample program, create a directory under the "MSSDK / Samples / MultiMedia / Direct3D /" path, then copy the source file into the directory (this sample program references some DirectX 8 SDK public example application frame file ). View the Toon.exe sample code in MSDN Online Code Center (English). Download the Toon.exe sample file. (242 kB) The control method is as follows:
Operational Control Influence / Decrease Threshold Q / A Switch Built-in Grid (Ring or Circle) T Rotate Object Click Left mart and drag loading. X file L Rendered load .x file O