Skip to content
本系列的前三篇讲的都是关于Deferred Rendering的改进,本篇会专注于流水线后端的Post Process。 Post Process链 在KlayGE的渲染流水线里,不管用不用deferred,post process链是都会执行的。完整的post process链由一系列单独的post process组成,流程如下图所示。 前三个属于HDR的,经过tone mapping转成LDR之后,又经过三次post process,得到渲染结果。如果开了stereo,就会被stereoscopic的post process处理成立体的。 不管是用CUDA里的GPU kernel launch还是用图形API里的Draw Call来启动一个GPU任务,常见的改进规则都是,如果某次GPU任务不依赖于上次任务的其他单元,就应该和上次任务合并起来。这样可以省去GPU写入和读 ...
上一篇提到了在视口间共享shadow map的优化,以及对代码的重构。重构中的一个小发现造就了在不增加存储占用的情况下,就能支持透明物体的渲染。 透明物体和Deep G-Buffer 在透明的烦恼一文中,为了用纯Deferred的框架解决透明物体渲染的问题,KlayGE引入了Deep G-Buffer的方法。对不透明物体、透明物体的背面、透明物体的正面分为三个G-Buffer layer,分别有一条Deferred流水线,最终通过alpha把三层blend成最终结果。这种方法虽然能简单有效地解决问题,并避免繁琐的forward流水线,但需要三倍的存储和带宽。而且如果depth peeling的层数增加,开销还会进一步加大。最近出现的几种OIT方法,都不兼容于deferred。所以如果不用forward,就得 ...
上一篇讲到了把GI系统从Deferred Rendering框架中分离出来,以降低耦合度。本篇会涉及到一个共享shadow map、提高性能的改进。 多视口的改进 多视口的特性是KlayGE 4.2引入的。Deferred rendering layer支持通过多个视口生成多个渲染结果,可以用于分屏、反射、缩略图等情景。原先每个视口都是完全独立渲染的,互相不共享任何东西。实际上spot light和point light的shadow map是view independent的,不会因为视点不同而改变,就应该在视口间共享。 于是开发团队成员李渊完成了这个任务,把shadow map的生成提前到所有视口的G-Buffer之前。也就是说,原先的流水线是: for each view port: generate g-buffer. for each shado ...
从KlayGE 4.0确定了Deferred Rendering的框架以来,每个版本都有一些小改进。在正在开发的4.3里,多个改进经过这几个版本的融会贯通,产生了一些新的变化。这里做个系列总结一下。 GI和Deferred的分离 最早提到这个问题的是团队成员陈顺斌。他在去年就提出Deferred rendering layer太过复杂,应该把相对独立的GI拆出去。当时我的想法是,Deferred和MRSIL GI(Multiresolution splatting for indirect lighting)在逻辑上关联甚大,应该是一体的。后来实现了SSGI,也放在Deferred框架内,复杂度进一步增加。Deferred也成了个带有多种GI方法的怪物,各个组件之间的耦合度很高。 在分析了MRSIL、SSGI以及未来可能支持的SVO等多种GI方法之后 ...
上一篇提到了PSSM的方法,及其它的两个缺点。I3D2011上的Sample Distribution Shadow Maps可以用很低的代价同时解决掉那些缺点,在最大程度上优化shadow map上sample的分布。 SDSM PSSM的那两个缺点实际上都来自于同一个根源:光锥区域是根据视锥的大小,而不是可见pixel的范围来调整。这里所说的pixel范围涉及到两个方面。第一是pixel在view space的深度范围,这会影响区域的划分。另一个是pixel投影到light space的坐标范围,这影响到scale和bias的计算。很显然最佳情况是,shadow map的sample分布在所有可见pixel上,其他地方不浪费。而这两个方面都可以很简单地通过场景的depth texture得到。 原论文提到了多种sample distribution ...
大家一定很熟悉大场景的阴影渲染容易出现的锯齿问题,我这里就不废话了。这个问题常用的解决方式是Cascaded Shadow Map(CSM),用一系列同样大小的shadow map,每个管视锥的一个范围。现在大部分引擎也都支持CSM,各种资料也很齐全,所以我这里不详细阐述原理了。想了解细节的可以看原论文,或者GPU Gems 3的文章。 CSM还是PSSM 一个常见的疑问是为什么有的叫它CSM,有的叫他PSSM(Parallel-Split Shadow Map)。实际上原论文是把它叫做PSSM,工业界实现的时候选择了个更广泛的名字CSM。从名字本身来说,只要是一系列层级关系的shadow map,就能叫CSM,而只有平行切分视锥的才叫做PSSM。换句话说,CSM是个种类,PSSM是具体方法。 PSSM ...
去年4月,Forward+刚出来的时候,我写过一篇介绍的文章。很遗憾的是,原来的paper只比较了Forward+和传统Deferred,甚至是个没怎么好好优化的Deferred。对于Tiled Deferred(TD)的比较,一直都没见到详细的。今年GDC上,终于看到了一个对Forward+和Tiled Deferred的全面性能对比,包括不同光源数,不同render target(RT)个数和是否MSAA。 别的不说,直接看结论阶段。 算法分析 首先是对Forward+和Tiled Deferred的算法分析,列出可能影响性能的地方。     RT数量对比 G-Buffer包含了多少个render target,也就是用多少带宽,对性能应系那个很大。第一轮是关闭MSAA,三角形数量较多(1.25M个),Forward+和RT数 ...
上一篇介绍了Win7的touch和手势识别状态机。在Win8中,touch API虽然还存在,但新增了一个更方便使用的Pointer API,本篇会介绍一下它的使用。 Win8桌面的Pointer 和Win7的Touch相比,Win8的Pointer成熟得多了。它分为down、up、update等多个消息,甚至还有wheel消息。也就是说,相当于鼠标消息被完全移植过来了,并加入了触点ID。所以可以和容易地把原先处理鼠标消息的经验和代码都转移到WM_POINTER的系列消息来。在功能上还胜过Touch的一点在于,Pointer不光支持触摸屏,还支持鼠标、电子笔等多种设备,并可以返回之前n帧的历史坐标。目前KlayGE并没有用那些功能,仍是把几个基本的消息转到一个经过抽象平台无关的数据结构上。 需要注 ...
上一篇提到了,KlayGE的输入系统正在大改,将要加入触摸支持。本篇将会介绍Win7的touch,以及简单的手势识别。 Win7 Touch API 实际上Win7开始就支持了多触摸,只是UI和续航没跟上,使得Win7的平板体验一般。Win7的touch分为两个层面,第一个是底层的WM_TOUCH消息,应用程序收到的是触点坐标等;第二个是高层的WM_GESTURE消息,应用程序收到的就是已经经过识别的手势了。两者只能选择一个,不能两个都收到。默认的是WM_GESTURE,如果调用了RegisterTouchWindow,系统就会不再发送WM_GESTURE,而把底层的WM_TOUCH发给应用程序。WM_GESTURE虽然简单,但缺点很明显。它受限于支持的几种手势,没有办法添加自定义的。所以这里只打算介绍WM_TOUC ...
KlayGE的输入系统从2003年完成之后,几乎就没有大的修改。谁想到在10年后的今天,输入系统几乎完全重写了。 DirectInput的缺点 原先KlayGE的输入系统只有DirectInput一个插件,基本就是简单地把DirectInput包一层,实现对键盘、鼠标和手柄的支持。在核心层,获取了设备的输入之后,经过action mapping系统,把输入转化成具体动作传给应用程序。这套系统就这么工作了很久,直到这两年触摸输入设备软硬件的发展,只支持传统输入就显得限制很大了。 即便是在键盘、鼠标上,DirectInput也不像它的名字那样direct了。根据Taking Advantage of High-Definition Mouse Movement,在系统内部,DirectInput会建立一个独立线程,读取WM_INPUT,所 ...