02 2011 档案
在场景中添加光线——在Deferred Shading引擎中添加阴影能力
摘要:问题 虽然你已经掌握了基本的计算机实时光照,但你应该注意到光源还没有投射出阴影。这是因为pixel shader是基于光线与法线的夹角计算光照的。直到现在,pixel shader还没有考虑到光线与像素间的物体。 阴影映射(shadow mapping)技术在我的网站(http://www. riemers. net)的第三个系列中加以介绍,这个技术可以对一个光源生成正确的阴影,但是你想用de... 阅读全文
posted @ 2011-02-14 15:03 AlexCheng 阅读(434) 评论(0) 推荐(0)
在场景中添加光线——使用Deferred Shading在场景中添加多光源
摘要:问题 你想在场景中同时使用多个光源。 一个方法是使用多个光源绘制场景并将每个光源的影响混合在一起。当添加一个新光源时场景需要整个被重新绘制,这个方法无法拓展,因为帧频率会随着光源的增加按比例下降。 解决方案 本教程中将使用一个完全不同的方法。你将3D场景绘制到一张2D纹理中。然后,为这张纹理中的所有像素计算所有光源的光照。这意味着你要在2D纹理上进行逐像素的处理,但只需绘制3D场景一次。 ... 阅读全文
posted @ 2011-02-14 15:01 AlexCheng 阅读(396) 评论(0) 推荐(0)
在场景中添加光线——添加HLSL镜面高光
摘要:问题 你想使用自定义的HLSL effect在场景中添加镜面高光。镜面高光是位于反光位置的高亮度区域,如图6-11所示。 解决方案 下面的讨论将帮助你判断哪个像素具有高光分量。 图6-11的左图显示了一条光线L,从光源指向三角形中的一个像素。在左图中还显示了 eye向量,从相机指向像素。如果L的反射向量与E相同,那么这个像素就有一个高光分量。 图6-11 使用靠近eye向量的光线... 阅读全文
posted @ 2011-02-14 14:52 AlexCheng 阅读(487) 评论(0) 推荐(0)
在场景中添加光线——使用HLSL定义聚光灯
摘要:问题 前面教程中定义的点光源从一个点发出四面八方的光。你想定义一个聚光灯,它与点光源很很像,但光线只照亮一个圆锥区域,如图6-10。 图6-10 定义一个聚光灯的变量 解决方案 在pixel shader中,判断当前像素是否在光照圆锥中,这可以通过将光线方向和圆锥方向进行点乘做到。 工作原理 开始的代码与前面的教程中的是一样的。因为聚光灯比点光源需要设置的东西更多,你需要将下列X... 阅读全文
posted @ 2011-02-14 14:50 AlexCheng 阅读(400) 评论(0) 推荐(0)
在场景中添加光线——添加HLSL逐像素光照
摘要:问题 如教程6-3所示,要获得最好的光照效果应该使用逐像素光照,特别是对那些由大三角形构成的曲线的情况中。你想使用自己的effect添加逐像素光照。 解决方案 前两个教程中,你在每个顶点中计算明暗值(shading value,也可以翻译成着色值)。三角形三个顶点的明暗值会进行线性以获取每个像素的明暗值。 在逐像素光照中,你想对三个顶点的法线进行插值以获取每个像素的法线,这样就可以基于每个... 阅读全文
posted @ 2011-02-14 14:48 AlexCheng 阅读(412) 评论(0) 推荐(0)
在场景中添加光线——使用HLSL定义点光源
摘要:问题 直到现在,你都是用单向光照亮场景,这对在3D世界中添加阳光是很有用的。但很多情况中,你还需要一个从点发出的光线,例如一个探照灯或爆炸。这种光源叫做点光源。 解决方案 将点光源的3D位置从XNA项目传送到XNA effect中。对每个顶点,计算光源指向顶点的方向,并将这个方向作为光线方向。知道了光线方向就可以像以前一样继续了。 工作原理 在. fx文件中,使用下列代码替换xLight... 阅读全文
posted @ 2011-02-14 14:47 AlexCheng 阅读(541) 评论(0) 推荐(0)
在场景中添加光线——添加HLSL Vertex Shading
摘要:问题 使用你配置好的光照,BasicEffect可以很好地绘制场景。但是,如果你想定义一些更酷的效果,首先要实现的就是正确的光照。 本教程中,你将学习如何编写一个基本的HLSL effect实现逐顶点光照。 解决方案 传递每个顶点的3D位置和法线到effect中。显卡上的vertex shader需要对每个顶点做两件事。 首先,当绘制3D世界时,总是要使用世界矩阵,视矩阵和投影矩阵将3D... 阅读全文
posted @ 2011-02-14 14:39 AlexCheng 阅读(584) 评论(0) 推荐(0)
在场景中添加光线——在反光表面添加镜面高光
摘要:问题 就算开启了逐像素明暗,有些金属或闪光表面仍显得有点暗淡。在现实生活中,当观察诸如金属、玻璃或一些塑料时,你会发现某些区域的反光非常强烈。这样的区域如图6-6的虚线圆圈所示。这些高亮的区域叫做镜面高光(specular highlights)。 图6-6 镜面高光 解决方案 和逐像素光照一样,你只需简单地告知BasicEffect创建镜面高光就可以开启它。 注意:镜面高光只... 阅读全文
posted @ 2011-02-14 14:36 AlexCheng 阅读(347) 评论(0) 推荐(0)
在场景中添加光线——给光线添加更高的细节:逐像素光照
摘要:问题 在前两个教程中,是在每个顶点中计算明暗程度,对三角形的每个像素需要对这个值进行插值。所以这叫做逐顶点光照(per-vertex lighting,又叫做高洛德着色,高洛德浓淡Gouraud shading)。 在某些情况中,逐顶点光照没不能产生最好的结果。特别是使用大三角形或有锐利的边缘或两者都有时,往往得不到想要的结果。 举例说明,如图左边是一个有三个面的立方体。图的右边表示共享的法... 阅读全文
posted @ 2011-02-14 14:32 AlexCheng 阅读(328) 评论(0) 推荐(0)
在场景中添加光线——在顶点间共享法线
摘要:问题 在前面的教程中,你学习了如何根据法线数据使三角形获取正确的光照。 但是,盲目地将这个方法施加到所有三角形中往往得不到最好的效果。 如果三角形的每个顶点具有相同的法线方向,那么光照是一样的,所有像素会获得同样的光照。如果两个相邻三角形(不在同一平面)也是如此施加光照,那么一个三角形的所有像素获得同样的光照,另一个三角形的所有像素获得另一个光照。这会导致很容易地可见看见两者的边界,因为两个... 阅读全文
posted @ 2011-02-14 14:28 AlexCheng 阅读(374) 评论(0) 推荐(0)
在场景中添加光线——定义法线和使用BasicEffect
摘要:问题 没有正确地光照,场景会缺乏真实感。在某些情况中,如果光照不正确3D效果会完全消失。 例如,一个有着不透明颜色的球,如果没有光照,球的所有像素将会是相同的颜色,在屏幕上看起来像一个平面的盘子。当光照正确时,球上面对光照的部分比其他部分的颜色更亮,使球看起来是一个真实的3D对象。 解决方案 在计算机图形学中,所有的3D对象都是由三角形组成的。你想使三角形对应入射光可以正确地被照亮。图6-... 阅读全文
posted @ 2011-02-14 14:25 AlexCheng 阅读(465) 评论(0) 推荐(0)
在场景中添加光线——概述
摘要:给场景添加光照听起来很简单:设置3D世界中物体的位置,定义光源的位置就可以了。但是,虽然看起来让显卡实现光照很简单,其实不是。 对物体的每个表面,显卡需要计算表面接受光照的数量,这个光照数量是基于光线方向和表面法线方向的夹角的。幸运的是,XNA框架拥有BasicEffect,它可以为你进行所有的计算。本章第一部分解释如何使用BasicEffect给场景添加光照。 但是,如它的名称所示,Basi... 阅读全文
posted @ 2011-02-14 14:22 AlexCheng 阅读(220) 评论(0) 推荐(0)
处理顶点——为赛道创建顶点
摘要:问题 给定三维空间中的一个基点集合,你想创建一条通过所有点的赛道。你想创建顶点,计算法线,在赛道上贴上纹理。 解决方案 你可以经过几个步骤从3D点的集合创建一个赛道。首先使用教程5-16中讨论的3维Catmull-Rom插值生成位于你预定义的点之间的样条上的额外点。第一步可用图5-33中的从“a”指向“b的箭头表示”。 基于这些点无法定义三角形。对样条上的每个点,你要计算垂直于样条的方向,... 阅读全文
posted @ 2011-02-14 14:17 AlexCheng 阅读(315) 评论(0) 推荐(0)
处理顶点——在3D空间中使用Catmull-Rom插值生成额外的顶点
摘要:问题 给定一个3D空间中的点序列,你想构建一个漂亮的,光滑曲线可以通过所有这些点。图5-32中的黑色曲线显示了这样条曲线,灰色线段表示使用简单的线性插值的情况,可参见教程5-9。 图5-32 通过5点的Catmul-Rom样条(spline) 这在许多情况中是很用的。例如,你可以用它产生一个赛道,可参见教程5-17。当相机非常靠近模型或地形时,你可以使用Catmull-Rom插值产... 阅读全文
posted @ 2011-02-14 14:14 AlexCheng 阅读(869) 评论(0) 推荐(0)
处理顶点——在3D世界添加水面
摘要:问题 你可以在CPU上计算所有波的3D位置,但这样做会消耗大量的资源,每帧向显卡发送大量的数据是不可接受的。 解决方案 在XNA程序中,你只需创建一个三角形组成的平面网格。这和创建地形类似,在教程5-8中已经解释过了,只不过这次网格是平的,你将需一次性地把这些数据传递到显卡。当绘制网格时,vertex shader会在网格上添加水波,pixel shader添加反射,这一切都在GPU中完成,... 阅读全文
posted @ 2011-02-14 14:12 AlexCheng 阅读(598) 评论(0) 推荐(1)
处理顶点——通过切线空间的凹凸映射添加逐像素细节
摘要:问题 虽然前一个教程中具有不变法线的平面物体工作良好,但如果对一个曲面或有转角的表面进行凹凸映射仍会遇到麻烦。 主要问题是包含在凹凸映射中的偏离法线是在切线空间中的,这意味着它与默认法线有联系。 为了形象化的说明这个问题,设想绘制一个圆柱体,如图5-30所示。左图表示圆柱体顶点的默认法线。 图5-30 圆柱体的默认法线和凹凸映射法线 想象一下你想对这个圆柱体使用凹凸映射。例如,... 阅读全文
posted @ 2011-02-14 14:06 AlexCheng 阅读(557) 评论(0) 推荐(0)
处理顶点——凹凸映射:固定法线
摘要:问题 三角形的最主要问题是它是平的。如果你使用两个三角形绘制一堵巨大的墙并在墙上附上一个漂亮的纹理,结果是令人失望的平的。 你可以将三角形分割成更小的三角形以添加细节,这需要定义每个顶点的3D位置,但这样做会消耗太多的资源。 解决方案 你可以使用凹凸映射代替上述这个丑陋的方法。凹凸映射通过改变三角形每个像素的颜色给观察者留下三角形表面高低起伏的印象。 如果你看一张平整的红色的塑料板的图片... 阅读全文
posted @ 2011-02-14 13:59 AlexCheng 阅读(611) 评论(0) 推荐(0)
处理顶点——创建自己的顶点格式
摘要:问题 顶点用来存储从XNA项目发送到显卡的数据。一个顶点格式包含存储在顶点中的数据的描述。XNA框架自带有默认的顶点格式,从简单的VertexPositionColor到 VertexPostionNormalTexture格式。 但是,如果你需要顶点带有额外的数据,例如切线或时间数据,就需要定义自己的顶点格式。如果要在顶点shader中使用这个数据,这一步是必须的。所以,只有编写自定义的顶点... 阅读全文
posted @ 2011-02-14 13:52 AlexCheng 阅读(592) 评论(0) 推荐(0)
处理顶点——从XML文件加载数据
摘要:问题 你想从一个XML文件中加载数据到XNA项目。你可以使用默认的.NET文件IO功能在XNA项目启动时读取文件做到这点,但这在Xbox360平台上无法工作。 你想使用内容管道将一个XML文件串行化为一个二进制文件,这样就可以在XNA项目中读取包含在这些文件中的内容了。 解决方案 在XML文件中,只需简单地将你想要加载的对象插入到和标签之间,下面的XML示例文件是一个自定义的MapData... 阅读全文
posted @ 2011-02-14 13:49 AlexCheng 阅读(564) 评论(0) 推荐(0)
处理顶点——计算光标与地形的碰撞点:表面拾取
摘要:问题 你想获取地形上由光标指示的位置的精确3D坐标。 解决方案 如教程4-19的介绍中讨论的那样,通过光标指示的屏幕上的一个2D点对应3D场景中的一条射线。在本教程中,我们将沿着这条射线直到它与地形发生碰撞。 你可以使用一个二分法搜索(binary search algorithm)做到这点,这可以根据你选择的精度获取碰撞位置。 对高低起伏的地形来说,可能在射线和地形之间有多个碰撞点,如... 阅读全文
posted @ 2011-02-09 09:12 AlexCheng 阅读(347) 评论(0) 推荐(0)