zoukankan      html  css  js  c++  java
  • 不争气的geometry shader

    转载请注明出处为KlayGE游戏引擎,本文地址为http://www.klayge.org/2011/07/26/%e4%b8%8d%e4%ba%89%e6%b0%94%e7%9a%84geometry-shader/

    上周末实现了打算在KlayGE 4.0中使用的render to texture array功能。于是自然而然想到在ShadowCubeMap这个例子中使用,用来在1个pass内直接生成cubemap。结果,不比不知道,一比吓一跳。在不同GPU上FPS如下:


    NV 9800GT NV 480GTX AMD 5870
    6 pass Cubemap 158.63 312.82 241.10
    Dual Paraboloid 5.77 375.32 211.91
    1 pass Cubemap 66.08 288.77 228.44
    1 pass Cubemap with instance 105.37 281.34 224.10
    1 pass Cubemap with instance GS NA 287.80 211.01

    9800GT所在机器的CPU比后两套系统差得多,没法横向比较,只能纵向比较。后两套系统只有GPU不同,可以横向和纵向比较。

    5种做法

    • 6 pass Cubemap是个基准,实现方法就是最通俗的,在光源的位置向6个方向各渲一遍场景,得到cubemap的shadow map。
    • Dual Paraboloid需要渲染2个pass,正反面各一次,把经过tessellation的场景参数化到抛物面坐标系上。这种方法看似不错,但实际上省 不了多少draw(因为在高层就做了视锥剪裁),而且因为需要tessellation,开销会增加很多。在9800GT上,因为没有硬件的 tessellator,这里用的是简单的instanced tessellation,每个三角形不管大小都固定切分5次,所以性能超级低下。
    • 1 pass Cubemap的做法是,把每个顶点在VS里面分别乘上6个model view projection,得到了6个position全都传给GS。在GS里把每个三角形根据不同的position生成6份,然后通过 SV_RenderTargetArrayIndex传到不同的rt上,一个pass完成render to texture array。原先也试过在VS里面只是简单地把输入的position传给GS,而在GS里面完成乘矩阵的事情,结果更慢。
    • 1 pass Cubemap with instance的做法是用instance来生成6个顶点。这样在VS里面只需要根据SV_InstanceID选择乘上哪一个model view projection,在GS里面也不用生成6份。
    • 1 pass Cubemap with instance GS用到了D3D11新增的instance GS功能,让GS自己instance多个,而不用IA来进行instance的操作。

    数据分析

    1. Dual Paraboloid需要做很细的tessellation,而tessellation正是NV Fermi的强项,所以DP在NV 480GTX上比AMD 5870快得多,甚至快于不必做tessellation的方法。
    2. 1 pass Cubemap with instance比1 pass Cubemap快一些,说明用IA来拆顶点的效率比GS高得多(因为GS更通用)。
    3. 1 pass Cubemap with instance GS和 pass Cubemap with instance速度差不多。instance GS的出现就是为了加速这种状况,但它似乎没有做到。
    4. 1 pass Cubemap比6 pass Cubemap慢了不少。而且如果没有在GS里面做frustum culling,会慢相当多!

    对于3和4,有两种可能。第一是cubemap只有6个面,太少了,不够GPU发挥;这种可能性存在,但概率很低。更有可能是,GS太垃圾了,没法很有效地执行预期的操作。

    结论

    这样一测试,基本上可以认为,在render to cubemap的情况下,只要经过了GS,哪怕很简单的GS,都会对性能大打折扣。所以除非是类似于stochastic rendering、motion blur,其他时候用GS往往得不偿失。好在,D3D11的GPU上GS已经有所优化。比起D3D10的GPU来说,新一代GPU的GS性能损失少了很 多。但本来寄希望于instance GS,结果没有太多的好处,不知道以后的GPU和驱动会不会有所改进。

    另外,如果实在要做render to texture array,别忘了在GS里面自己做frustum culling以及back face culling。这样能极大地减少输出三角形的个数,从而提升GS的性能。

  • 相关阅读:
    eclipse如何与git 配合工作。
    git托管代码(二)
    PPC2003 安装 CFNET 3.5成功
    我的Window Mobile WCF 項目 第三篇 WM窗体设计
    我的Window Mobile WCF 項目 第一篇Mobile开发和WinForm开发的区别
    我的Window Mobile WCF 項目 第七天
    我的Window Mobile WCF 項目 第二篇 WindowsMobile访问WCF
    WCF 用vs2010 和 vs2008的简单对比测试
    vs2010beta1 和 搜狗输入法 冲突,按下 Ctrl 键就报错,重装搜狗解决
    我的Window Mobile WCF 項目 第六天 (二)
  • 原文地址:https://www.cnblogs.com/gongminmin/p/2118000.html
Copyright © 2011-2022 走看看