﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-上下求索</title><link>http://www.cnblogs.com/sssa2000/</link><description>探索DirectX9.0)</description><language>zh-cn</language><lastBuildDate>Sun, 05 Jul 2009 16:25:44 GMT</lastBuildDate><pubDate>Sun, 05 Jul 2009 16:25:44 GMT</pubDate><ttl>60</ttl><item><title>[论文摘要]Tips and Tricks for D3DX Effects-Based Renders</title><link>http://www.cnblogs.com/sssa2000/archive/2009/05/01/1447309.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Thu, 30 Apr 2009 16:24:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2009/05/01/1447309.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1447309.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2009/05/01/1447309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1447309.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1447309.html</trackback:ping><description><![CDATA[<div>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">ShaderX4的这篇文章主要将的是在设计一个用于的实时绘制Render的时候，如何处理渲染状态的问题。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">在渲染中，尤其是多PASS的渲染中渲染状态的管理是一个很重要的议题。由于渲染状态的切换回影响到绘制的效率，所以人们想了很多的方法来尽量减少渲染状态的切换。文中提出，考虑到D3D&nbsp;API调用的开销以及D3D&nbsp;API和GPU&nbsp;Driver的开销，将渲染状态的Restoring操作放到了Fx中进行。通过在fx中添加一个额外的pass，这个pass不渲染任何几何体只进行渲染状态的设置。例如：</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;technique&nbsp;tec20&nbsp;{</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass&nbsp;POpaque&nbsp;{</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VertexShader&nbsp;=&nbsp;compile&nbsp;vs_1_1&nbsp;vsMainOpaque();</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PixelShader&nbsp;=&nbsp;compile&nbsp;ps_1_1&nbsp;psMainOpaque();</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AlphaTestEnable&nbsp;=&nbsp;True;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AlphaFunc&nbsp;=&nbsp;Greater;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AlphaRef&nbsp;=&nbsp;250;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass&nbsp;PAlpha&nbsp;{</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VertexShader&nbsp;=&nbsp;compile&nbsp;vs_1_1&nbsp;vsMainAlpha();</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PixelShader&nbsp;=&nbsp;compile&nbsp;ps_1_1&nbsp;psMainAlpha();</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AlphaTestEnable&nbsp;=&nbsp;False;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ZWriteEnable&nbsp;=&nbsp;False;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AlphaBlendEnable&nbsp;=&nbsp;True;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SrcBlend&nbsp;=&nbsp;SrcAlpha;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DestBlend&nbsp;=&nbsp;InvSrcAlpha;</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass&nbsp;PRestore&nbsp;{</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AlphaBlendEnable&nbsp;=&nbsp;False;&nbsp;//&nbsp;restore&nbsp;alpha&nbsp;blend&nbsp;to&nbsp;standard&nbsp;value</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ZWriteEnable&nbsp;=&nbsp;True;&nbsp;//&nbsp;restore&nbsp;z&nbsp;write&nbsp;to&nbsp;standard&nbsp;value</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">紧接着，作者花了比较长的笔墨来阐述哪些渲染状态是经常改变的哪些是基本不变的等等。说着写的目的就是为了做一个分类，确定哪些渲染状态是需要在fx文件中使用一个多余的pass还原渲染状态的。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">在ShaderX6的一篇文章：A&nbsp;Flexible&nbsp;Material&nbsp;System&nbsp;in&nbsp;Desgin中也有提到关于将渲染状态分类的内容。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">接下来，作者阐述了使用上述方法的一个实现思路：那就是引擎读入fx文件后，分析该fx做了哪些渲染状态的改变，然后找出在下一个pass渲染前有哪些渲染状态是需要Restore的。最后动态将需要Restore的渲染状态写到一个新增的pass中去。分析fx中有哪些渲染状态改变的方法可以使用DXSAS语法。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">那么如何将一段动态生成的pass代码塞入到已有的fx中去呢？作者提出的方法是使用Effect框架的宏。也就是说，以上面的fx代码为例，在书写fx的时候，这么写：</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;technique&nbsp;Foo&nbsp;{</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass&nbsp;P1&nbsp;{&nbsp;...&nbsp;}</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass&nbsp;P2&nbsp;{&nbsp;...&nbsp;}</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RESTORE_PASS</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">其中RESTORE_PASS是一个宏，这个宏的内容是动态设置进去的，作者利用了D3DXEffect的这样一个特性来进行动态代码的生成。不过这个方法的缺点是需要将fx载入两次，因为必须在创建Effect的时候就将宏提交给D3DX&nbsp;API。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">管理渲染状态的另一个有效的方法是，使用D3DX提供的一个接口ID3DXEffectStateManager，使用这个接口需要派生该接口并实现相应的虚函数，就可以在派生类中记录状态切换的的次数以及根据现有的状态进行是否需要进行渲染状态的更改的决策。我依稀记得D3D&nbsp;SDK的Sample中就有一个关于State&nbsp;Manager的示例，有兴趣的朋友可以Check一下。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">文中最后提到将渲染物体分类的话题，将渲染物体分类确保使用相同Effect的物体可以不需要切换fx代码渲染。同时文中也给出了一个&#8220;准泛型&#8221;的设置Shader常量的方法，使用一个对象记录一个fx中的变量名（或者handle）和实际的引擎的值的关系，然后使用这个对象统一设置shader的常量。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">在ShaderX3中有一篇文章：Effect&nbsp;Parameters&nbsp;Manipulation&nbsp;Framework，方法和上述如出一辙，不过讲的更加详细一些。另外关于设置Shader常量的文章在ShaderX5中有一篇Transparent&nbsp;Shader&nbsp;Data&nbsp;Binding，不过我认为这篇文章更多的是一篇关于C++函数指针的文章，中心思想是使用C++中的联合进行类型转换，看上去有点像观察者模式的实现。从表面上分析为fx的shader常量设置值的过程很像是设计模式中讲到的观察者模式，但是我认为和观察者模式有一个很大的不同，那就是不管在一帧当中不管fx的shader常量有没有发生变化都要进行shader常量的设置，不能说摄像机的位置没有发生变化就不设置了。所以反正在每帧会之前都需要进行绘制，那么不如老老实实在绘制前统一的进行各种SetXXX调用，这样也利于调试也不会出现编译器的差异的问题，虽然我也承认ShaderX5的那篇文章提到的方法很美丽，不过我实在是没有能够在设计的时候找到需要用到该技术的位置。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">到此，文章结束。纵观全文，作者的思想是建立在设计一个基于fx文件驱动的引擎。这个引擎的特点是基于一堆写好的shader的基础上的。在渲染状态管理方面，作者将渲染状态Restore的工作交给了GPU来进行，同时通过实现ID3DXEffectStateManager接口将多余的渲染状态设置过滤掉。这个方法看上去似乎很好但是，假如2个物体接受相同的光照，有相同的纹理只是因为一个是透明的一个不是透明的，那么渲染这2个物体就需要使用2个不同的fx文件，这就意味着向GPU提交了2次fx代码，而这个消耗肯定比D3D&nbsp;API的消耗要大。如果把渲染状态全部放在CPU端管理，通过D3D&nbsp;API来设置，那么就能够最大限度的将材质差不多的物体使用一个fx代码来渲染。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">以上只是我的浅薄的看法，如果有不同的看法欢迎留言。如果想看这篇Paper的朋友可以去http://aras-p.info/texts/d3dx_fx_states.html，这是同一个作者写的这篇内容几乎和ShaderX4上的这篇内容一模一样，只有少许差别。</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">另外，作者也提供了他的一个引擎的源码，地址是http://dingus.berlios.de/</span></p>
<p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">其中包含了上述思想的详细实现，代码可读性很强。</span></p>
</div><img src ="http://www.cnblogs.com/sssa2000/aggbug/1447309.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47989/" target="_blank">Twitter无处不在 魔兽世界Twitter发送器插件发布</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[zt]矩阵和向量的乘法顺序</title><link>http://www.cnblogs.com/sssa2000/archive/2009/04/30/1447205.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Thu, 30 Apr 2009 11:02:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2009/04/30/1447205.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1447205.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2009/04/30/1447205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1447205.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1447205.html</trackback:ping><description><![CDATA[<p>from : http://blog.csdn.net/Nightmare/archive/2009/03/12/3983724.aspx <br />
</p>
<p>似乎经常有人被这个问题转晕。向量有两种表达形式，行向量和列向量，对应的矩阵也有行矩阵和列矩阵。采用哪种形式和左右手系无关。</p>
<br />
行矩阵：<br />
&nbsp;&nbsp;&nbsp; 三个轴向量为前三行，最后一行为位移变换<br />
&nbsp;&nbsp;&nbsp; 连乘时从左到右接合，左边的变换先应用<br />
&nbsp;&nbsp;&nbsp; 变换向量时为vector * matrix<br />
列矩阵：<br />
&nbsp;&nbsp;&nbsp; 三个轴向量为前三列，最后一列为位移变换<br />
&nbsp;&nbsp;&nbsp; 连乘时从右到左接合，右边的变换先应用，注意这和*运算符的接合顺序相反<br />
&nbsp;&nbsp;&nbsp; 变换向量时为matrix * vector<br />
<br />
DirectX 采用了行矩阵，OpenGL采用了列矩阵，而基于OpenGL的OpenInventor却采用了行矩阵。图形学的书籍多使用列矩阵和列向量，或许是学术 上的传统，或许是节省版面的原因；而不少图形库选择了行矩阵是因为行矩阵在现有的内存架构上效率要略高于列矩阵。另外，行矩阵的接合顺序和*运算符是一致 的，这一点非常适合运算符重载。<br />
<br />
而四元数则不同，在数学上，四元数的乘法只有从右到左接合定义。DirectX里为了四元数也能和行矩阵 的接合顺序一致，也特意颠倒了四元数的乘法顺序，使四元数也能符合*运算符的接合顺序。WPF、XNA都采用了右手系、行矩阵，然而决定让四元数恢复它的 本来模式。如此，四元数必须独立看待，虽然重载了*运算符，但千万不要用它来连乘，因为接合顺序是错误的。<img src ="http://www.cnblogs.com/sssa2000/aggbug/1447205.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47988/" target="_blank">Firefox 3.5匆忙推出漏洞多 Mozilla本月将更新</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[论文简要]Integrating Shaders Into the Vision Rendering Engine</title><link>http://www.cnblogs.com/sssa2000/archive/2009/04/23/1442497.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Thu, 23 Apr 2009 15:17:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2009/04/23/1442497.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1442497.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2009/04/23/1442497.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1442497.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1442497.html</trackback:ping><description><![CDATA[<p>shaderx3中的这篇paper现在看来明显已经成为了3d game engine设计的commom sense。</p>
<p>下面按照文中的章节标题进行摘要性的叙述：</p>
<h2>Assigning Shaders to Geometry</h2>
<p>　　文中提到，将物体的shader分成2种，一种是静态物体的材质例如毛皮，凹凸等等，一种是动态环境例如动态光影，体积雾等等。在进行动态shader的计算的时候如果动态环境是具有体积效果的话，需要找出受动态环境影响的可渲染物的集合。</p>
<p><br />
</p>
<h2>Rendering Order </h2>
<p>　　文中将渲染基本的纹理贴图和静态光照称为Base Pass。将其他的动态效果或者是其他shader的渲染称之为Effect Pass。<br />
</p>
<p>　　在进行渲染的时候，常识是先进行不透明物体的渲染，再进行透明物体的渲染。但是在多pass渲染的情况下这个方法就不那么灵验了。多pass的情况下使得渲染顺序的复杂度剧增，为了解决这个问题，并能够协调诸如钩边，体积雾等技术，文中提出了以下解决方法：</p>
<p>　　</p>
<div class="cnblogs_code"><img id="Code_Closed_Image_230901" onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_230901').style.display='none'; document.getElementById('Code_Open_Image_230901').style.display='inline'; document.getElementById('Code_Open_Text_230901').style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" width="11" height="16"><img id="Code_Open_Image_230901" style="display: none;" onclick="this.style.display='none'; document.getElementById('Code_Open_Text_230901').style.display='none'; getElementById('Code_Closed_Image_230901').style.display='inline'; getElementById('Code_Closed_Text_230901').style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" width="11" height="16"><span style="background-color: highlight;" id="Code_Closed_Text_230901" class="cnblogs_code_Collapse">Code</span><span id="Code_Open_Text_230901" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;RenderLoop3()<br />
</span><span style="color: #008080;">&nbsp;2</span><span style="color: #000000;"><img id="Codehighlighter1_19_244_Open_Image" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_19_244_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_19_244_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_19_244_Closed_Text').style.display='inline';" align="top"><img id="Codehighlighter1_19_244_Closed_Image" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" style="display: none;" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_19_244_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_19_244_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_19_244_Open_Text').style.display='inline';" align="top"></span><span id="Codehighlighter1_19_244_Closed_Text" style="border: 1px solid #808080; background-color: #ffffff; display: none;"><img src="http://www.cnblogs.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_19_244_Open_Text"><span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;3</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />&nbsp;&nbsp;RenderEffects(OPAQUE,PRE_BASEPASS);<br />
</span><span style="color: #008080;">&nbsp;4</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />&nbsp;&nbsp;RenderBasePass(OPAQUE);<br />
</span><span style="color: #008080;">&nbsp;5</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />&nbsp;&nbsp;RenderEffects(OPAQUE,POST_BASEPASS);<br />
</span><span style="color: #008080;">&nbsp;6</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" /><br />
</span><span style="color: #008080;">&nbsp;7</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />&nbsp;&nbsp;RenderEffects(TRANSLUCENT,PRE_BASEPASS);<br />
</span><span style="color: #008080;">&nbsp;8</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />&nbsp;&nbsp;RenderBasePass(TRANSLUCENT);<br />
</span><span style="color: #008080;">&nbsp;9</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />&nbsp;&nbsp;RenderEffects(TRANSLUCENT,POST_BASEPASS);<br />
</span><span style="color: #008080;">10</span><span style="color: #000000;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top" />}</span></span></span></div>
<p>&nbsp;　　将Effect Pass的渲染分为了Pre-Base Pass和Post-Base Pass。例如要进行卡通渲染的钩边，常用的做法是在VS中根据normal进行，这一步放在Pre-Base中进行。而使用Blend方式的渲染动态光源则放在了Post-Base Pass中进行。有时候在同一个阶段可能会存在多个需要渲染的pass，例如动态光照和体积雾的渲染，都是放在Post-Base Pass中进行，这个时候可以给shader加上一个sort key，这样就可以保证体积雾的绘制始终在动态光照绘制之后进行。<br /></p><h2>shader callback functions<br /></h2><p>&nbsp;　　文中提到，在进行每帧渲染前以及每个批次的几何体渲染前分别提供回调函数，以进行渲染前的最后修改。这点倒是和Gamebryo的实现很像，Gamebryo的Render系统的设计中也是提供了这样的一组回调函数，用意也和本文观点一致。</p><p>　　文中举出了2个使用回调函数的例子，一个是进行光照渲染的时候，使用回调函数计算几何体受哪些光影的影响，另一个例子是在渲染毛皮的时候，使用到摄像机的距离选择毛发的shell长度。</p><h2>Reducing Overhead for State Setup<br /></h2><p>&nbsp;　　为了减少渲染状态的切换，文中提出的方法有：对透明以及不透明物体进行排序；在shader对象中提供接口，能够查询shader使用了哪些特殊的纹理，例如光照贴图，法线贴图等等，对这些使用特殊纹理的shader设置需要的渲染状态，否则不进行渲染状态的绘制。另外再进行渲染状态设置前，查询当前的渲染状态，如果和要设置的状态一致的话，就不进行API的调用，毕竟调用改变渲染状态的API耗时还是比较多的。</p><h2>&nbsp;Texture</h2><p style="margin-bottom: 5pt; margin-top: 5pt;">　　<span style="font-size: 10.5pt; font-family: '宋体';">文中提到，为了灵活的使用程序生成的纹理（CPU端生成的过程纹理）和通过美术制作的纹理，使用另一种叫做纹理修改器的技术，纹理修改器是一个函数，接受一个纹理，然后通过某种算法将纹理中的像素转化为想要的效果，例如转化为灰度图，添加alpha通道等等。纹理修改器提供给了使用引擎的人一定的灵活性，用户可以自定义修改器，来进行纹理的修改，在某些运行时的情况下，这种功能是很方便的。</span></p><p>&nbsp;</p><img src ="http://www.cnblogs.com/sssa2000/aggbug/1442497.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47987/" target="_blank">预测：Twitter最可能收购的十家公司</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Depth Bias</title><link>http://www.cnblogs.com/sssa2000/archive/2009/04/22/1441616.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Wed, 22 Apr 2009 13:31:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2009/04/22/1441616.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1441616.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2009/04/22/1441616.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1441616.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1441616.html</trackback:ping><description><![CDATA[<p>在dx中的depth bias要以如下形式调用</p>
<p>&nbsp;</p>
<p>inline DWORD F2DW( float f ) { return *((DWORD*)&amp;f); }</p>
<p>m_pD3DDevice-&gt;SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1));</p>
<p>m_pD3DDevice-&gt;SetRenderState(D3DRS_DEPTHBIAS, F2DW(0.001));</p>
<p>&nbsp;</p>
<p>总之，奇怪的api。</p><img src ="http://www.cnblogs.com/sssa2000/aggbug/1441616.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Planar Shadow</title><link>http://www.cnblogs.com/sssa2000/archive/2009/04/20/1440062.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Mon, 20 Apr 2009 15:46:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2009/04/20/1440062.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1440062.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2009/04/20/1440062.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1440062.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1440062.html</trackback:ping><description><![CDATA[<p>　　相比shadow map 和shadow vol，planar shadow是一种用于简单场景的技术。通过将渲染物体压扁到一个平面上实现。planar shadow也只能渲染在一个平面上的阴影。</p><p>　　planar shadow通过一个矩阵M将物体的每个顶点&#8220;压扁&#8221;，矩阵M的推导过程在http://www.cnblogs.com/Pointer/archive/2004/07/26/27305.html以及http://www.csie.ntu.edu.tw/~r89004/hive/shadow/page_1.html中有很详细的过程。思想是，已知一个顶点Q和投射阴影的方向K以及接受阴影的平面L，求Q点被光线K投影到L上的点P的过程。</p><p><br /> </p><img src ="http://www.cnblogs.com/sssa2000/aggbug/1440062.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47985/" target="_blank">杰克逊悼念仪式或成史上最大规模Web活动</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Instancing 渲染简要</title><link>http://www.cnblogs.com/sssa2000/archive/2009/04/19/1439330.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Sun, 19 Apr 2009 14:43:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2009/04/19/1439330.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1439330.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2009/04/19/1439330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1439330.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1439330.html</trackback:ping><description><![CDATA[<div><h1><span style="font-weight: bold; font-size: 22pt; font-family: '宋体';">Instancing&nbsp;渲染</span></h1><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">在渲染重复的顶点数目很少的小物体时，使用Instancing渲染方法能大量减少对绘制函数的调用，从而达到提高效率的目的。在GPU&nbsp;GEMS2中以及DX9&nbsp;SDK的Sample中对该方法有详细的描述。</span></p><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">在GPU&nbsp;GEMS2中将Instancing渲染技术分成了4个种类：</span></p><p style="margin-left: 21pt; text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: 'Wingdings';">l&nbsp;</span><span style="font-size: 10.5pt; font-family: '宋体';">静态批次</span></p><p style="margin-left: 21pt; text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: 'Wingdings';">l&nbsp;</span><span style="font-size: 10.5pt; font-family: '宋体';">动态批次</span></p><p style="margin-left: 21pt; text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: 'Wingdings';">l&nbsp;</span><span style="font-size: 10.5pt; font-family: '宋体';">顶点常量实例化</span></p><p style="margin-left: 21pt; text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: 'Wingdings';">l&nbsp;</span><span style="font-size: 10.5pt; font-family: '宋体';">几何体实例API批次</span></p><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">书中对4中技术阐述的十分清楚，以下只针对DX&nbsp;SDK中的Sample中的三种做法进行叙述。</span></p><h2><span style="font-weight: bold; font-size: 16pt; font-family: '黑体';">Stream&nbsp;Instancing</span></h2><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">Stream&nbsp;Instancing</span><span style="font-size: 10.5pt; font-family: '宋体';">使用2个VB&nbsp;Buffer，1个IB。一个存放数据的顶点，一个存放所有实例的属性。以绘制1000个立方体为例，一个VB存放一个立方体24个顶点（6个面，每个面4个顶点），一个IB存放36个索引（6个面，每个面2个三角形，每个三角形3个顶点）。另外一个VB存放所有1000个立方体的实例数据，包括：颜色，位置，方位角等等。</span></p><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">设置好各个Buffer后即可渲染。渲染的时候一次只能渲染一个立方体，每次DrawIndexedPrimitive之前都需要调用SetStreamSource设置实例在第二个VB中的偏移量即可。显然对于每个物体都调用DrawIndexedPrimitive的做法肯定对效率影响很大。</span></p><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">这种方法算是一种比较静态的方法，不过和GPU&nbsp;GEMS2中的静态方法不太一样。GPU&nbsp;GEMS2中的静态方法只使用一个大的VB和一个大的IB，这个VB中存放转换好的几何实例信息，IB中存放每一个实例的索引，然后使用一个DrawIndexedPrimitive绘制出所有的几何体。这种方法需要耗费大量的储存器且不能支持骨骼运算，对CPU的消耗十分的大。</span></p><h2><span style="font-weight: bold; font-size: 16pt; font-family: '黑体';">Shader&nbsp;Instancing</span></h2><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">Shader&nbsp;Instancing需要一个大的VB和一个大的IB以容纳所有的实例的顶点和索引。另外几何体实例的所有信息存放在系统的内存中。和前面的方法不同的是，并不需要在创建VB的时候将几何体实例的信息Lock到VB中去，而是在渲染的时候通过顶点常量传递进去。由于顶点常量的个数有限，所以一批几何体可能需要渲染几次才能全部完成。</span></p><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">这个方法和GPU&nbsp;GEMS2中的顶点常量实例化的方法很相似，不过由于GPU&nbsp;GEMS2中的这个方法将所有的顶点常量拿来做Instancing运算，无法进行骨骼运算。为了解决这个问题DX&nbsp;SDK中的Sample中并没有使用全部的顶点常量。</span></p><h2><span style="font-weight: bold; font-size: 16pt; font-family: '黑体';">HW&nbsp;Instancing</span></h2><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">这种方法是DX&nbsp;SDK里面强烈推荐的方法，不过需要硬件支持vs3_0。前面2种方法都只是需要硬件支持vs1_1即可。</span></p><p style="text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">HW&nbsp;Instancing的方法和前面说的Stream&nbsp;Instancing的方法如出一辙，所不同的是，HW&nbsp;Instancing使用了DX&nbsp;SDK提供的API：SetStreamSourceFreq()。通过这个API，就可以不需要在渲染的时候指定实例在VB中的偏移量，所以使用这个方法可以自动的将所有的实例使用一个</span><span style="font-size: 10.5pt; font-family: '宋体';">DrawIndexedPrimitive绘制完毕。</span></p><p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';"><br /></span></p></div><img src ="http://www.cnblogs.com/sssa2000/aggbug/1439330.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47984/" target="_blank">《商业周刊》:Mozilla的志愿者开发模式被复制</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>球面环境贴图</title><link>http://www.cnblogs.com/sssa2000/archive/2009/03/22/1419205.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Sun, 22 Mar 2009 13:21:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2009/03/22/1419205.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1419205.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2009/03/22/1419205.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1419205.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1419205.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;相比立方体贴图，球面贴图的结果虽然不很精确，但是只需要一张贴图。这个时候球面环境贴图还是有用武之地的。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;随便用搜索引擎在网上找了下，基本上没发现关于球面环境贴图的内容，本来想找个简单的shader直接来用的，没想到的是找了半天也没找到，于是只能自己动手写了。以下文章是我参考了一些资料加上我自己的理解写成的，如果有错误的地方还望大家指正。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;环境映射是一种近似，它基于这样的假设：相对于光洁物体的大小而言，环境中的物体离光洁物体很远，也就是说，将一个很小的光洁物体放在大房间中。对于物体表面上的点，假设有一条从眼睛到该点的光线，这条光线被反射出去的方向决定该点的颜色。在一个二维纹理图中对各个方向的颜色进行编码，相当于将一个光洁度非常高的球体放在环境中央，然后在很远的地方用带长焦镜头的相机拍摄球体。从数学上说，镜头的焦距为无限长，相机位于无穷远处。因此，需要进行编码是纹理图的内切圆形区域，该圆形区域外的纹理值没有影响，因为进行环境印射时没有使用它们。（摘抄自OpenGL红宝书）
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据这段来自红宝书中的文字，在一个环境中生成球面贴图的时候，由于环境相对于球体而言无限大，所以可以把球体看成是一个单位球体。同时，有由于相机位于无限远处，所以相机到球体上的各个点的向量可以看成是相互平行的。
<p><a href="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image1_2.png">
<div align="center"><img title="wps_clip_image1" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="171" alt="wps_clip_image1" src="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image1_thumb.png" width="244" border="0" /></div>
</a>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;于是很容易的想到：
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、生成视线向量V。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、根据顶点法线生成反射向量R。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、查找R和球面的交点。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4、根据交点求出UV坐标。
<p><a href="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image2_2.png">
<div align="center"><img title="wps_clip_image2" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="182" alt="wps_clip_image2" src="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image2_thumb.png" width="192" border="0" /></div>
</a>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R可以很容易的求出。为了求出UV，需要求出R和球面的交点E在球面的位置。这个时候回到生成球面纹理图时候的场景，由于球面是单位球面，利用单位球面的一个性质：球面上的点的归一化法线就是该点在球面上的位置。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们只需要知道在生成球面纹理图的时候，在球面上相同的点，当反射向量也为R的时候该点的法线为多少即可。
<p><a href="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image3_2.png">
<div align="center"><img title="wps_clip_image3" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="224" alt="wps_clip_image3" src="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image3_thumb.png" width="243" border="0" /></div>
</a>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据向量加法原则，法线是视线向量和反射向量的和。为了模拟视点位于无限远处的情况，可以假象生成球面纹理图的过程是位于View Space，这样的话，Eye Vec就总是(0,0,1)。于是只需要把反射向量也转化到View Space就可以得出球面的法线向量。
<p><a href="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image4_2.png">
<div align="center"><img title="wps_clip_image4" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="205" alt="wps_clip_image4" src="http://www.cnblogs.com/images/cnblogs_com/sssa2000/WindowsLiveWriter/abeefd8887f0_12C4E/wps_clip_image4_thumb.png" width="244" border="0" /></div>
</a>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;还剩下最后一个问题，求出来的法线每个分量的值域是[-1,1]，而uv要求的值域是[0,1]，所以需要转换一下。以下是关键的VS代码片段：
<p>&nbsp;&nbsp;
<p>&nbsp;</p>
<div class="cnblogs_code"><img id="Code_Closed_Image_212348" onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_212348').style.display='none'; document.getElementById('Code_Open_Image_212348').style.display='inline'; document.getElementById('Code_Open_Text_212348').style.display='inline';" height="16" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" width="11" align="top"><img id="Code_Open_Image_212348" style="display: none" onclick="this.style.display='none'; document.getElementById('Code_Open_Text_212348').style.display='none'; getElementById('Code_Closed_Image_212348').style.display='inline'; getElementById('Code_Closed_Text_212348').style.display='inline';" height="16" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top"><span class="cnblogs_code_Collapse" id="Code_Closed_Text_212348">Code</span><span id="Code_Open_Text_212348" style="display: none"><br />
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">world&nbsp;normal&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;float3&nbsp;normalWorld</span><span style="color: #000000">=</span><span style="color: #000000">OUT.WorldNormal;&nbsp;<br />
</span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">world&nbsp;space&nbsp;eye&nbsp;vec&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;float3&nbsp;eyeVecWorld</span><span style="color: #000000">=</span><span style="color: #000000">OUT.WorldView;&nbsp;<br />
</span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">world&nbsp;reflect&nbsp;vec&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;float3&nbsp;reflectWorld</span><span style="color: #000000">=</span><span style="color: #000000">reflect(eyeVecWorld,normalWorld);&nbsp;<br />
</span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">eye&nbsp;space&nbsp;relect&nbsp;vec&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;float3&nbsp;reflectView</span><span style="color: #000000">=</span><span style="color: #000000">mul(reflectWorld,matViewIT);&nbsp;<br />
</span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">unit&nbsp;sphere&nbsp;normal&nbsp;in&nbsp;view&nbsp;space&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;float3&nbsp;SphereNormal</span><span style="color: #000000">=</span><span style="color: #000000">float3(</span><span style="color: #800080">0</span><span style="color: #000000">,</span><span style="color: #800080">0</span><span style="color: #000000">,</span><span style="color: #800080">1</span><span style="color: #000000">)</span><span style="color: #000000">+</span><span style="color: #000000">reflectView;&nbsp;<br />
</span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;SphereNormal</span><span style="color: #000000">=</span><span style="color: #000000">normalize(SphereNormal);&nbsp;<br />
</span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;float2&nbsp;newUV</span><span style="color: #000000">=</span><span style="color: #000000">SphereNormal.xy;&nbsp;<br />
</span><span style="color: #008080">24</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">25</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;newUV.x</span><span style="color: #000000">=</span><span style="color: #000000">newUV.x</span><span style="color: #000000">*</span><span style="color: #800080">0.5</span><span style="color: #000000">+</span><span style="color: #800080">0.5</span><span style="color: #000000">;&nbsp;<br />
</span><span style="color: #008080">26</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">27</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;newUV.y</span><span style="color: #000000">=</span><span style="color: #000000">newUV.y</span><span style="color: #000000">*</span><span style="color: #800080">0.5</span><span style="color: #000000">+</span><span style="color: #800080">0.5</span><span style="color: #000000">;&nbsp;<br />
</span><span style="color: #008080">28</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">29</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;OUT.UV</span><span style="color: #000000">=</span><span style="color: #000000">newUV;&nbsp;<br />
</span><span style="color: #008080">30</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">31</span>&nbsp;</span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后记：写这篇文章以前，我参考过DirectX SDK中文档的内容，文档中说，只需要把顶点的法线转换到Camera Space然后除以2加上0.5即可。我使用这个方法在FxComposer中实验，没有得到正确的结果，我不知道是否是哪写错了。SDK的文档中也没有详细说明这个方法的来龙去脉，不知道有没有知道的朋友。 </p>
<img src ="http://www.cnblogs.com/sssa2000/aggbug/1419205.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47977/" target="_blank">Mono 的Virtual PC 虚拟机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>MaxScript 心得1</title><link>http://www.cnblogs.com/sssa2000/archive/2008/09/01/1281626.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Mon, 01 Sep 2008 15:28:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2008/09/01/1281626.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/1281626.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2008/09/01/1281626.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/1281626.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/1281626.html</trackback:ping><description><![CDATA[<p>1、当你在 maxscript中的rollout中注释掉一个控件的时候，那么当你再运行脚本，与该控件有关的事件的代码将消失！</p>
<p>&nbsp;</p>
<p><span style="font-size: 24pt">2、</span><span style="font-size: 24pt">如何使用dotnet 的ListView?</span>&nbsp;</p>
<p>&nbsp;</p>
<p>声明：&nbsp;dotNetControl lv_objects "System.Windows.Forms.ListView" pos:listBoxPos width:485 height:459</p>
<p>&nbsp;</p>
<p>添加项：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local li = dotNetObject "System.Windows.Forms.ListViewItem" (submat.MaterialName)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;li.ImageIndex =0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lv_objects.Items.Add li </p>
<p>&nbsp;</p>
<p>on lv_objects DoubleClick arg do<br />
&nbsp;(<br />
&nbsp;&nbsp;--取0是因为不允许多选 所以直接取0<br />
&nbsp;&nbsp;local doubleItemIdx=lv_objects.SelectedIndices.item[0]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... ...<br />
&nbsp;&nbsp;)</p>
<img src ="http://www.cnblogs.com/sssa2000/aggbug/1281626.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47970/" target="_blank">19岁天才黑客发布首个iPhone 3GS破解软件</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Export利器：IGame</title><link>http://www.cnblogs.com/sssa2000/archive/2007/05/28/762787.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Mon, 28 May 2007 09:31:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2007/05/28/762787.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/762787.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2007/05/28/762787.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/762787.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/762787.html</trackback:ping><description><![CDATA[<p>古人云：君子生非异也，善假于物也<br>数据导出是一个繁琐的工作，于是，有了IGame这个解脱程序员的东西：<br><br>&nbsp; </p>
<p>&nbsp;</p>
<h2><span>关于</span><span>IGame</span></h2>
<p>&nbsp;</p>
<p><span>IGame</span><span>是</span><span>Max</span><span>提供给游戏开发的一个用于导入导出的接口。在</span><span>Max</span><span>的</span><span>help</span><span>里面这个东西叫做</span><span>3ds Max Data Ex<st2:rtx w:st="on">change</st2:rtx> Interface</span><span>。有了这个接口，可以大大的简化导入导出工作的工作量。</span></p>
<p><span>如果有经历过用</span><span>MAX SDK</span><span>导出关键帧动画以及骨骼动画，</span><span>Skin</span><span>，</span><span>Modifier</span><span>等等的经历的话，我想肯定会记忆深刻。</span><span>IGame</span><span>的作用就是把复杂的</span><span>Max</span><span>的概念简化，封装。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2><span>建立</span><span>IGame:</span></h2>
<p><span>IGameScene * m_pIgame= GetIGameInterface()</span></p>
<p>&nbsp;</p>
<h2><span>坐标系：</span></h2>
<p><span>前面我提到的导出的文章都没有提这个问题，所有的坐标都是用的</span><span>MAX</span><span>本身的坐标系，及</span><span>Z</span><span>轴向上。在游戏中坐标系可能千奇百怪，</span><span>IGame</span><span>考虑到这点提供了指定坐标系的功能：</span></p>
<p align=left><span>IGameConversionManager * cm = GetConversionManager();</span></p>
<p align=left><span>cm-&gt;SetCoordSystem(IGameConversionManager::IGAME_D3D);</span></p>
<p align=left><span>m_pIgame-&gt;InitialiseIGame(true); </span></p>
<p><span>其中</span><span>IGAME_D3D</span><span>就是指定的坐标系，同样也可以自定义坐标系：</span></p>
<p><span>&nbsp; UserCoord WhackySystem = { </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; 1,&nbsp;&nbsp; //Right Handed </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; 1,&nbsp;&nbsp; //X axis goes right </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; 4,&nbsp;&nbsp; //Y Axis goes in </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; 3,&nbsp;&nbsp; //Z Axis goes down. </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp; //U <st1:state w:st="on"><st1:place w:st="on">Tex</st1:place></st1:state> axis is left </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; 1, //V <st1:place w:st="on"><st1:state w:st="on">Tex</st1:state></st1:place> axis is Down </span></p>
<p><span>&nbsp;&nbsp; };&nbsp;&nbsp; </span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp; IGameConversionManager * cm = GetConversionManager(); </span></p>
<p><span>&nbsp;&nbsp; cm-&gt;SetUserCoordSystem(WhackySystem); </span></p>
<p>&nbsp;</p>
<h2><span>IGame</span><span>要点：</span></h2>
<p><span>GetTopLevelNodeCount</span><span>：获得顶级的</span><span>Node</span><span>数目，不包括</span><span>Root</span><span>。</span></p>
<p><span>GetRootMaterialCount</span><span>：获得所有的材质数目</span></p>
<p><span>GetTopLevelNode(i)</span><span>：获得指定</span><span>Node</span></p>
<p><span>GetIGameObject()</span><span>：获得</span><span>Node</span><span>中包含的</span><span>Object</span></p>
<p><span>GetLocalTM()</span><span>：获得</span><span>Node</span><span>的矩阵</span></p>
<p>&nbsp;</p>
<p><span>IGameMesh </span><span>：：</span><span>GetVertex(i)</span><span>：获得顶点</span></p>
<p><span>IGameMesh </span><span>：：</span><span>GetFace(i)</span><span>；获得面</span></p>
<p><span>IGameMesh </span><span>：：</span><span>GetNormal(i)</span><span>：获得法线</span></p>
<p><span>至于其他就依次类推了，从函数的命名，到概念的简化，无疑都比原始的</span><span>MAXSDK</span><span>进步了很多。有了</span><span>IGame</span><span>接口，大大减轻了程序员的负担，我相信没有哪个愿意把大把的时间花在数据的导入导出上。</span></p>
<p>&nbsp;</p>
<p><span>花了几十分钟简单的试用了一下</span><span>IGame</span><span>写了个小小的导出插件，只导出了顶点，面，材质，法线以及矩阵，感觉基本上没什么阻碍。不过</span><span>IGame</span><span>最大的功能还是用在骨骼动画，关键帧动画上面，仅仅只是简单的几何体导出并不能体现出</span><span>IGame</span><span>的功效。</span></p>
<p>&nbsp;</p>
<p><span>最后还是附上代码和工程吧。不得不提示一下，由于种种曲折的原因，我这个工程是在</span><span>MAX8 SDK</span><span>和</span><span> MAX8</span><span>下</span><span> </span><span>完成的，其间省略上千字曲折的经历，不过在</span><span>MAX9</span><span>下应该可以通过编译。编译完成后，记得在</span><span>Max </span><span>中选择</span><span>Export Selected</span><span>而不是试用</span><span>Export</span><span>。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<a href="http://www.cnblogs.com/Files/sssa2000/TestIGame1.rar">DownLoad Source</a>
<img src ="http://www.cnblogs.com/sssa2000/aggbug/762787.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47969/" target="_blank">新浪邮箱大本营粉墨登场！Sina.cn开放注册</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>MAX Script Export/Import</title><link>http://www.cnblogs.com/sssa2000/archive/2007/05/18/751800.html</link><dc:creator>大河马和小魔鱼</dc:creator><author>大河马和小魔鱼</author><pubDate>Fri, 18 May 2007 10:08:00 GMT</pubDate><guid>http://www.cnblogs.com/sssa2000/archive/2007/05/18/751800.html</guid><wfw:comment>http://www.cnblogs.com/sssa2000/comments/751800.html</wfw:comment><comments>http://www.cnblogs.com/sssa2000/archive/2007/05/18/751800.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/sssa2000/comments/commentRss/751800.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sssa2000/services/trackbacks/751800.html</trackback:ping><description><![CDATA[摘要: 2个工作日写了一套简单的Export/Import插件一直对MAX的 Script感到很好奇说说使用的感受吧。首先，如果要使用这套Script那么 首先会陷入到庞大的MAX的概念的汪洋大海之中MAX中很多概念不同于平常熟知的 RealTime里面的思想例如，MAX中的纹理坐标，每个顶点都有一对UV 这个很正常但是同时 MAX对每个Face也保存了UV，这是因为MAX中的 每个Face都有可能是不同&nbsp;&nbsp;<a href='http://www.cnblogs.com/sssa2000/archive/2007/05/18/751800.html'>阅读全文</a><img src ="http://www.cnblogs.com/sssa2000/aggbug/751800.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47968/" target="_blank">IE市场份额首次跌破60%</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item></channel></rss>