http://hi.baidu.com/freedomknightduzhi/blog/item/0cdb8a0fe7cf37ffab6457df.html Author: FreeKnightDuzhi 关于Bloom和HDR的帖子和图片网上已是一堆,但罕有能够明确说明程序实现过程的帖子,明天需要进行简单一个讲解,故在此做个补充记录。 首先HDR是高动态光照。注意两个词:1:高(高精度)。 2:动态(光照时实时运算的)。 然后说下当前计算机图形学大部分颜色表示A8R8G8B8,即颜色可以表示为0-255的亮度(即一个深灰暗色到一个灰白亮色之间,并不能表示一个深黑色和一个非常耀眼的亮白色),用浮点数表示为【0,1】内,其实这是远不能表示人眼可分辨的亮度层级的(补,人眼可分辨亮度层级是1000,当前色彩学能表达的亮度层级是10的12次方……悲催啊,可怜的人眼)。那么,高于1.0f 的亮度将丢失被当成1.0f 表示进行渲染,得到的结果就是常规没有HDR游戏看到的画面。 那么HDR技术目的就是把颜色通道中无法表示的高亮亮度和极暗亮度 表示出来,所以它的特点就是: 1:亮的地方更亮。2:暗的地方更暗。3:亮暗部分的细节都表现的明显。 技术原理就是使用更高的颜色精度的纹理格式渲染。 它的传统分类有:按照单颜色通道精度分类有int16, FP16, FP32等。首先int16就意味着用16位int表示一个颜色通道,这个很诡异,在SM2.0下就可以支持,效率不高,效果很差,现在都被废弃了-。- FP16就是单精度float类型来表示一个颜色通道,GPU对浮点处理通常有额外加速,所以它的效率更高,效果也更好。FP32就是双精度浮点类型表示一个颜色通道,自然精度更高效果更好,可是会付出一些效率代价。FP系列的都要求是SM3.0以上。而后来DX10,11神马浮云般的就支持FP64,FP128咯╮(╯_╰)╭ 某志开发网游,面对国内二三级城市,8予考虑…… 基本想法流程:我们使用A8R8G8B8肯定是不能充分表达我们所想表达的肉眼可分辨细节啦,那么就用更精确的颜色通道来表示亮度呗,很简单,使用D3DFMT_A16R16G16B16F就好啦。但是很遗憾,由于GPU限制,我们不能设置后台缓冲为这么高精度的模式。所以,这个方法不行……悲催……那么,我们创建一个这样高精度的纹理,然后进行渲染,将渲染后的结果递交给后台缓冲就可以再屏幕上得到这种高精度的结果咯:) 所以,我们不得不创建一个高精度的纹理作为渲染对象,用它来替代原本的后台缓冲,我们就称这个纹理叫HDR渲染纹理。 其实,我们将HDR渲染纹理作为渲染对象后,就像平常的渲染就足够了。渲染完了之后呢,将这个纹理绘制到原本的后台缓冲就OK了。呃,怎么将纹理绘制到后台缓冲?……直接渲染一个全屏的四方面片带上这个纹理到后台缓冲就哦了 -.- 那么,从上面流程我们发现貌似我们还没有做像素的精度提升处理,这一步我们称之为曝光吧。 关于曝光的说明,有兴趣的去看看http://freespace.virgin.net/hugo.elias/graphics/x_posure.htm(╮(╯_╰)╭某志表示懒的翻译) 总之,各种数学家得到的最终结果之一是: float4 exposed = 1.0 - pow( 2.71, -( vignette * unexposed * exposure ) ); 这也就是我们写Shader所需要关注的唯一的公式(当然也有其他类型的公式,不同的公式有不同的效果)。其中 unexposed 就是原始的未加工的颜色纹理,vignette 下面描述,exposure 就是曝光度,大于1一般就可以了。(个人喜欢设置为2.0f,省事) vignette 在摄影里面称之为 暗角。因为照相机镜头有一个曲线度,导致照出的相片四个角会有一些亮度的丢失,发暗。这个就是暗角。 下面用俩公式表示暗角的代码。 float2 vtc = float2( iTc0 - 0.5 );float vignette = pow( 1 - ( dot( vtc, vtc ) * 1.0 ), 2.0 );其中,iTc0就是纹理边角的大小,值限制为[0,1]之间。 呃,扯远点。之前说过,大自然的色彩现在表示为10的12次方,可是人眼只可以分辨10的3次方色彩。那是否人眼就会很多色彩无法分辨,当然不是-。-人眼不能分辨的颜色,我们自然也没必要渲染和讨论了……那么人眼是如何做到识别更大范围的色彩的呢。是一种亮度自动适应机制,我们可以假设从一个光亮的室外刚走进一个黑暗的小黑屋里,那么人眼开始时什么都看不到的,但是慢慢的人眼会调整,适应黑暗的亮度,就可以看到一些色彩了,这就是亮度适应。 游戏里有些时候需要这么去做,例如从室内到室外,或者天气的突然变化(打闪咯),此时,我们需要做的就是动态修改一下曝光度,即exposure 。那么,此时这个曝光度如何计算呢? 最简单的方法就是使用Mip-map,Mip-map递归到1个像素纹理,此时得到的这个像素点亮度就很接近当前的全场景平均亮度,然后将这个亮度作为曝光度,将会比你硬编码方便自然的多。而且,很眩哦,全场景动态光照自适应。 最后,进行Bloom。这个单词我相信能来研究HDR的人是不会陌生的,它非常简单,就是获得当前场景纹理的一份拷贝,然后将这份拷贝进行Blur得到处理后的纹理(Blur一般是先水平方向再垂直方向,当然,可以进行多次╮(╯_╰)╭),再将处理后的纹理和原场景纹理进行一个混合得到最终结果。 当然这里有两个细节:1,为了让Bloom效率更高,我们经常可以将原场景拷贝后,缩减为原来的1/4再进行Blur,。2,我们经常是为了让亮的地方更亮,而不是需要全场景都进行Blur(没必要对普通色彩就可以表达的色彩进行Blur处理),所以在压缩拷贝场景纹理之前,通常我们会减去一个固定的色彩值,仅处理高于该色彩值的像素纹理即可,这样效率也会有些提升。当然,反之亦然,可以处理更暗的情况。 我们终于得到了一个高精度的纹理,但是考虑到可怜的显示屏,我们需要再加一道工,进行ToneMapping以保证最终渲染的RGB值不能超过计算机显示屏显示范围。ToneMapping的目的很明显,就是将一个高范围的值映射为一个低范围的值,这里就要求有合适的映射算法。 这里,http://www.graphixer.com.cn/ShowWorks.asp?Type=1&ID=48他有详细说明,俺不再做额外解释。 然后,将这个纹理渲染到后台缓冲。 那么,HDR到这里就全部结束了-。- 若需要特殊的效果,可以调整一下曝光度的数值,或者进行诡异的Blur便可以。 还不明白?那么详述一下 详细流程: 1:创建一个D3DUSAGE_RENDERTARGET的高精度格式纹理,并且设置渲染对象为该纹理,替代后台缓冲。 device->SetRenderTarget( 0, m_hdrTex ); 2:为这个纹理创建Mip-Map取得1/4即第三层级纹理m_hdrTexLevel3. 3:对m_hdrTexLevel3进行逐纹理像素曝光处理。 4:对m_hdrTexLevel3图进行Blur。 5:恢复m_hdrTexLevel3图到原始大小m_hdrTex。 6:将原始场景图和Blur过的m_hdrTex图进行相加混合。 7:进行Tone-mapping。 8:得到最终纹理,将该纹理渲染至后台缓冲。 以上流程均可以写在一个.fx里交由GPU处理~ //------------------------------- 附:获得亮度很简单…… float lum = dot( color.rgb, float3( 0.333, 0.333, 0.333 ) ); 有些人喜欢重视Green轻视Blue,那是未必有意义的……俺测试的效果还是均衡的好-。-但是还是给出吧。 float lum = 0.27*r + 0.67*g + 0.06b; // 据说这个公式是根据人眼对红绿蓝的敏感度得到的。好吧,叫兽砖家。
深入说明HDR的更多相关文章
-
基于Fast Bilateral Filtering 算法的 High-Dynamic Range(HDR) 图像显示技术。
一.引言 本人初次接触HDR方面的知识,有描述不正确的地方烦请见谅. 为方便文章描述,引用部分百度中的文章对HDR图像进行简单的描述. 高动态范围图像(High-Dynamic Range,简称HDR ...
-
Direct3D学习笔记 - 浅析HDR Lighting Sample
一.HDR简介 HDR(High Dynamic Range,高动态范围)是一种图像后处理技术,是一种表达超过了显示器所能表现的亮度范围的图像映射技术.高动态范围技术能够很好地再现现实生活中丰富的亮度 ...
-
手机开启HDR后拍照有什么不同?
转自http://www.leiphone.com/news/201406/hdr-pic.html HDR这词大家可能并不陌生,但大部分人只是听过而已,在脑子并没有太多的概念,可能只是简单的认为HD ...
-
HDR 拍照模式的原理,实现及应用
转自:http://blog.csdn.net/fulinwsuafcie/article/details/9792189 HDR 拍照: (High Dynamic Range Ima ...
-
HDR the Bungie Way PPT and demo from MSFT
Gamefest 2006 - HDR the Bungie Way Posted By: Falagard <falagard@hotmail.com> Date: 4/26/07 9: ...
-
[ZZ] Deferred Rendering and HDR
http://www.gamedev.net/topic/496785-deferred-rendering-and-hdr/ Quote: Original post by jstrohYeah I ...
-
[ZZ] RGBM and RGBE encoding for HDR
Deferred lighting separate lighting rendering and make lighting a completely image-space technique. ...
-
[ZZ] HDR&;ToneMapping
http://blog.csdn.net/toughbro/article/details/6745207 float游戏存储照片blogimage HDR high dynamic range. 很 ...
-
[ZZ] HDR the bungie way
http://blog.csdn.net/toughbro/article/details/6755394 bufferencoding游戏float算法 bungie 06年,gamefest上的p ...
随机推荐
-
java常见面试题及答案 11-20(JVM篇)
11.JVM内存分哪几个区,每个区的作用是什么? Java虚拟机主要分为以下一个区: 方法区:1. 有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生GC,在这里进行的GC主要是对方法区 ...
-
CLR via C# 3rd - 06 - Type and Member Basics
1. Different Kinds of Type Members A type can define zero or more of the following kinds of ...
-
MySQL之MySQL5.7安装包(msi文件)在Windows8下安装
最近自己在使用MySQL5.7.16.msi安装MySQL.自己下载的是.msi文件,在安装的过程中遇到了许多文件,网上大部分的Blog都是关于免安装包的安装方法,希望我的方法对大家有帮助. 1,下载 ...
-
Java通过继承thread类与实现Runnable接口实现多线程的区别
Java中线程的创建有两种方式: 1. 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2. 通过实现Runnable接口,实例化Thread类 一.通过继承T ...
-
【转载】计算机视觉(CV)前沿国际国内期刊与会议
计算机视觉(CV)前沿国际国内期刊与会议这里的期刊大部分都可以通过上面的专家们的主页间接找到1.国际会议 2.国际期刊 3.国内期刊 4.神经网络 5.CV 6.数字图象 7.教育资源,大学 8.常见 ...
-
使用JDT.AST解析java源码
在做java源码的静态代码审计时,最基础的就是对java文件进行解析,从而获取到此java文件的相关信息: 在java文件中所存在的东西很多,很复杂,难以用相关的正则表达式去一一匹配.但是,eclip ...
-
RHive
R + Hive = RHive 支持原创:http://blog.fens.me/nosql-r-hive/ R利剑NoSQL系列文章 之 Hive Hive介绍 Hive安装 RHive安装 RH ...
-
winform中执行任务,解决未响应界面
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { var coun ...
-
html5的结构
目录 一.新增的主体结构元素 1.1.article元素 1.2.section元素 1.3.nav元素 1.4.aside元素 1.5.time元素 1.6.pubdate元素 二.新增的非主体结构 ...
-
Java常用类库 读书笔记 二
1.Date类 常用操作方法: public Date () 构造方法,实例化Date类对象 public Data(long Date) ...