博主在unity5上的渲染结果,第一张图片是母校图书馆 ^ _ ^

但是随着游戏业的画面水准开始向电影水准发展,就需要我们有更好的理解HDR,来进一步把游戏像电影画质推进,这也是近几年的GDC和siggraph上都有一线studio在推HDR相关的技术,比如naughty dog10年的filmic tone mapping,11年crytek在siggraph里面提到的physically based hdr等。

首先看一下概念:
  • dynamic range:reinhard的<tone mapping>论文中定义:一个场景中最高亮度与最低亮度的比是dynamic range。
  • low dynamic range : 之所以出现这种情况是图像存储介质(打印纸,照片,电脑屏幕等)精度有限造成的,导致在range上没法完全记录一个场景的亮度信息,只能记录有限的一部分,比如游戏里常见的在rgba8上渲染,每个channel大于1的部分就被截取到1了。
  • high dynamic range : 准确讲是high dynamic range imaging,是指一种图像技术,它能让图像表示一个比原有技术(之前的LowDynamicRange)更大(greater)的dynamic range
    • 这样就可以更加准确和真实的描绘一个场景
进一步说,hdr的存在在于图像存储与表达介质的精度有限,这也是为何游戏引擎大佬在提的都是CG和电影画质,而不是和现实一样的:因为存储介质在这里摆着呢,没法和现实一样,cg是上限。
实际应用中,我们也看到了,hdr除了在range上发力,在精度上也可以更好,比如描绘发暗的场景,可以把亮度矫正到可以充分显示暗部细节。

oneMapping&ExposureAdjustment

这里除了数学上正确的亮度计算以外,要考虑到人眼视网膜的特点,比如之前的gamma就是一个根据视网膜特点,重新分配亮度信息,来让人眼在有限的显示精度下获得最大的信息量。视网膜有两个典型特点,这里通过tone mapping和exposure adjustment来解决:

  • 自动根据亮度矫正明暗:让我们晚上看东西也能比较清楚,一开灯眼睛要矫正一会回来
  • 局部适应性:比较经典的图是:
这里我们遇到两个问题,各用两个方案解决:
  • 曝光率问题---解决:exposure adjustment。和照相时候曝光原理差不多,白天亮曝光就短一些,晚上曝光长一些,编程时候就是计算render target的平均亮度,然后矫正,这样沙漠的白天和丛林的夜晚都可以在游戏中的rgba8上有一个良好的体现。在hable的论文里,这个属于不同的场景之间的处理问题范畴。
  • 压缩的过程中不可避免的涉及到重新分配亮度值,怎么做来得到更好的尽可能不失真的画面这个解决方案就是tone mapping

实际中也有把这个exposure adjustment并到tone mapping中去,其实还是分开比较好,因为这些概念是从摄像技术中来的,曝光就是曝光,tone mapping就是tone mapping。

  • zone:存储空间的亮度阶这么一个概念,比如print只有11个zone
  • middle grey:中间的亮度
  • dynamic range:指场景中最高亮度与最低亮度的比值
    • 这是一个最学术派的定义,具体上摄像师一般会追求细节还可以明辨的range
  • key:描述整个场景亮度的数值
  • dodging and burning:把高亮度的东西亮度降低为dodging,把低亮度的部分加亮为burning

Filmic Tonemapping Operators

The most common questions that I get about my GDC talk have to do with the tonemapping operators. In particular, I’ve always found that when I read through presentations for code snippets that I always miss something. Those 2.2s can be tricky! So this post is a quick reference for various operators that I talked about. Also, I copied and pasted this code from my RenderMonkey scene so there may be typos.

All of these examples use this HDR image of Habib’s killer condo. Also, click any image for the high-res version.

First off, there is good old linear. All it does is read the linear data, do an exposure adjustment, and adjust for the monitor’s gamma of 2.2.

view sourceprint?
1.float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
2.{
3.float3 texColor = tex2D(Texture0, texCoord );
4.texColor *= 16; // Hardcoded Exposure Adjustment
5.float3 retColor =pow(texColor,1/2.2);
6.returnfloat4(retColor,1);
7.}

Pretty simple. It looks like this. Click for high-res.

Don’t forget the pow(1/2.2). If you forget that step, it looks like this:

view sourceprint?
1.float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
2.{
3.float3 texColor = tex2D(Texture0, texCoord );
4.texColor *= 16; // Hardcoded Exposure Adjustment
5.float3 retColor = texColor;
6.returnfloat4(retColor,1);
7.}

Next up is Reinhard. There are many variations, bu I’ll do the simplest which is 1/(1+x). A common variation is to only do it on luminance. Don’t forget the pow(1/2.2) at the end!

view sourceprint?
1.float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
2.{
3.float3 texColor = tex2D(Texture0, texCoord );
4.texColor *= 16; // Hardcoded Exposure Adjustment
5.texColor = texColor/(1+texColor);
6.float3 retColor =pow(texColor,1/2.2);
7.returnfloat4(retColor,1);
8.}

Here it is with Haarm-Peter Duiker’s curve. This version is very similar to the Cineon node in Digital Fusion. The texture FilmLut refers tothis TGA file. No pow(1/2.2) necessary.

view sourceprint?
01.float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
02.{
03.float3 texColor = tex2D(Texture0, texCoord );
04.texColor *= 16; // Hardcoded Exposure Adjustment
05. 
06.float3 ld = 0.002;
07.floatlinReference = 0.18;
08.floatlogReference = 444;
09.floatlogGamma = 0.45;
10. 
11.float3 LogColor;
12.LogColor.rgb = (log10(0.4*texColor.rgb/linReference)/ld*logGamma + logReference)/1023.f;
13.LogColor.rgb = saturate(LogColor.rgb);
14. 
15.floatFilmLutWidth = 256;
16.floatPadding = .5/FilmLutWidth;
17. 
18.//  apply response lookup and color grading for target display
19.float3 retColor;
20.retColor.r = tex2D(FilmLut, float2( lerp(Padding,1-Padding,LogColor.r), .5)).r;
21.retColor.g = tex2D(FilmLut, float2( lerp(Padding,1-Padding,LogColor.g), .5)).r;
22.retColor.b = tex2D(FilmLut, float2( lerp(Padding,1-Padding,LogColor.b), .5)).r;
23. 
24.returnfloat4(retColor,1);
25.}

Next up is the optimized formula by Jim Hejl and Richard Burgess-Dawson. I completely forgot about Richard in the GDC talk, but he shares the credit with Jim. Sorry Richard!! Note that you don’t need the pow(1/2.2) for this one either.

view sourceprint?
1.float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
2.{
3.float3 texColor = tex2D(Texture0, texCoord );
4.texColor *= 16; // Hardcoded Exposure Adjustment
5.float3 x = max(0,texColor-0.004);
6.float3 retColor = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
7.returnfloat4(retColor,1);
8.}

Finally for the Uncharted 2 operator made by yours-truly. For this image I changed the defaults slightly for A and B.

Edit: Oops, in the previous version, I had the exposure bias outside the tonemapping function. Now it is fixed, where it is inside the tonemapping function.

view sourceprint?
01.floatA = 0.15;
02.floatB = 0.50;
03.floatC = 0.10;
04.floatD = 0.20;
05.floatE = 0.02;
06.floatF = 0.30;
07.floatW = 11.2;
08. 
09.float3 Uncharted2Tonemap(float3 x)
10.{
11.return((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
12.}
13. 
14.float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
15.{
16.float3 texColor = tex2D(Texture0, texCoord );
17.texColor *= 16; // Hardcoded Exposure Adjustment
18. 
19.floatExposureBias = 2.0f;
20.float3 curr = Uncharted2Tonemap(ExposureBias*texColor);
21. 
22.float3 whiteScale = 1.0f/Uncharted2Tonemap(W);
23.float3 color = curr*whiteScale;
24. 
25.float3 retColor =pow(color,1/2.2);
26.returnfloat4(retColor,1);
27.}

Hopefully, that should clear up most of the ambiguity about these operators.

HDRFilmic Tonemapping Operators相关推荐

  1. Filmic Tonemapping Operators

    http://filmicworlds.com/blog/filmic-tonemapping-operators/ 转载于:https://www.cnblogs.com/guochen/p/992 ...

  2. 图形渲染技术分享:《GTA V 》图形分析摘要

    环境渲染 最外层的 cubemap 是每一帧实时生成的,目的是简化后续真实反射的渲染. 这个 cubemap 是一张低精度的 128*128 纹理,每个面 30 左右 drawcall,都是地表天空等 ...

  3. Tone Mapping(简洁直观的Tonemapping介绍)

    转自:https://64.github.io/tonemapping/ What is tone mapping? Most monitors are capable of displaying R ...

  4. RxJS - Observables, observers 和 operators 简介

    RxJS 是响应式编程 (reactive programming) 强大的工具,今天我们将深入介绍 Observables 和 Observers 的内容,以及介绍如何创建自己的操作符 (opera ...

  5. HDR (automatic exposure control + Tonemapping + Bloom)

    <div class="markdown_views"><!-- flowchart 箭头图标 勿删 --><svg xmlns="http ...

  6. Effective C++ 读书笔记之Part2.Constructors, Destructors, and Assignment Operators

    5.Know what functions C++ silently writes and calls. 总结:编译器可以暗自为class创建default构造函数.copy构造函数.copy ass ...

  7. 一周一论文(翻译)——[VLDB 19] Minimizing Cost by Reducing Scaling Operators in Distributed Stream Processing

    Abstract 弹性分布式流处理系统能够动态地适应工作负载的变化.通常,这些系统通过向上或向下扩展来对输入数据的速率或资源利用水平做出反应.目标是优化系统的资源使用,从而降低其运营成本.但是,这种扩 ...

  8. Python编程基础:第九节 逻辑运算Logical Operators

    第九节 逻辑运算Logical Operators 前言 实践 前言 常用的逻辑运算共分为三种:与(and).或(or).非(not).与运算就是同真才真,有假则假:或运算就是有真则真,同假才假:非运 ...

  9. Blender文档翻译:Operators tutorial(操作教程)

    原文:https://wiki.blender.org/index.php/Dev:2.5/Source/Architecture/Operators/Tutorial 逐行解释操作如何工作的.首先解 ...

最新文章

  1. wpf每隔一小时_包河区徐河排涝站24小时不间断运作 11座区管泵站全面应战保安澜...
  2. MySQL——数据库的增删改操作
  3. 使用numpy与matplotlib.pyplot画图
  4. EF Code First学习笔记:数据库创建(转)
  5. mesh渲染到ui_在Unity中使用UGUI修改Mesh绘制几何图形
  6. 用Linux同时编辑两个文档,如何使用Vim编辑多个文件
  7. 佛山高新区构建大数据产业新生态
  8. 熟悉 scrollTop ,轻松做5个方面的事情。
  9. WebStorm配置(2016/11/18更新)
  10. 桌面图标拖不动怎么办?
  11. 关于LocalDateTime的全局返回时间带“T“的时间格式处理
  12. [Unity存档系统]简单介绍Unity常见存档系统二JSON以及使用方法
  13. 粗粒度和细粒度的区别
  14. java学习笔记————SSH
  15. 循环渐进NsDoor(一)
  16. matlab振动信号数据,Matlab在场地微振动信号数据处理中的应用
  17. android 爱普生打印机,安卓打印 爱普生推出智能iPrint新应用
  18. Vue.js入门学习--列表渲染--v-for遍历数组生成元素(四)
  19. Windows Server 2003 介绍
  20. 【HTML+CSS(六)】

热门文章

  1. 【正则表达式测试工具】使用正则表达式快速找出两列数据中不同的行
  2. MySQL常用存储引擎详解
  3. 方波正弦波(幅移键控发生器ASK)电路设计
  4. python制作图片居中加文字
  5. Transformer发展历史
  6. 20170321MFC05_Tab/File
  7. 写好SCI论文的语言技巧 --- 学术英语的表达 ---- 主动与被动语态如何取舍
  8. Apollo:planning模块概况
  9. python金融数据分析单元测试答案_智慧树知到Python金融数据分析答案_完整章节答案...
  10. Python画动漫人物(1)