首页 > 其他分享 >色调映射

色调映射

时间:2023-03-31 15:46:29浏览次数:59  
标签:HDR 映射 色调 vec3 mapped 曝光

前言

​ 本篇将介绍什么是色调映射,为什么需要色调映射,HDR,HDRI,当前流行的色调映射算法

HDR和色调映射

  • 在谈及色调映射前我们先来看看平时经常听到的HDR和HDRI

    • HDR: High-Dynamic Range(高动态范围)的缩写,可以理解为一个 CG 的概念,常出现在计算机
      图形学与电影、摄影领域中
    • HDRI: High-Dynamic Range Image 的缩写,即 HDR 图像,高动态范围图像

    现代照相机是无法捕捉到人眼能看到的所有细节,这意味着即使使用分辨率最高的照片,所拍摄的场景也不能真实地还原。为了解决这一问题,需要拍摄同一场景的多张照片,并将它们合并。但是不能合并同一张照片,需要拍摄一张曝光均衡的照片,然后拍摄更多曝光不足和曝光过度的照片。然后合并这些照片,最终即可得到更多的细节都在高光和阴影的图片。这一合并过程就是色调映射

    动态色调映射是用来使图像在显示器上看起来很真实。色调映射会到降低图像中的色调值,使其适合在显示器上观看(因为屏幕的颜色范围是[0,255])。例如,具有100,000:1动态范围的 HDR 照片需要进行色调映射,以便色调值落在1和255之间

    那为什么不能简单地复制呢?因为在帧缓冲(Framebuffer)中时,亮度和颜色的值是默认被限制在[0,1],若将一个高范围的HDR照片简单的复制到帧缓冲中,会导致大于1范围的被限制为1。可能的效果如下图所示,可以看到大部分区域都是白色,这并不是我们想要的效果
    image-20230331111539287

  • 色调映射的定义:色调映射(Tone mapping)又称色调复制(tone reproduction)是将宽范围的照明级别拟合到屏幕有限色域内的过程。色调映射与表示高动态范围的 HDR 和 HDRI 密切相关

  • 渲染中的色调映射:HDR渲染和合成照片很相似,用更大范围的颜色值进行渲染从而获取大范围的黑暗与明亮的场景细节,最后将所有HDR值转换成在[0.0, 1.0]范围的LDR(Low Dynamic Range,低动态范围),且它可以在渲染过程的任何阶段完成.因为显示器的颜色范围在[0,1],我们肯定要做一些转换从而使得当前的HDR颜色值符合显示器的范围。简单地取平均值重新转换这些颜色值并不能很好的解决这个问题,因为明亮的地方会显得更加显著,所以我们能做的是用一个不同的方程来转换这些HDR值到LDR值

  • 使用色调映射的原因:进行大幅度的对比度衰减将场景亮度变换到可以显示的范围,同时要保持图像细节与颜色等表现原始场景的重要信息

  • 根据应用的不同,色调映射的目标可以有不同的表述。在有些场合,生成“好看”的图像是 主要目的,而在其它一些场合可能会强调生成尽可能多的细节或者最大的图像对比度。在实际的渲染应用中可能是要在真实场景与显示图像中达到匹配

色调映射算法

  • 色调映射算法大致分为两种

    1. 全局映射

      对于图片中任一像素我们不考虑它处于明部还是暗部,所有像素的映射方式是相同的。这种算法的好处是很快,但图像较为平坦

    2. 局部映射

      局部映射会考虑图像的亮区或暗区中像素的位置,根据像素的空间特性对其进行处理,从而得到更多的细节。该算法会慢点,但效果更好

​ 以下我们介绍两种流行的算法

Reinhard

​ Reinhard色调映射算法将所有亮度值平均地分布到LDR,增加了亮度值较低的像素的亮度,同时为高亮度像素提供了较低的对比度。我们将Reinhard色调映射应用到之前的片段着色器上,并且为了更好的测量加上一个Gamma校正过滤(包括SRGB纹理的使用)

​ 函数:$\large $$\large V_{out} = \frac{V_{in}}{V_{in} + 1}$

void main()
{             
    const float gamma = 2.2;
    vec3 hdrColor = texture(hdrBuffer, TexCoords).rgb;

    // Reinhard色调映射
    vec3 mapped = hdrColor / (hdrColor + vec3(1.0));
    // Gamma校正
    mapped = pow(mapped, vec3(1.0 / gamma));

    color = vec4(mapped, 1.0);
}   

该算法是倾向明亮的部分,暗的部分不会那么精细
image-20230331141905949

伽马压缩(Gamma Compression)

HDR图片包含不同曝光(图像的明暗程度)等级的细节,若需要控制图像的明亮程度,我们可以实现伽马压缩(曝光参数).如有一个场景要展现日夜交替,在白天使用低曝光,在夜间使用高曝光,就像人眼调节方式一样

函数:$\large V_{out} = AV_{in}^\gamma,A > 0 \space and \space 0 < \gamma < 1 $.该函数基于非线性的伽马压缩技术

uniform float exposure;	//默认为1

void main()
{             
    const float gamma = 2.2;
    vec3 hdrColor = texture(hdrBuffer, TexCoords).rgb;

    // 曝光色调映射
    vec3 mapped = vec3(1.0) - exp(-hdrColor * exposure);
    // Gamma校正 
    mapped = pow(mapped, vec3(1.0 / gamma));

    color = vec4(mapped, 1.0);
}  

通过改变曝光因子,我们可以看见场景的很多细节,而这些细节可能在LDR渲染中都已经被丢失。比如说隧道尽头,在正常曝光下木头结构隐约可见,但用低曝光木头的花纹就可以清晰看见了。对于近处的木头花纹来说,在高曝光下会能更好的看见
image-20230331143531298

reference

Understanding HDR and Tone Mapping (skylum.com)

[Tone mapping | Indigo Renderer](https://www.indigorenderer.com/documentation/manual/rendering-with-indigo/camera/tone-mapping#:~:text=Tone mapping changes the brightness,immediately to the rendered image.)

[HDR - LearnOpenGL CN (learnopengl-cn.github.io)](https://learnopengl-cn.github.io/05 Advanced Lighting/06 HDR/)

Tone Mapping To Achieve High Dynamic Range (HDR) | by Vincent Tabora | High-Definition Pro | Medium

标签:HDR,映射,色调,vec3,mapped,曝光
From: https://www.cnblogs.com/chenglixue/p/17276471.html

相关文章

  • windows键盘映射Caps与Esc互换
    1.查找windows的键值对照表从对照表中找到需要更改映射的按键的值,windows的键值对照表放在文末。CapsLock:3A00Esc:0100Backspace:0E00Insert:52E02.创建ScanCodeMap打开cmd或者powershell,然后输入“regedit”回车打开注册表编辑器找到以下路径:HKEY_LOCAL_MACHINE......
  • Mybatis动态SQL映射
    Mybatis动态SQL映射动态SQL映射1.if结构test里面的and或or必须小写2.trim-if多条件结构3.where-if多条件结构4.choose-when-otherwise多选一结构5.foreach循环结......
  • Mybatis-Plus自定义TypeHandler映射JSON类型为List
    1.实体类注意点:别忘了autoResultMap=true@Data@TableName(value="report",autoResultMap=true)publicclassReportimplementsSerializable{privates......
  • 【SpringMVC-03】拦截器+类型转换器+数据校验以及异常映射,文件上传和下载
    第一章拦截器(重点)1.概念1.1使用场景1.1.1生活中坐地铁的场景为了提高乘车效率,在乘客进入站台前统一检票:1.1.2程序中的校验登录场景在程序中,使用拦截器在请求到达具体......
  • JPA的一对多映射(单向)
     JPA的一对多映射(单向)Postedon  CN.programmer.Luxh 注意:这里说的是一对多的单向关联,不是一对多的双向关联。实体Author:作者。实体Book:作者写的......
  • Winform/Csharp中使用Linq的Where条件筛选、Select字段映射(左外连接并设置无匹配时默
    场景Java8新特性-Stream对集合进行操作的常用API:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126070657上面讲的是在Java中使用Stream中对集合的常用操......
  • 关于mybatis创建的mapper映射路径不对导致的系列报错
    今天在写mybatis项目的时候,使用注解发现无法使用别名,添加ResultMap的时候直接报错显示无法解析。经过百度了好久也是成功的发现了问题的所在,就是这个:这个路径创建的时候......
  • mybatis的resultMap部分映射字段失败
    出现这种情况,一般是sql语句多表查询时,返回的字段出现重复情况,比如a对象分别有handle_status属性,和b嵌套对象,但是b对象里面也有handle_status属性,两张表进行关联查询,并且要......
  • 视差映射
    视差映射ParallaxMapping 主要为了赋予模型表面遮挡关系的细节。引入了一张高度图可以和法线贴图一起使用,来产生一些真实的效果高度图一般视为顶点位移来使用,此时......
  • Winform/Csharp中连接Mysql并执行指定sql,查询结果通过反射映射为对象的List
    场景Winform中连接Mysql8并查询表中数据进行显示:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/120395988在上面连接Mysql的基础上,如果需要连接Mysql并执......