我刚刚终于理解为什么rendertarget的format对颜色的影响为什么那么大了
r8g8b8a8 这种会有band artifacts
rgbafloat 这种浮点rt 的色带变化更为连贯(R11G11B10Float 里面有指数位 rgba16half这个也是有指数位的 RGBE R9G9B9E5这个E也是指数位
这几张都是hdr的rt
那上面的rt和下面rt相比 缺少的就是 让颜色看起来更为连贯的那些中间过渡的颜色
还有srgb空间在总的颜色空间占一部分那幅图可以辅助理解这个事情
要注意 两个空间 0 和1 是重合的 缺的是中间的 过渡地带
我以前总觉得这些事情 比如一个后处理我能抄出来就可以了 因为我没见过能很好的理解的人
也没有谁对我有这样严格的要求 其实存在很多对它们的原理理解很深刻的人 我见到一些 我平时见不到
是因为我水平不行 接触不到。。。。。就在那里洋洋自得很多年
============
开hdr 要给相机加tonemap才可以
不然我估计在linear space下开关hdr没效果 只是换rt最后又采样回去 精度仍然丢失
https://unity3d.com/cn/learn/tutorials/topics/graphics/high-dynamic-range-hdr
===============================
今天做了精确的测试 以及分析
总体看下来 在unity管线里面 一种正确的 hdr的pipeline是 开hdr 最后加tonemap
前面开hdr做的事情是 rendertarget的format变成 float 存储更高精度的数据
但如果不开tonemap 这些高精度数据没有办法remap会argb32或者srgb32 直接四舍五入了。。。都丢了
如果开tonemap的话 这个pass的位置 比较。。不正确 场景artists和ui和特效artists要的可能不一样 但是放多个colorgrading太费 放最后不能满足三个角色
所以放在前面 场景transparent之后是比较合理的
这样的问题就是后面在tonemap remap之后 如果太亮 接近1 颜色会丢 再加tonemap可以拿回来这样又会对前面调好的场景颜色叠加一层影响
====================
在线性空间下测试只开关hdr (无bloom和tonemap) 透明会有变化 其它颜色没有变化----这说明只开hdr的hdr是不对的(unity的hdr开关 只控制了rt format)
开了bloom或者tonemap再开关hdr才会有颜色变化
==================
linear+hdr的管线
srgb read float float float srgb write
这是原本的 为什么中间不用encode decode因为中间原本就是float 是线性空间 但最后因为有displaygamma所以最后一个pass要用srgb再压回去
(这里又有一点点问题 混淆了gamma encode和hdr到ldr remap这两件事 见注释1)
在线性空间做正确的计算
---------
ui pass 可以不需要float rt
==========
注释1
http://read.pudn.com/downloads169/ebook/782104/hdr_opengl.pdf
HDR--》LDR最基本变换 color =color/(color+1)
要有这个是因为! mobile平台不支持hdr的backbuffer。。。只有srgb
所以要这样转回去 不然直接截掉 clamp(0,1)那大于那部分 白算了 全丢了
而
为了从float rt 到 srgb rt所应用的 gamma encode 是pow0.45 配显示器pow2.2用 显示器为了配人眼pow0.45.。。。。。。