|
Vertex Blending Contents of this lesson 1. What is Vertex Blending?什么是顶点混合? 如果你对Direct3D管道技术不太了解的话,这篇文章可能改变你的思想。 当你发送顶点数据到渲染设备,它在世界坐标中的数据流中经过矩阵处理(视图和投影还未进行)世界矩阵按常规旋转,移动对象。 一般,世界矩阵转换每一个顶点用同一种方法,整个网格被旋转,移动。这种方法不能应用于每个独立的单元,缺乏柔性。 看一下以下画面。
没有比这更兴奋的,不更改原始格式将上面的网格渲染成下面的样子:
顶点弯曲需要我们建立四个矩阵,及变形的几何学分布。上图用了两个矩阵,第2个矩阵主要集中于下方,所以弯曲主要在下方。 2. How to set up simple vertex blending 如何设置一个简单的顶点混合 首先要考查硬件是否支持顶点混合,对于所有硬件每个顶点最多使用四个矩阵
上面代码最重要的是MaxVertexBlendMatrices这个数值,我们现在只用两个矩阵,所以只要核查2。 Pfinal = Pvertex * W1*M1 * W2*M2 * W3*M3 * (1.0-W1-W2-W3)*M4 Pfinal代表世界空间坐标 Pvertex代表原始的顶点模型坐标,W1, W2,W3是三个浮点弯曲值 M1, M2, M3 and M4代表四个矩阵。 下一布确定顶点格式,顶点格式如下描述:
在Direct3DDevice8.SetTransform( )函数中定义两个矩阵D3DTS_WORLD 及 D3DTS_WORLD1。从建立的以下下方程看出,B1越靠近1,顶点受D3DTS_WORLD影响越大,B1越靠近0,顶点受D3DTS_WORLD1影响越大。 Pfinal = Pvertex * B1*D3DTS_WORLD * (1.0-B1)*D3DTS_WORLD1 还有一个问题,从.x文件读入的文件并不知道顶点混合的权重值,所以在开始读入后改为下面的顶点格式
CloneMeshFVF( )会分配权重值,但它不会有任何数据,下步是最重要的-设置权重值:
本质上这个方法同关键贞动画是一样的 (original, extended). 早被使用。你可以改变弯曲值随你的需要,但是要记着处理1000个点可能会让程序减慢 这是渲染网格的初始化:
D3DVBF_DISABLE更快点 示例代码演示了绕 (Y and Z) 旋转的结果 3. Extending this to use all 4 matrices 扩展到4矩阵 The previous section dealt with using only the first two matrix slots. Just to cover all the bases I'm going to give a quick demonstration of how you could use all 4 matrices - with these two examples you should be able to work out how to do 3-matrix blending. The downloadable sample code does not include any of the source from this point onwards, but you should see how it will easily fit in... For using all 4 matrices we must change the FVF and the vertex declarator again:
By using this data format, you need to put valid matrices in all four slots: D3DTS_WORLD, D3DTS_WORLD1, D3DTS_WORLD2, D3DTS_WORLD3. The weighting of all 4 matrices is calculated as follows: D3DTS_WORLD = B1 D3DTS_WORLD1 = B2 D3DTS_WORLD2 = B3 D3DTS_WORLD3 = (1.0 - B1 - B2 - B3) which follows the format of the general equation stated earlier. When you are ready to render the geometry you must use the following two lines of code:
upon doing this you will be ready to go! 4. Taking it all the way: Indexed vertex blending Vertex blending has been available through Direct3D for several versions now, the methods discussed thus far are nothing new. However, there is one new addition to vertex blending for Direct3D8 - indexed vertex blending. This still limits you to a maximum of 4 matrices per vertex, BUT it allows you to specify up to 256 matrices for each call. How does this work? well, it's actually very clever... If you're an experienced DirectX programmer, you may well remember using/learning how 8-bit palletized textures work. Each pixel stores an 8bit number - this indexes to to a palette of 256 different colors, but each color in the palette is defined as a 24 bit RGB triplet. A similar idea applies here. For each vertex we still have the blending weights (1,2 or 3 of them), but we also add a 4-byte packed index value. This 32bit long is 4 indices packed into one variable. The idea being that you can store the 3 weights as appropriate, but then use the indices to select which 4 matrices they apply to - from a list of up to 256. Say for example you had a list of 35 matrices setup, and for a triangle of 3 vertices you wanted 11 different matrices (based on each vertices distance from a bone node for example). This wouldn't be possible using the traditional method. For example: to use indexed vertex blending we must (again) alter the vertex structure and the FVF:
A useful trick for setting the four indices is to use the D3DColorARGB( ) function. Because VB doesn't have an unsigned 32bit integer variable, when bit shifting/packing the 4 indices we have to mess around with the signed bit. Using D3DColorARGB( ) avoids this problem. For example:
If you do use the above technique, but choose not to use 4 matrices then the color components refer to: A=D3DTS_WORLD3 R=D3DTS_WORLD2 G=D3DTS_WORLD1 B=D3DTS_WORLD Before you actually use indexed vertex blending you need to check hardware support. Only the more recent hardware will support any significant number of matrices - my ATI Radeon8500 supports 58 matrices (slots 0 to 57), and not the full 256 possible.
When you actually want to use indexed vertex blending there are 3 things you must do: first: create and apply each matrix. You can't apply more matrices to the device than specified in the above enumeration. The following code will allow you to set a matrix in slot "I":
secondly, you must enable indexed vertex blending:
lastly, you must set the FVF:
Having completed all these steps, all geometry rendered from now on will be probably blended based on the matrix palette indices and the weighting values. Configuring Direct3D to let you use indexed vertex blending is not a complicated task - however, writing an algorithm that selects the correct weights and matrix indices is going to be the far harder challenge. It may well be worth writing a plugin/tool for a 3D renderer that allows an artist to specify weighting values. One solution I have thought of - assuming you were using this
technique in conjunction with skeletal animation (I would!): In using a solution like that the artist need only specify a skeleton animation and a mesh-skin, and the resulting animation would be a very convincing and fluid system. |