3D图形学笔记 – 法向量变换
7今天碰见一个需求,要将一个世界空间的光方向向量变换到屏幕空间中,再与屏幕空间的法向计算光照,遇到一个一直以来都未曾仔细想过的问题:
为什么对于法向量,需要用(M-1)T进行变换呢?
查了一下《Game Engine Architecture》和 《Mathematics for 3D Game Programming and Computer Graphics》,前者只是简单的介绍了一下Normal必须要这样变换,给了个参考链接到后者。
后者在这里有电子版可以看。
表示方向的向量在坐标系变换中需要采用(M-1)T,其原因如下,经过矩阵M变换之后,由于M可能不是一个正交矩阵,向量在经过变换之后可能失去了原有的性质——在变换前,法线与面垂直,但是变换之后失去了与面垂直的特性。
我们定义定点的切向量T,我们知道N与面垂直,由于切向量是在面上,我们知道N dot T的结果必然为0,如果要对N做变换,我们需要保证这个点积操作(N dot T)在变换前和变换后都得到一样的结果,即是0。
现在假设有一个变换矩阵M对定点做变换,由于T是根据顶点与UV计算出来的,我们可以将M直接应用到T上,得:
T’ = T M
对应的,我们假定有一个变换矩阵G对N做变换,可以保持N dot T的性质不变:
N’ = N G
我们有: N dot T == N’ dot T’
那么就有:
(N G) dot (T M) = (N G) (T M)T = N G MT TT
如果要求: N dot T == N G MT TT <*>
由于 N dot T 等于 N TT ,所以 <*>式成立当且仅当 M GT == Identity
也就意味着: G等于 (M-1)T
注意到,如果M是正交矩阵,那么M-1 = MT,也就意味着(M-1)T就等于M。
因此,如果我们确知矩阵M是正交的,就可以省去这一步。但是如果M非正交,或者未必正交,例如投影矩阵,或者是xyz轴不一致的缩放,那么就需要做这一步。
什么时候应用之?
通常情况下,只要需要将Normal的坐标系进行变换,由于矩阵可能非正交,我们都不应当直接乘变换矩阵本身,而是应当乘以其逆矩阵的转置。(与变换顶点不同)
参考:
http://book.douban.com/subject/2619205/
http://book.douban.com/subject/3745143/
http://dev.gameres.com/Program/Visual/3D/3Dfaxiangliang.pdf
http://hi.baidu.com/game_developer/blog/item/2ef0025e679a4648faf2c0ee.html
[译]每个软件开发者必须绝对至少需要了解的Unicode和Character Sets的知识(没有借口!)
1每个软件开发者必须绝对至少需要了解的Unicode和Character Sets的知识(没有借口!)
原文:http://www.joelonsoftware.com/articles/Unicode.html
by Joel Spolsky
译windam
2003.10.8 星期三
你是否曾经对那个神秘的Content-Type标记感到不解?
译注:每个HTML页面的head块中都可能包含一个Content-Type标记,例如:
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
你知道这东西应该被放到HTML里,但是你从来都没有确切得弄清楚它到底应该是什么?
你是否曾经收到过你朋友从Bulgaria发来的Email,它的主题行是“???? ?????? ??? ????”?
当我发现还有那么多的软件开发者并没有真正领会关于字符集(Character sets),编码(encoding),Unicode以及相关知识的时候,我非常失望。几年前,FogBUGZ的一个beta测试者对于它是否能处理收到的日语邮件感到疑惑。日语?他们有日文的Email?我不知道。但当我仔细研究我们用来解析MIME email的商业ActiveX控件时,我们发现它恰恰正好对字符集做了完全错误的处理,于是,为了撤销控件中所做的错误转换,并正确的重新处理,我们不得不编写修正它的补救代码。而当我研究另一个商业库的时候,发现它有一样的完全错误的字符代码实现。我和那个代码库的开发者通信,发现他的想法是,他们“不能(对字符集)做任何事(正确的处理)”。就像很多程序员一样,他只是祈祷着,这一切麻烦事都可以被吹走。
但事实上不会!当我发现流行的web开发语言PHP几乎完全的忽略了字符编码的问题,没心没肺的用了8bit字符,这种傻逼的行为让开发好的国际化web应用变得几乎不可能的时候,我想,我受够了。
我在此声明:如果你是一个工作在2003年或之后的程序员(此文写于2003年10月),并且你还没有对字符,字符集,编码和Unicode有所了解,而且你被我我抓住了,我会罚你在潜艇里剥6个月的洋葱皮!我发誓我会这样做的!
此外还有一事:
这真的没那么难
在本文中,我将会告诉你每个在工作中的程序员所应知道的。所有关于“plain text = ascii = character就是8bit”的知识不仅仅是错误的,而且是错得令人绝望。如果你依然像这样编程,那么你真不比一个不信基因的医生好到哪里去。在读完本文之前,请不要再编写任何一行代码!
在我开始之前,我应该提醒你,如果你是那些少数懂得国际化的知识的程序员,那么你会发现我讨论的整个话题有那么一点过于简化。我仅仅只是希望在此设立一个门槛,使得每个人都理解关于字符编码究竟都发生了些什么事情,并有希望使写出的代码可以在任意语言下正常工作,而非仅仅只能工作在在不带方言词汇的英语环境中。我还要再提醒你,想创建可以在国际化语言环境下工作的软件,字符处理仅仅只是很小的一部分工作,但是我一次只能写一个主题,所以本文就是关于字符集的。
Crysis 地形渲染技术剖析——材质与LOD
10材质
Crysis地形的一个最重要的特色是它的地表材质系统。当进入到一定距离之后,可以看到非常精细的地表材质,包括Bump Mapping,Parallax Occlusion Mapping,有了材质系统的支持,Crysis的地形相较基于传统的Texture Splatting的地形可以呈现出令人惊叹的细节。
在POM技术支撑下的Crysis地形:
基于Texture Splatting技术的地形:
Crysis的地表材质技术的原理如下:
渲染包括两个步骤,首先基于颜色图和法线图,绘制基本的地形色彩与明暗,这一遍渲染结果主要用于远处地形。然后会针对不同材质,将细节通过AlphaBlend融合到之前的渲染结果上,材质细节通常只在离视野较近的区域内才渲染,因此第二个步骤的耗费并不多,根据实际情况,每帧中大约会有从一百到数百个不等的细节层Mesh被绘制。 (more…)
关于地形渲染技术的杂谈
4地形是3D游戏中不可或缺的基础部分,特别是对于要表现室外场景的游戏来说。随着图形硬件的发展,地形渲染技术也经历了若干变迁。主要包括几个方面:LOD,光照和阴影,材质表现。由于本人的时间精力有限不可能面面俱到,所以只能是浅谈辄止,粗浅的叙述一下相关的技术和一些思考,欢迎交流指正。
关于LOD
早些年,由于图形硬件的瓶颈在于顶点和三角形处理上,因此发展出一批目的在于尽可能减少顶点和三角形数量的算法,如ROAM。后来随着显卡性能的提升,渲染效率的瓶颈逐渐变成了总线上的数据传输速率,地形渲染随之演变成尽可能将预计算好的数据存储于显卡上,从而避免每帧传递数据,如Geo-Mipmapping。还有后续的算法在此基础上继续改进,如Chunked LOD。
除此之外,地形LOD算法还需要处理的问题包括如何消除LOD级别改变时发生的视觉上的突变。一种常见的方法就是通过Morphing。不过不知是出于效率还是工程上的考虑,Crysis的地形上并没有做morphing。
再后来,随着Shader Model 3.0中增加了Vertex Texture访问以及对Instancing的支持,地形渲染技术则有了更多的选择,例如通过VertexTexture技术,可以在VertexShader中算顶点,而Instancing技术更进一步减少了数据传输量,进一步简化了CPU端的计算和数据传输。
参考:CDLOD,这个作者正在基于DX11实现他的下一个版本的CDLOD,将会包含下面要说的Tessellation技术。
到了DX11,新引入的Tessellation技术则让引擎开发者拥有了将整个地形渲染完全搬到显卡上去做的能力。如果说SM3.0中我们只是在硬件上动态生成所需的地形顶点,那么到了DX11中,我们就可以在硬件上实现LOD了,我们可以GPU上决定每个Patch应该有多细密的网格,并且在GPU上处理好和邻接Patch的接缝问题。关于这个话题可以参考GPU Pro2中的Terrain And Ocean Rending with Hardware Tessellation。
这意味着到DX11普及的时候,以往的那些在用于CPU端计算LOD索引的很多算法,都不再被需要了。当然,上述算法中产生的核心思想仍然会继续起作用——例如利用四叉树做地形的数据管理,例如如何在LOD改变时避免视觉上看到跳变等等。 (more…)
自动构建二:CruiseControl.NET配置基础
0在软件工程领域,CruiseControl是一个基于Java的持续集成框架。它包含了大量与持续集成有关的功能,如:邮件通知,Ant自动构建,以及支持多种源码管理工具。可以利用Web页面观察当前和以往的构建流程。它允许我们对软件开发中的很多流程进行持续的自动化控制。
CruiseControl是一个自由,开源软件,使用BSD类型的license。最早的时候,该软件是由ThoughtWorks公司的员工开发出来用于该公司自身内部项目的,随后则变成了一个独立的应用软件。
CruiseControl.NET是CruiseControl的.NET版本。还有一个Ruby版本的CruiseControl,被称为CruiseControl.rb。
对于使用Windows平台,以及Visual Studio集成开发环境的团队来说,使用CruiseControl.NET的好处在于他整合了MSBuild,NAnt,VSS等微软平台下常用的软件开发中的工具,并且非常易于在.NET平台下对他的功能进行扩展。