高动态范围(High Dynamic Range)本来是出版界的名词, 先捕捉自然界的色彩和亮度(比如摄影)再将源数据输出(印刷或曝光),这样就可以完整的将真实场景展现出来。可自然界的亮度范围(即动态范围)是非常大的,从没有星光的夜晚到阳光明媚的白天,亮度变化高达1:1012,而印刷物上可展现的动态范围只有可怜的几百,至于显示器嘛……就算是比较好的CRT,也只能达到1:300左右。原来的3D渲染只能在1:255的对比下计算光照和颜色,但随着图形技术的飞速发展,我们需要更高的动态范围用来模拟真实场景(比如3DMARK06中的日光渲染),我们将HDR的原始数据存放在浮点纹理上,那么下来如何将高动态范围的图像显示到低动态范围的显示器上呢?
通过名为Zone System的色彩空间及一系列的理论,我们可以对源数据进行Tone Mapping,重新映射HDR到指定的LDR区域而不丢失对比度细节,在Tone Mapping的过程中,还会模拟人眼对不同亮度的适应现象来进行亮度调整,最后进行Brighter Pass,这将过滤掉所有低亮度的部分,只保留高亮度,最后进行高斯模糊,就可以将这些数据混合起来,实现完整的HDR特效渲染:Tone Mapping + Automatic Adapt + Bloom
HDR数据存放在浮点纹理上,浮点纹理有半精度FP16和全精度FP32两种。支持浮点纹理的显卡较多,但支持浮点纹理过滤的就不多了,只有GF6/7支持FP16过滤,其他所有的显卡都不支持FP16过滤,至于FP32过滤嘛……现在世界上还没有任何卡能支持。所以我在FP16.EXE中使用硬件过滤,如果你的显卡不支持的话会看到严重的马赛克,而在FP32.EXE中使用Shader来模拟纹理过滤,这样做会降低运行效能,但画质得到了保证。
这个DEMO是基于Shader Model 2.0开发的,9500、GF FX及以上等级的显卡都可以跑。但由于HDR渲染的步骤非常多,而且都是巨量的纯像素运算,所以对显卡像素渲染管线的要求很高,4管的低端卡在1024*768分辨率下都很难达到30帧
需要注意的是:Geforce系列最好使用8系驱动,旧驱动很可能会造成DX9c下浮点纹理无法正常存储高动态范围的颜色数据
下面是在7800GT上的运行截图:
人眼适应-暗:
人眼适应-亮:
下面是硬件不支持浮点过滤在FP16下的效果(出现明显的马赛克,GF FX5200):
下面是驱动程序导致无法正常存储HDR数据在FX5200上的截图(注意右上角,亮度细节丢失,颜色很不自然):
程序下载(可以用FlashGet):
http://equuleusd.mofile.com/6596555770241614/2855418030322304/2/33EBF267A07C1B636E2D61D649EC58D5/HDRAdapt.rar