转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=1964

在KlayGE开发版中,deferred rendering的流水线中新增加了由组员王清源实现的屏幕空间反射(Screen Space Reflection,SSR),也称为Real Time Local Reflections。

反射对rasterizer来说是非常郁闷的,一般只能是平面反射或者cubemap的环境反射,并且需要多次渲染场景。对于非平面物体,可能性之一是使用Real-time Multi-perspective Rendering on Graphics Hardware的方法,把场景中的所有三角形通过非线性映射重新投射到反射物体上。这样的方法仍需要多次渲染场景,而且pixel shader开销巨大。相反,对于ray tracing来说,反射是个非常直接的事情,只要多算一次求交就可以了。

SSR就是借用了ray tracing的思想,对于每个要反射的pixel,计算一个反射ray,与屏幕空间的像素求交。对于deferred rendering来说,屏幕空间的normal和depth都是现成的,所以很容易直接就能计算出反射ray。然后就把反射ray和depth buffer做一次ray marching,得到相交点,采到它的颜色,就完成了反射。这个算法听着耳熟?没错,parallax occlusion mapping(POM)也是这样。所以,相当于你可以用POM的低廉开销做到屏幕空间非平面反射!

Screen Space Reflection

当然,因为反射本应该是全局的,而屏幕空间的数据很有限,这种方法只能反射局部的像素。如果发现相交点接近屏幕边缘,就得fade out。另外,根据表面的光滑程度做jitter,不然都会是非常清晰的反射。

SSR的优点:

  • 速度极快
  • 可以处理非平面
  • 与deferred rendering配合良好
  • 支持各种光滑度

缺点:

  • 反射结果较粗糙
  • 只能局部反射

本来打算把Ocean例子改成用SSR,但因为Ocean目前不是采用deferred rendering,要修改的话肯定赶不上KlayGE 4.1了。只能等到下一版才有空切换过去。在当前版本中还有另一个问题,因为normal用的是best-fit的方法保存成24bit,精度较低,所以在某些视角上会出现误差较大的反射ray,导致反射图像不连续。