紧跟前提文章,没有HDR.ToneMapping知识基础的同学请先阅读之前的文章:

HDR in Android 专栏

这篇文章主要是介绍在GLSL中处理HLG(hybrid-log-gamma 混合对数伽马曲线)的HDR tonemap SDR的渲染流程。

先看看Wiki有关HLG的概述:

混合对数伽马 (HLG) 传递函数是 BBC 和 NHK 联合开发的用于高动态范围 (HDR) 显示的传递函数。它向后兼容 SDR(伽马曲线)的传递函数。它被无线电工业和商业协会 (ARIB) 批准为 ARIB STD-B67。它还在 ATSC 3.0、数字视频广播 (DVB) UHD-1 第 2 阶段和国际电信联盟 (ITU) Rec. 2100中被定义。

HLG 传递函数和 HLG 格式都是免版税的。当接收器与 BT.2020 颜色容器兼容时,向后兼容性允许它们与现有传输标准一起使用,从而降低设备制造商和内容分发商的复杂性和成本。[1][10][9] 它们受 HDMI 2.0b、HEVC、VP9 和 H.264/MPEG-4 AVC、支持,并被 BBC iPlayer、DirecTV、Freeview Play、和YouTube。

HLG 被设计为更适合电视广播,其中其他 HDR 格式所需的元数据不能向后兼容非 HDR 显示器,消耗额外的带宽,并且还可能在传输中变得不同步或损坏。 HLG 定义了一个非线性光电传递函数,其中下半部分信号值使用伽马曲线,上半部分信号值使用对数曲线。在实践中,标准动态范围显示器将信号解释为正常(尽管能够在高光中显示更多细节),但 HLG 兼容显示器可以正确解释信号曲线的对数部分以提供更宽的动态范围。 与其他 HDR 格式相比,它不使用元数据。

HLG 传递函数向后兼容 SDR 的伽马曲线。 但是,HLG通常与 Rec.2020色域 一起使用。 在不兼容的设备上产生具有可见色调变化的去饱和图像。 因此,HLG 向后兼容 SDR-UHDTV,在仅支持 Rec.709色域 的常见 SDR 设备上显示,色彩会有所失真。

(详细Wiki:https://en.wikipedia.org/wiki/Hybrid_log%E2%80%93gamma#Description)

三个关键重点已加粗:

1、详细标准在ITU.BT2100中定义;

2、HLG曲线的本质;上半部分信号值使用对数曲线,下半部分信号值使用伽马曲线。

3、HLG要与BT.2020色域一起食用。

直接上GLSL,fragment shader代码:

#version 320 es
precision highp float;
uniform int bitMark;
uniform float maxLuminance;
uniform lowp float imgWidth;
uniform lowp float imgHeight;
uniform highp usampler2D tex_unsigned_y;
uniform highp usampler2D tex_unsigned_uv;
in  vec2 vTextureCoord;
out vec4 _FragColor;highp vec3 medialook_YuvConvertRGB_BT2020(highp uvec3 yuv, int normalize) {highp vec3 rgb;highp int y = highp int(yuv.x);highp int u = highp int(yuv.y);highp int v = highp int(yuv.z);float r = float(y - 64) * 1.164384                             + float(v - 512) * 1.717000;float g = float(y - 64) * 1.164384 - float(u - 512) * 0.191603 - float(v - 512) * 0.665274;float b = float(y - 64) * 1.164384 + float(u - 512) * 2.190671;rgb.r = r;rgb.g = g;rgb.b = b;if (normalize == 1) { rgb.r = r / 1024.0;  // [64, 960]rgb.g = g / 1024.0; rgb.b = b / 1024.0; } return rgb;
}const float A3 = 0.15f;
const float B3 = 0.50f;
const float C3 = 0.10f;
const float D3 = 0.20f;
const float E3 = 0.02f;
const float F3 = 0.30f;
highp vec3 hableToneMapping(highp vec3 color) {return (color * (color * A3 + B3 * C3) + D3 * E3) / (color * (color * A3 + B3) + D3 * F3) - E3 / F3;
}
highp float hableF(highp float inVal) {return (inVal * (inVal * A3 + B3 * C3) + D3 * E3) / (inVal * (inVal * A3 + B3) + D3 * F3) - E3 / F3;
}float ARIB_B67_A = 0.17883277f;
float ARIB_B67_B = 0.28466892f;
float ARIB_B67_C = 0.55991073f;
highp float arib_b67_inverse_oetf(highp float x)
{x = max(x, 0.0f);if (x <= (1.0f/2.0f))x = (x * x) * (1.0f / 3.0f);elsex = (exp((x - ARIB_B67_C) / ARIB_B67_A) + ARIB_B67_B) / 12.0f;return x;
}
highp float arib_b67_ootf(highp float x)
{return x < 0.0f ? x : pow(x, 1.2f);
}
highp float arib_b67_eotf(highp float x)
{return arib_b67_ootf(arib_b67_inverse_oetf(x));
}
highp float arib_b67_oetf(highp float x)
{x = max(x, 0.0f);if (x <= (1.0f / 12.0f))x = sqrt(3.0f * x);elsex = ARIB_B67_A * log(12.0f * x - ARIB_B67_B) + ARIB_B67_C;return x;
}float Lb = 0.1f;
float Lw = 302.0f;
float sys_gamma = 1.001f;
highp float bfiler(highp float x) {float b = sqrt(3.0 * pow((Lb/Lw), (1.0/sys_gamma)) );return max(0.0, ((1.0-b)*x + b) );
}#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c)
void main() {float samplerPosX = vTextureCoord.x * imgWidth;float samplerPosY = vTextureCoord.y * imgHeight;highp uint unsigned_y = texelFetch(tex_unsigned_y, ivec2(int(samplerPosX), int(samplerPosY)), 0).x;highp uint unsigned_u = texelFetch(tex_unsigned_uv, ivec2(int(samplerPosX / 2.0), int(samplerPosY / 2.0)), 0).r;highp uint unsigned_v = texelFetch(tex_unsigned_uv, ivec2(int(samplerPosX / 2.0), int(samplerPosY / 2.0)), 0).g;highp uvec3 yuv10bit = uvec3(unsigned_y >> bitMark, unsigned_u >> bitMark, unsigned_v >> bitMark);highp vec3 rgb10bit = medialook_YuvConvertRGB_BT2020(yuv10bit, 1);// 电 转线性光信号highp vec3 fragColor = 2.5 * vec3(arib_b67_eotf(bfiler(rgb10bit.r)), arib_b67_eotf(bfiler(rgb10bit.g)), arib_b67_eotf(bfiler(rgb10bit.b)) );// HDR线性 ToneMapping映射转成 SDR线性highp float sig;highp float sig_orig;sig = FFMAX(FFMAX3(fragColor.r, fragColor.g, fragColor.b), 1e-6);sig_orig = sig;float peak = maxLuminance / 100.0f;  //  MaxCLL / REFERENCE_WHITE(100);sig = hableF(sig) / hableF(peak);fragColor.r = fragColor.r * (sig / sig_orig);fragColor.g = fragColor.g * (sig / sig_orig);fragColor.b = fragColor.b * (sig / sig_orig);// 逆线性光信号,变回电fragColor = vec3(arib_b67_oetf(fragColor.r), arib_b67_oetf(fragColor.g), arib_b67_oetf(fragColor.b));_FragColor = vec4(fragColor.r, fragColor.g, fragColor.b, 1.0);
}

流程和PQ曲线没有区别(流程分析参考 仿照FFmpeg在GLSL中处理HDR.Tonemapping)差异就是在eotf电光转换 和 oetf光电转换 的传输函数上的区别。参数公式都是参考zimg模块中的源码提示。

也可以参照ITU.BT2100标准详细扣细节:https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-2-201807-I!!PDF-E.pdf

主要还是一下两个转换函数的table。

几处细节要解析一下:

步骤一(电转线性光信号)的bfiler对应的 β 的操作,Lb和Lw是暂时还不懂原理,个人感觉是一组魔术数(magic number)w3c组织研究过这一组参数的取值(具体研究链接:https://www.w3.org/Graphics/Color/Workshop/slides/Cotton2.pdf)

还是步骤一(电转线性光信号)后乘以2.5,这个对应的to_linear_scale,也是一个魔术数(magic number)这个不是固定值,看主观效果的喜好调整。

步骤三(逆线性光信号,变回电)这一次不是在想PQ感知量化曲线那样,用rec_709_oetf,因为HLG全程都是配套BT.2020色域使用的,所以就按照ARIB STD-B67标准的就好了。

That is all,欢迎讨论。

OpenGLSL中处理HDR.ToneMapping(HLG)相关推荐

  1. 仿照FFmpeg在GLSL中处理HDR.ToneMapping(下)

    FFmpeg 命令行 HDR 转 SDR ffmpeg -i planet_hdr.MP4 -vf zscale=t=linear:npl=100,format=gbrpf32le,zscale=p= ...

  2. 仿照FFmpeg在GLSL中处理HDR.ToneMapping(上)

    承接上文内容,纯干货,别看漏一个字. BT.601.709.2020标准下的YUV转RGB 上回我们已经把解码数据以short类型传递到gpu显存环境当中,下一步就是要正确的转换城rgb形式,翻查li ...

  3. 了解如何通过简单的技巧在Photoshop或GIMP中制作HDR图像

    HDR tone mapping is everywhere these days; it's sort of like Auto-Tuning equivalent of photography. ...

  4. 佳能hdr_(摄影后期)在佳能DPP中制造HDR,改善照片画质转载

    "所得即所见"--你信不信?翔哥是不信的. 因为人的眼睛能够感知的影调宽度要比照相机大得多,所以目前的数码相机拍到的并不是我们眼睛所看到的全部.为了弥补技术上的不足,只能借力后期P ...

  5. 计算机投影仪的作用是什么,投影机中的HDR功能是什么?

    投影机中的HDR功能是什么?它有什么作用?对于许多刚接触投影的新朋友来说,他们对这项功能的了解并不多. 通常,相机会使用HDR功能,使用此功能可以使照片更美丽. 因此,在将这种技术添加到投影机之后投影 ...

  6. 相机中的HDR、WDR和EDR分别指的是什么?

    相机中的HDR.WDR和EDR分别指的是什么? 随着人们对手机摄影的追求,现在也有越来越多的厂商让相机原生支持HDR效果. 一:HDR 1.HDR(High-Dynamic Range)翻译过来就是高 ...

  7. 两种HDR格式(HLG, HDR10)的理解

    1.HLG只在sps的vui中会携带信息,包括colour_primaries(=9),transfer_characteristics(=18),matrix_coefficients(=9) 2. ...

  8. 相机中的HDR和WDR分别指的是什么?

    HDR WDR 手机拍摄 随着人们对手机摄影的追求,现在也有越来越多的厂商让相机原生支持HDR效果,但你们是否知道HDR的概念呢?近来新兴起的WDR又是什么意思呢?这里小编做一个简单的小科普. HDR ...

  9. 关于IBL中,HDR图片转换为cubeMap参数的含义

    1.shader中参数的配置 // float PI=3.14152 invAtan = vec2(0.1591, 0.3183)=vec2(1/(2*PI), 1/PI); const vec2 i ...

最新文章

  1. Oracle中序列(Sequence)详解
  2. UA MATH636 信息论5 信道编码定理
  3. 4. Nest :module (Model)
  4. Pandas之:Pandas简洁教程
  5. JAVA语言基础-面向对象(IO:IO字符流、递归)
  6. 西南科技大学城市学院计算机专科,西南科技大学城市学院官网
  7. 冒泡排序法 - python版详解
  8. 关于信贷资产逾期计算口径和小微模型的经典问题与答案
  9. 常用的非线性激励函数
  10. Postman下载及WebApi测试遇到问题点
  11. ftp服务器上图片文件显示不出来,ftp服务器上图片文件显示
  12. Markdown表格中换行、合并单元格
  13. MIT 18.06 +线性代数的几何意义+3Blue1Brown 笔记
  14. 什么是宝塔面板?宝塔面板的作用和功能是什么?
  15. 使用k-means聚类anchors
  16. EMC选定计划首现国内厂商(迪思杰)
  17. 你没看错!TCL品牌日10万台洗衣机免费送
  18. matlab柱状斜线_matlab画柱状图,能否达到附件的效果。
  19. Python爬虫——aiohttp异步协程爬取同程旅行酒店评论
  20. [原创]推荐学习STL的好书(入门级别)

热门文章

  1. (附源码)计算机毕业设计SSM基于的企业人事管理系统
  2. 【Xasset谷歌分包】打包AAB并上传谷歌商店操作流程分享
  3. v2视频服务器退出系统怎么启动,v2会议视频系统
  4. JVM原理之完整的一次GC流程
  5. Open-world knowledge graph completion for unseen entitiesand relations via attentive feature aggreg
  6. 恒源云GPU租用保姆级教程,助力深度学习训练!
  7. 洛谷P1036选数题解--zhengjun
  8. 深度学习中的注意力机制(2017版)
  9. promise 实现分批请求
  10. Dalvik虚拟机操作码