03
Nov 13

Last of Us的光照技术

最近一年异常的忙碌,博客更新就耽搁下来了,现在总算有时间了。还是继续保持每周一篇的分享吧。先来一篇SIGGRAPH2013中比较实用的,由Naughty Dog的二号工作室带来的Last of Us中用到的小技巧分享。这个游戏前不久也买了数字版,虽然也许是不喜欢打僵尸,个人觉得游戏性上不如Uncharted,但是画面还是非常漂亮的,技术和美术的结合非常好。

写一下最感兴趣的部分,解决光照图接缝问题的Trick

Last of Us也大量使用了预烘培光照图技术,并且也遇到一个经典问题,就是一个模型在3D空间连续的面,实际上在2D的UV空间里面是不连续的,这样烘培之后的光照图就会有硬边出现。
Photo & Video Sharing by SmugMug
解决办法出人意料的简单,虽然不是物理正确的,但是也足够了。就是在这种会被分离的三角形边上定义一系列的焊接点,由于需要的是让纹理空间中相同的焊接点位于不同位置的采样点的值相同,所以定义一个Error Function为

\(E_i=(C_{i0}-C_{i1})^2\)

接下来的工作就是如何让整个光照图中所有E最小化。用经典的最小二乘法即可,有很多现成的库可以用。比如这个Eigen。大致想了一下实现方法,因为我们现在的贴图平铺算法也是自己实现的,而大部分模型美术都是依赖工具自动平铺的,人工干预的并不多。所以这个焊接点的标记也可以在平铺算法中自动标记,这样集成这个算法到我们现在的GI烘培流程中并不太困难。以后也许还可以分享一下具体实现的效果。
Photo & Video Sharing by SmugMug
相同的思想也能用来减少3D LUT后期算法的量化误差,通过对PS中的图像和实际的IN-GAME图像使用最小二乘法修正用于后期处理的Volume Texture。可以保证IN-GAME效果和PS中差别不大。
Photo & Video Sharing by SmugMug
总结一下,光照图和静态烘培技术对提高画面品质作用非常大,但是必须要技术和美术的密切结合才能做到出效果,并且需要一套能够实现这些定制渲染算法的工具。虽然开发和维护成本很高,但是确实是衡量一个团队是否有自己的核心技术的标准。现在的通用引擎非常多了,像Unity3D之类的更是以极低的价格集成了大量的中间件。但是从另一个角度来说,能否用好这种引擎,还是要看团队的内功。建立自己的工具管线才是提高制作效率保证效果的王道。


18
Jan 12

I3D 2012

I3D算是Mini-SIGGRAPH,有很多更容易应用到游戏中的文章,今年的很多文章已经有预印本放出来了,整理下,我觉得比较有意思的文章:

Real-Time Bidirectional Path Tracing via Rasterization:用硬件光栅化来做实时的双向路径追踪,很有意思,是史克威尔的人写的,类似的东西我去年做烘培的时候也考虑过,后来觉得实现难度比较大就放弃了。

Surface Based Anti-Aliasing:又一个适合延迟渲染用的反走样算法

Fast, Effective BVH Updates for Animated Scenes:高效的BVH更新算法,是一个实时光线追踪库的一部分,代码在这里。想起来Blender新的Cycles实时渲染器也有一个很快的BVH更新实现。值得研究研究,我觉得我们迟早要把烘培器实时化的,这样能大大提高美术场景制作的效率。

Decoupled Deferred Shading for Hardware Rasterization提出了一个叫做Compact G-Buffer的数据结构,把Visibility和Shading Sample独立开,这样可以把Shading的计算进行缓存和复用。

A Reconstruction Filter for Plausible Motion Blur:这个技术用来做运动模糊的特效似乎非常值得一试,只需要一个场景内容的纹理和一个运动速度场描述纹理就可以了。作为一个后期滤镜来实现。

最后,更完整的论文列表在老地方

对了,GPU Pro 3明天应该就开卖了,回上海可以入手了。


13
Jan 12

自动UV平铺算法-Smart Project

光照图生成的一个基本要求是需要一套不重叠的平铺纹理坐标,对美术来说,展这个UV是比较痛苦的工作,虽然一般的MAX或者Blender里面都有这样的自动平铺工具,但如果能直接集成在编辑器中,这样修改后可以快速看到效果。那就更理想了。因为这不是很简单的工作,尝试过很多方案,准备写一个系列的文章,把这些算法都总结总结。

基本上主流的解决方案有几种:

  • DX SDK自带的UVAtlas算法,是基于几篇SIGGRAPH Paper实现的。Unreal3是直接用的这个库。听说不是很好用,但是可能以后还会尝试一下。因为这个库里面集成了一些用信号分析的方法,对UV岛屿进行自动缩放的算法。但是看API,要用明白还是不容易。
  • 基于LSCM的一些算法,尝试过自动切分,效果和后面要说的Smart Project差不多。如果有手动的切分,参数化效果会很不错。可惜不能满足我们的需求
  • 最后就是MAX和Blender里面带的比较土的一种算法,这种算法对建筑类型的物件比较适合,对曲面比较多的物件就不太好用了。所以主要现在还是用在场景模型自动平铺上。输入参数有两个,一是角度阀值(决定了面的变形和孤立岛屿的数量),一是UV岛屿的间隔(用来减少漏光的缓冲区域)。

在有手动切分情况下LSCM和Smart Project的效果对比(Blender)如下,左边是LSCM,右边是Smart Project:

在没有手动切分下,LSCM和Smart Project的效果对比如下,左边是LSCM,右边是Smart Project:

今天主要介绍一下这个Smart Project算法.主要步骤如下:

0.准备几何数据,合并冗余顶点,在每一个三角面中保存由这些不重复顶点索引构成的边索引列表

1.生成模型的ProjectionVector

a.从面积最大的面开始试探,收集所有法线和这个面法线夹角小于用户设置阀值的面,把这些面从FaceList删除

b.把这些面法线按面积加权平均,获得一个AverageVec

c.遍历当前的FaceList,找到面法线和这个平均的法线角度差别最大的面

d.如果这个面的夹角是大于用户设置的角度阀值的,就把这个面设置为新的试探法线,重新进行a

e.直到所有的面都处理过了,迭代终止

总的来说,就是按用户给的角度阀值,对所有的面法线进行一次聚类,找到特征向量,这些特征向量

代表了在这个角度阀值下,几何体的面法线分布

2.获得每一个特征投影向量对应的面,这些面法线和这个特征向量夹角是最小的,这样投影之后变形比较小

a.遍历所有的面

b.对每一个面,遍历所有的特征投影向量

c.把这个面加入到与其夹角最小的投影向量面数组中去

3.构造切向空间的投影矩阵

a.遍历所有特征向量面集合

b.用当前特征向量构成一个切向投影矩阵

c.把所有的面顶点都投影到切向空间,变成2D坐标

4.把这些面根据其边的连通性打散成不同的UV岛屿

a.对每一个特征向量的面集合,构造其边和面的映射表

b.遍历这个面的所有边(合并冗余顶点非常重要,因为这里需要把相邻的面合并到一个UV岛屿中)

5.对每一个UV岛屿,根据用户输入的间隔值,将其包围盒扩大一定的范围

6.对UV岛屿进行旋转试探保证其面积最小

7.尝试搜索有洞的UV岛屿,把面积比较小的UV岛屿填充进去,节约空间

8.用经典的BinPack算法进行排列

9.把每一个岛屿的UV坐标变换到0-1范围,即完成了UV平铺坐标生成

结果大概是这样的:

可以改进的地方还不少,比如把一个区域内的所有物件的光照图进行合并,这样能把浪费的空间降低。总的来说,自动平铺是个水很深的东西,很难做到完全自动,对一些复杂模型手动平铺是必须的。但是对场景里面建筑类模型基本90%都能用这种算法平铺,以后准备做一个模型画刷,能让美术直接把漏光的部分绘制一下。可能就够用了。也可以考虑直接在编辑器里面加一个简化的UV坐标编辑功能,让美术能对UV进行微调。


11
Jan 12

Sparse Virtual Textures

今天看到一个比较有意思的东西:GameDeveloper杂志主编对Bungie高级图形工程师Hao Chen的访谈

Bungie的渲染技术一直是非常牛b的,有微软亚洲研究院做后盾确实不一样。HaoChen的名字经常在各种PPT里面看到。这次的访谈感觉还可以,主编的问题还是有点深度的。摘要一些重点:

1.Bungie没有用超大纹理技术(Megatexture),但是他们用的类似的Sparse Textures技术看上去蛮有意思的,类似纹理映射的稀疏矩阵。可以只保存有效的纹理数据,对超大地表绘制的MASK图和阴影图来说很有用。Google了一下,发现好几篇Paper,也有不少开源代码,都是基于Clipmap的技术。有时间可以深入研究一下。

2.Shadow还是一个不能获得完美解决的问题,因为阴影从本质上说是光照的副产品,而各种频率的阴影则是全局光照的副产品。所以实时计算还很困难。现在大家只能用各种trick去改进

3.反走样是Bungie下一代引擎要解决的重点问题,除了锯齿,还有很多其他的temporal aliasing. MLAA是比较重要技术,最近的一些进展使得我们可以只用2x或者4x反走样的存储空间获得8x或者16x的图像质量。除了这些,还有更好的纹理滤波技术,光照和材质技术。可以消除走样。

4.体素化技术,现在是用在寻路和裁剪上,未来可能还会用在GI和光照计算上,但是如何从离散化的体素映射回来不是很容易的事情

5.Bungie的图形工程师的时间分配:65-70写代码,剩下的和美术交流,工具的使用和反馈

6.后续引擎的重点:消除各种走样,比如植被的边缘,头发的边缘。创造更加动态的世界。最后是角色效果,角色动画,表情动画。


08
Jan 12

渲染器设计笔记-DX9的多线程标记

最近忙着做新效果新工具的各种规划,还是很充实的,特别是经过去年下半年做新烘培引擎的锻炼,从辐射度算法一路到光线追踪,看了一堆Paper(PDF居然有接近10G了,当然图形学的Paper图比较大)。再到具体的实现和美术编辑器的整合。解决了很多实际问题。这就是PureCreation的乐趣吧。看SIGGRAPH的Paper也比较适应了。很多问题终于都能想透了。有一种登堂入室的感觉。PBRT虽然05年读研的时候就看过,但没有实战过,理解终究是肤浅的。但是这次能在短时间搞定烘培,和之前的积累还是有关系的。最近PPT写了不少,可惜不是很方便放出来。

今天简单的说一下渲染器设计的一个前期就要考虑的问题,那就是是否要打开多线程标记,也就是D3DCREATE_MULTITHREADED标记。因为这个设计决策会对其他子系统的设计有直接影响,比如资源的后台加载系统。所以还是需要仔细考虑的。因为现在即使是中国的家用PC也基本进入多核时代了。所以引擎支持多核是基本的要求,国外单机引擎大概在05-07年已经完成这个转变。而DX9在创建设备的时候有一个是否打开多线程支持的标记,如果打开这个标记,则表示我们会从不同的线程去访问DX9的设备对象,因为DX9从本质上讲是一个单线程的API,所有的DX9 API调用这时都会有大量的锁操作来进行保护。当然会有性能损失。另一方面,不管是DX9还是DX10,真正的异步资源创建都是不可能的。所以这也给人感觉是不是对于多线程的引擎来说,我们必须打开多线程标记?答案当然是No!别忘记软件工程的一个解决问题的基本原则,那就是增加多一层的间接性!所以基本上目前大家实际上的做法是这样的:

  1. 用Command Buffer的机制来使得为单线程设计的DX9 API可以在多个线程调用,每一个线程有一个Per-Thread的Buffer,最后只在主线程全部提交所有的Buffer,也就是做DX9 API的调用。这样一方面可以在多个线程构造Command Buffer,另一方面,只在渲染线程访问DX9,可以在创建设备的时候关闭DX9的多线程标记,带来不小的性能提升。并且由于会导致陷入内核级的函数调用集中进行,也会给驱动优化的空间。
  2. 对于资源后台加载来说,由于DX9和DX10的渲染资源只能在渲染线程做填充和创建操作,所以我们只能引入额外的Buffer,在后台线程完成资源文件的解压和加载等操作。然后在渲染线程用到的时候再进行真正的创建,由于全部数据已经读入内存,所以效率还是可以接受的。
  3. 现在的主要问题就是如果我们使用这种Command-Buffer的抽象,会不会增加很多复杂度,但是带来的性能提升并不明显?以后等我们的引擎实现这个特性之后,我会再给出性能测试的报告。

参考文献:

  • Gamefest 08 Multi threaded rendering for games
  • Memory Models:Foundational Knowledge for Concurrent Code
  • Game Engine Gems I  Chapter 9: A Multithreaded 3D Renderer
  • Game Engine Gems I Chapter 10: Camera-Centric Engine Design for Multithreaded Rendering
  • Practical Parallel Rendering with DirectX 9 and 10 Windows PC Command Buffers

这些资源Google都能找到全文或者电子书下载。


10
Dec 11

球谐光照(Spherical Harmonic Lighting)实现笔记

球谐光照其实已经不是什么新技术了,基本是国外单机游戏必备的渲染技术。要深入理解这个技术必须先简单说一下基函数的概念。前面讲采样还原的时候我们提到过,某一点的辐射度(Radiance)可以看成一个关于光源位置的无穷维函数。那么如果我们能够把这个函数用一组简单的基函数表示,那么就意味着,我们可以保存这些基函数的系数即可近似的还原原函数。对于游戏来说,这意味着我们可以在预处理阶段把很多信息记录下来,在实时渲染的时候用简单的方式加以还原,获得类似全局光照(GI)的效果。下面用一个简单的例子来直观的说明这种思想:

比如我们有一个用20个标准基系数才能表示的数据,如上图左边图形所示。那么我们能否只用3个系数就表示出这个数据呢?使用另外一组基函数,并作相应的投射变换即可,比如用离散余弦变换,这样原函数的表示就被简化了,也能用更少的数据进行存储了,这就是基函数的意义。

回到球谐函数的主题,前面讲采样还原的时候提过,傅立叶变换可以把任意的函数分解为正弦和余弦函数之和。而球谐函数就是这个变换在3D球面上的推广,也就是说球谐函数是一组正交基函数。并且有很多很适合渲染函数使用的特性。如旋转不变性和线性插值。这样我们可以把渲染方程中的一些函数投射到球谐基上去。比如空间内某一点的辐射通量函数。这样通过基变换牺牲一点信息,可以获得复杂函数的近似表示。而对渲染来说,丢失一些信息对表现影响不大,特别是球谐光照往往应用在漫反射光照上,这种光照的特点就是不会有高频分量,变化是比较平滑的。球谐函数的实部定义(对于渲染来说,我们不需要考虑虚部)是这样的:

\(Y_{l}^{m}(\theta,\phi)=\left\{\begin{array}{ll} \sqrt{2}K_{l}^{m}P_{l}^{-m}(cos\theta)sin(-m\phi) & m \lt 0 \\ K_{l}^{m}P_{l}^{m}(cos\theta) & m = 0 \\  \sqrt{2}K_{l}^{m}P_{l}^{m}(cos\theta)cos(m\phi) & m \gt 0 \end{array}\right.\)

其中l的范围就是这组球谐函数的级数(Bands)。这里就不细写具体的数学推导了,其中的勒让德多项式(LegendrePolynomials)是一个递归定义的函数。对于实时渲染来说,一般只会用到2或3-Bands。再往上走,性价比就很低了。而从公式的系数我们可以看到这个基函数是定义在球形坐标上的,后面会讲到如何映射到我们通常使用笛卡尔坐标系。

在说具体实现算法之前,先讲一下典型的球谐光照应用场景

光照图的压缩存储

在之前讲光照图表示格式的文章里面提到过这种应用方式,就是把物体表面每一采样点的Irradiance函数变成一组球谐基函数合成。然后用4-6张贴图来保存这些系数。然后在运行时用法线和存储的系数进行Irradiance的还原。因为这种表示方法虽然效果很好,但是存储空间和计算成本都比较高,我们并没有在引擎中使用。这里就不继续展开了。

动态物体受静态光影响

这种应用是最普及,在很多实时游戏中,为了用比较小的代价获得比较高质量的光照效果,一般都会用到离线烘培技术,对于离线渲染器来说,面光源能够很轻松的处理,这样也能获得很自然的软阴影和Color Bleeding效果,并且最后用光照图的方式保存。实时渲染的代价是非常小的。但是这就带来一个问题,烘培时无法考虑的动态物体怎么办?比如角色,NPC之类的。如果角色不能受到静态光源的影响,就会显得和整个环境格格不入。比如下面这样:

所以我们需要用某种办法把静态光对场景的影响捕捉下来,并且能有廉价的方法在实时渲染的时候利用这些数据来还原静态光的影响。这就要用到球谐光照了,这种方法因为实现上有各种变形,并且大家总喜欢搞新名词,所以文献中叫法不太统一。比如Irradiance Volume,Volumetric Lighting,Ambient CubeMap,Light Probe等。首先我们会对场景做离线处理,在场景中选择一些重要的采样点,也可以按某种规则(比如只有角色会走到的地方)自动生成。在这个点上把这一点的辐射通量(E,Irradiance)投射到球谐基上去。而各家游戏在这个投射算法的选择上一般都会根据自己光照方程的特点做某些变化。存储格式也都各不相同,有用CubeMap的,也有直接保存球谐基系数到规则网格的。我们的引擎采用了自适应网格的方式,对光源比较多的区域,会生成比较细的采样点网格。在生成算法上,使用的是标准的蒙特卡洛积分,对每一个采样区域,计算一系列的可见采样点的球谐基系数,然后把这些系数加权平均即为这一个采样区域的球谐基系数。保存到文件中。我们使用的是2阶的球谐基,每一个点只需要9个浮点数。而角色可以行走的范围通常不会占据太大的空间范围,所以算下来一张地图所需要的文件大小并不大。下面详细讲讲如何在实时渲染时高效的从基函数系数还原Irradiance。

1.首先我们需要把递归计算的球谐基系数表示投射到笛卡尔坐标系上:

\(\begin{eqnarray}  Y_{0}^{0}(\theta,\phi) &=& \frac{1}{2} \cdot \sqrt{\frac{1}{\pi}}\\ Y_{1}^{-1}(\theta,\phi) &=& -\frac{1}{2} \cdot \sqrt{\frac{3}{\pi}} \cdot \frac{y}{r}  \\ Y_{1}^{0}(\theta,\phi) &=& \frac{1}{2} \cdot \sqrt{\frac{3}{\pi}} \cdot \frac{z}{r} \\ Y_{1}^{1}(\theta,\phi) &=& -\frac{1}{2} \cdot \sqrt{\frac{3}{\pi}} \cdot \frac{x}{r} \\ Y_{2}^{-2}(\theta,\phi) &=& \frac{1}{2} \cdot \sqrt{\frac{15}{\pi}} \cdot \frac{yx}{r^2} \\ Y_{2}^{-1}(\theta,\phi) &=& -\frac{1}{2} \cdot \sqrt{\frac{15}{\pi}} \cdot \frac{yz}{r^2} \\ Y_{2}^{0}(\theta,\phi) &=& \frac{1}{4} \cdot \sqrt{\frac{5}{\pi}} \cdot \frac{2z^2-x^2-y^2}{r} \\ Y_{2}^{1}(\theta,\phi) &=& -\frac{1}{2} \cdot \sqrt{\frac{15}{\pi}} \cdot \frac{zx}{r^2} \\ Y_{2}^{2}(\theta,\phi) &=& \frac{1}{4} \cdot \sqrt{\frac{15}{\pi}} \cdot \frac{x^2-y^2}{r^2} \end{eqnarray}\)

其中\(r=\sqrt{x^2+y^2+z^2}\)一般来说,我们都是用法线去插值的,所以这个r一般都是1.这个公式映射到顶点Shader中去,也就是10几条算术指令而已,所以可以说是非常廉价的。

这里要提一下的是,Spherical Harmonic Light:The Gritty Details的22页里面也有这个速算表,但是符号和最后一项的系数都有错误,请大家注意。一开始偷懒没有自己推算,用了这个公式,结果怎么结果都不对,实在是很坑爹的。

2.然后在运行时,根据动态物体的位置,获得最近的8个球谐基采样点的值,做三线性插值获得c_E,也就是我们投射到球谐基上的Irradiance函数的压缩表示。

3.最后把这9个浮点值传入Shader,用刚才的速算公式,带入顶点法线进行点积相加(c_E[i]*Y(l,m)的结果累加)即可获得这一点的Irradiance

最后生成的采样点和角色Diffuse受光效果如下图所示,主要看角色的受光和生成的采样球,其他部分因为是调试环境,效果可能会比较奇怪。

PS.用LaTeX渲染数学公式真的很漂亮,编辑起来也很方便。

比较有价值的参考文献:


02
Dec 11

暗黑3渲染技术分析-色调映射

色调映射是一种常用的后期算法,在电影业,通常是用所谓的Color Grading实现的,并且有专门的硬件。这几年游戏也开始使用这种技术来做到更方便的色彩管理。这种技术的原理非常简单,就是把复杂的颜色变换函数转换成一张查找表(LookUpTable)。GPU Gems 2上面有专门的文章

这样做一方面可以提高性能,因为数学运算变成查表了,另外更重要的作用就是美术调整效果可以完全脱离程序的协助了,只要直观的在PhotoShop中使用熟悉的曲线工具来调整想要达到的图像效果。然后把这个变化应用到标准的查找表上,最后导出成一张纹理即可。引擎基本上也会支持直接加载新的查找表纹理,可以在IN-GAME立即看到调整的效果。一般来说查找表可以是一维的,这样RGB三个通道就要用3张查找表了。这种简单的LUT适合不需要其他通道信息的简单图像变换,比如Gamma校正。但是对于复杂的图像变换,比如亮度调整就无能为力了。这时就需要三维的LUT了。生成好之后,用RGB去索引就能获得复杂的图像变换效果:

CryEngine3和Unreal3都采用的这种方式,可以看看他们引擎的效果截图:

UE3:

CryEngine3:

从这张图也可以看出查找表的制作方式,同时打开参考图像和标准查找表,然后调节到满意效果后,应用到标准表。

CryEngine用的标准表看起来是这样的:

下面说一下暗黑3的色调映射,先看看效果对比:

应用色调映射前:

应用之后:

可以明显的看到对比和色彩的变化。

暗黑的算法比较特别,为了效率的考虑,不像其他引擎,使用了3D纹理作为LUT,暗黑3使用的是两张512×512的纹理,也就是两张64×64×64的3D纹理平铺的二维表。从资源包里面我们也可以看到对不同的场景和区域,这两张LUT是完全不一样的。

ColorCorrectA:

ColorCorrectB:

Shader代码:

    ps_3_0
    def c0, 63, 7.875, 0.125, 8
    def c1, 63, 1, 0.5, 0.001953125
    dcl_texcoord v0.xy
    dcl_2d $texOriginal
    dcl_2d $texSatVignette
    dcl_2d $texColorCorrectA
    dcl_2d $texColorCorrectB
    texld r0, v0, $texOriginal
    mad r0.xyw, r0.zxzy, c1.x, c1.yzzz
    mul r1.x, r0.x, c0.z
    frc r1.y, r1_abs.x
    cmp r0.x, r0.x, r1.y, -r1.y
    mul r0.x, r0.x, c0.w
    frc r1.y, r0.x
    add r0.x, r0.x, -r1.y
    mul r2.x, r0.x, c0.z
    frc r0.x, r1.x
    add r0.x, -r0.x, r1.x
    mul r2.y, r0.x, c0.z
    mad r1.xy, r0.ywzw, c1.w, r2
    texld r2, r1, $texColorCorrectA
    texld r1, r1, $texColorCorrectB
    mul r3.xy, r0.z, c0
    frc r0.x, r3_abs.y
    cmp r0.x, r0.z, r0.x, -r0.x
    mul r0.x, r0.x, c0.w
    frc r0.z, r0.x
    add r0.x, -r0.z, r0.x
    mul r4.x, r0.x, c0.z
    frc r0.xz, r3.xyyw
    add r0.z, -r0.z, r3.y
    mul r4.y, r0.z, c0.z
    mad r0.yz, r0.xyww, c1.w, r4.xxyw
 
    texld r3, r0.yzzw, $texColorCorrectA
    texld r4, r0.yzzw, $texColorCorrectB
    lrp r5.xyz, r0.x, r1, r4
    lrp r1.xyz, r0.x, r2, r3
    add r0.xyz, -r5, r1
    texld r1, v0, $texSatVignette
    mad oC0.xyz, r1.x, r0, r5
    mov oC0.w, c1.y

从Shader代码可以看到使用平铺纹理查询的坐标计算还是很多的。并且要自己做插值算法,所以对LUT有4次纹理采样,但是还是比标准的8次少很多了。这是因为暗黑3采用了两张查找表的原因吧。也就是通过空间换时间。

总结一下,Color Grading技术可以给我们带来非常方便的色彩调节功能,简化美术调试流程,而且一些效果恐怕用以前程序写Shader的方法根本就调不出来。所以是非常值得采用的技术。具体的实现方法,暗黑3给我们带来了一个很好的思路,就是在DX9级别的硬件仍是国内主流的情况下,回避昂贵的3D纹理采样,用两张2D平铺纹理来获得一个效率上的折中。暴雪就是暴雪,总是用最廉价的方法获得最好的效果。


27
Nov 11

[Gamefest 2011]Rethinking Game Lighting Pipelines

PPT和录音可以在这里下载到:Rethinking Game Lighting Pipelines

这个PPT是做实时辐射度中间件的Geomerics技术头对光照管线的一些思考。总的来说就是希望能够尽量往实时靠。美术应该是渲染效果的关键,必须让美术尽量快的获得光照调节的结果,快速迭代才能出好结果。传统的离线烘培技术把渲染器当成一个黑盒子,对美术来说是很痛苦的。而随着GPU运算能力的提升,我们已经有一些新的实时算法可以模拟面光源效果(Area Light)了。而我们现在使用离线烘培最大的推动力之一就是可以使用面光源。如果实时也可以做到,那么完全可以重新设计光照烘培管线了!让美术可以实时调节光照,然后用类似这篇文章提到的方法,直接把实时光照的结果保存成光照图纹理供真正的游戏使用。既满足了效率的需求也兼顾了制作效率。 PPT里面提到的几个有意思的论文,有空得仔细读读,我想我们的烘培3.0系统应该就是这样,重新回归实时!编辑器用上DX11,烘培之后客户端还是能够在DX9上跑。


26
Nov 11

Gamefest 2011 资源分享

今年的Gamefest资源已经陆陆续续放完了,这次奇怪的是没有一个统一的索引页面,所以是在MSDN下载中心搜索到的,大概比较有意思的有下面这些:

How Valve Makes Games Better with XPerf

前面已经讲过我们整合WPT(Xperf)到性能测试中的一些心得,下面是Valve的,大量使用了自定义事件提供机制来达到和引擎层的深度整合,这也是我们后面做新引擎时要做的.
Xperf can be a powerful profiling tool, making otherwise invisible performance problems easy to find. There are, however, numerous challenges in using it effectively. This talk will explain the techniques used at Valve to record and analyze Xperf traces, with case studies showing some of the performance problems found in Valve games. Attendees will learn to integrate Xperf into their profiling life cycle in order to discover the secrets of their own Windows games.

Scaling Your Game to N Cores: A Deep Dive on Tasking

Working on a bleeding-edge PC title releasing in 2013 or beyond? By 2013, the average PC will have four cores, and systems will ship with six cores or more. Get the most out of the latest hardware, and scale efficiently between two and six (or more) CPU cores by using Tasking. Tasking decouples algorithmic parallelism from implementation, allowing your technology to scale to N cores. Together we will explore the parallelization of rendering, animation logic, and MLAA post-processing, investigating the implementation and performance pitfalls we encounter along the way.

Rethinking Game Lighting Pipelines

一个做实时辐射度算法公司(Geomerics)对现在游戏中光照管线的一些思考,还没有仔细消化,大致看了下,对我们新的烘培管线设计应该还有不少借鉴意义。
Many urban myths surround game lighting technology: baking lighting into textures is slow, high-quality real-time radiosity is not affordable, most lighting research is not practical for games, hardware is not yet fast enough for complex lighting, etc. This talk challenges these myths, showing that considerable, unexploited potential still exists on current consoles. An argument is made for why the static/real-time divide no longer is relevant, and how rethinking the way lighting is generated can provide higher quality, more iterative lighting. Examples are provided for what alternative lighting pipelines are possible today with existing techniques, and what considerations should be made to prepare for the next generation.

Modern Texture Content Pipelines

There’s more to texture resources than just a file an artist creates in Photoshop. This talk will cover DirectX 11 and Xbox 360 block compression, the modern DDS file format, and the latest tools for processing textures for Windows and Xbox 360 games.

Efficient Shadow Mapping

Shadow mapping is a well-known technique for rendering shadows in 3D scenes. For highly complex scenes, however, shadow map creation can consume a big portion of the rendering budget. A naive solution to this problem would use occlusion culling from the light source to reduce the amount of rendered shadow casters. In this talk, we describe a method for solving this problem by using knowledge of visibility from the main view for culling shadow casters. First, we use occlusion culling for the camera view to identify visible shadow receivers. Second, when rendering into the shadow map, we use only those shadow casters that cast shadows on visible shadow receivers. All other shadow casters are culled, leading to significant improvements in the total frame rendering time.

CryEngine 3 Rendering Techniques

For Crysis 2, the R&D team at Crytek created the third iteration of CryENGINE. This lecture will cover various topics related to Crytek’s latest engine iteration. The lecturer will provide an overview of the rendering pipeline, and the successful transition to a multiplatform friendly deferred lighting approach; how gamma-correct HDR rendering and its multiplatform details have been handled, with a focus on performance and quality. Other topics include deferred lighting techniques such as efficiently handling skin-rendering, and overcoming alpha-blending problems for hair/fur rendering for current-generation hardware; water-rendering and dynamic interaction; batched HDR post-processing; and how AA was handled. The lecture will include multiplatform comparisons on final image quality, optimization strategies, and performance analysis insights. It will also unveil the DX11 implementation of certain features.

Precompiled Command Buffers: Care and Feeding

关闭DX的多线程标记,通过抽象渲染的Command Buffer来达到多线程更新Command Buffer单线程提交是我一直想在新引擎中尝试的基础架构。有结果之后又是一篇博客的内容了。
In this talk, we discuss the use of precompiled command buffers (PCBs) on Xbox 360. We explain what PCBs are, and when to use them. We also explain the interaction of the D3D shadow state with PCBs, including how the inheritance and persist flags work. Learn about important points of PCB memory management, and get a walkthrough of the different ways of managing render state with PCBs.
不错的一篇常用术语的解释

What’s in a Frame: Latency, Tearing, Jitter, and Frame Rate 

An old developer joke goes: “Q: How do you keep your publisher happy? A: Always render the words ’60 fps’ somewhere on the screen.” If frame rate is so important, why do we need an on-screen monitor to tell us what it is? Surprisingly, “sluggish” or “chugging” performance doesn’t always correlate with dropped frames. Why is it, for instance, that 24 fps movies can play smoothly on your TV, but 24 fps games cannot? Most titles must occasionally exceed their processing budget. How should they react? Drop frames, tear, add extra latency? Maybe all three? We present strategies for making the best of a bad situation.

Learning from Others to Create Meaningful 3D 

Whether 3D is the next big thing or not, developers and designers now have the opportunity to use this tool to support their game story. It is up to them to make it efficient, relevant, of quality, and immersive. With the support of frame packing coming to Xbox 360, let’s learn from games and movies that have shown the way.

The Zen of Functional Testing on Xbox 360 

Join us in the Functional Certification presentation while we examine the two major types of Functional testing. We will cover the most common failing FTC issues, and then learn about how we catch the most common non-FTC issues with our test planning process. We will cover topics like passing/failing scenarios, FAQs, the Optional Final/Final testing process and what is involved. Our Functional lead also will take you on a deep dive into our top 10 game-failing issues. You will have the opportunity to view some of the all new Xbox 360 Functional Certification training videos. Most importantly, we will give you an insight into how you can use all this information and more with any future submission planned for Certificati

The Blood and Guts of Mortal Kombat

A mandate for the reboot of Mortal Kombat onto Xbox 360 and PS3 was to significantly update the visualization of blood and gore in the game, along with the image quality in general. The requirement to maintain a solid 60 Hz during gameplay put significant limitations on possible approaches. This talk will focus on the game’s gore system, which is quite extensive and had to allow for an unbounded amount of blood to be displayed. We had to support the damaging and dismemberment of characters, as well as the rendering of their internal musculature and skeletons. Additionally, the game had to support blood interacting with the environment, characters, and their dismembered limbs in a consistent way. Methods and optimizations employed to get this all practically working and extremely fast will be described in detail.
后面几篇都是Kinect的了,还有很多,没有列全

The Magic Behind Kinect 

Understanding of how Kinect works and what it does well is key to making great games that use the hardware and software to the fullest. Join us for an all-inclusive discussion about how the Kinect sensor, skeletal tracking, Identity, and speech recognition work together to create the magic behind Kinect.

The Evolution of User-Generated Content 

User-generated content (UGC) is everywhere! This talk highlights some of the trends in UGC, as well as policies and best practices for implementing safe UGC features and functions. The basis for the presentation will be a newly updated UGC policy document that covers traditional UGC, as well as photo, video, and voice using the Kinect sensor.

Feedback, Feedback, Feedback: Good Kinect UI Design

Controller-free gaming affects menu design and in-game controls more than any other part of the game. This is new ground for most developers, and an art—the Xbox team has seen examples of success from across the spectrum. In this talk, we will explore some example paradigms from released games and elsewhere, and describe what we need to see during the concept approval and UI review stages before your title can ship. This information is valuable to Producers and Designers wanting to understand—and to improve upon—current best practices in the crucial area of player feedback.

Avatar Navigation with Kinect

We will explore an approach to navigating an open environment with Kinect. Using a walking-in-place paradigm, the system transforms the player’s movement into natural looking locomotion on their avatar. Various techniques for detecting and analyzing rhythmic motion are covered, including power calculation, zero-crossing detection, auto-correlation, and Fourier analysis (FFT and DFT).

19
Nov 11

几个图形学基础概念的笔记

做基于物理的光照不可避免的会遇到使用什么样的物理模型的问题,这方面已经有很成熟的理论了,如果要阅读新的Paper,这方面的概念还是要搞清楚的,不然看SIGGRAPH,GDC之类的文章会看得一头雾水。下面简单总结一下,后面准备写写今年比较有意思的SIGGRAPH文章和GDC的PPT。

光的物理学模型

  • 光具有波粒二向性
  • 把光看作光子(Photon)的流动,每一个光子都携带一份辐射能量
  • 使用成熟的热力学理论进行建模

立体角(\( \omega\))

  • 可以看作平面角的三维推广,用来表示方向

Flux(\( \Phi\))

  • 是一个能量单位,单位时间通过单位面积的辐射能量,单位是瓦特
  • 也可以看作单位时间内通过的光子数量
  • \(\Phi(p,\omega) \)表示在p点方向为 \(\omega\)的通量大小

Radiance (\(L\))

  • 单位投影面积单位立体角离开一个表面的辐射通量大小,\(L(p,\omega)\)代表在p点\(\omega\)方向的辐射亮度
  • 光线追踪算法中每一个Ray携带的能量就是用这个量来表示的

Irradiance (\(E\))

下面用一张SIGGRAPH11的PPT来说明一下\(E\)和\(L\)的差异:
Radiant Exitance (\(M\))
  • 单位面积离开一个表面的辐射通量,某些文献用\(B\)来表示
  • 我们写的Shader返回的值就是这个值
BRDF
  • 双向反射分布函数
  • 用来描述某一点入射和反射的Radiance之间的关系,也就是物体的材质属性
  • 在游戏里面,我们一般都用非常简单的模型,比如用一张贴图来代表每一点的BRDF
  • \(M=L(p,\omega_{r})=f(p,\omega_{i},\omega_{r})E(p,\omega_{i})=f(p,\omega_{i},\omega_{r})L(p,\omega_{i})cos\theta_{i}d\omega_{i}\)

渲染方程(Rendering Equation)

  • 图形学最基本的方程
  • Radiance = Emitted Radiance + Total Reflected Radiance
  • \(L(p,\omega)=L_{e}(p,\omega)+\int f(p,\omega_{i},\omega)L(p,\omega_{i})cos\theta_{i}d\omega_{i}\)
  • 一般来说渲染方程涉及了很多高维积分,计算复杂度非常高,所以一方面比如电影行业是在追求在有限的计算能力下如何更精确的求解渲染方程获得更真实的CG,而另一方面游戏行业则是考虑如何用取巧的办法去简化渲染方程,获得特定游戏需求的效果,当然随着桌面PC计算能力的提升,我们可以把很多以前离线渲染的技术用在实时游戏中了。这也是为什么做实时渲染的人一定要理解离线渲染的基础技术。这才是一个大宝库。
  • CS348B课堂笔记有更详细的内容,值得一看。