修改后的简化版ACES Tonemap与原版效果是否一致?
简化版ACES色调映射与原版ACESFilmicToneMapping的效果差异分析
我知道本可自行对比差异,但作为业余人士,无法分辨自己修改的简化版ACES Tonemap与原版ACESFilmicToneMapping的效果区别,恳请提供技术建议。
简化版代码
vec3 tMACES(vec3 sample) { sample = mat3(0.59719, 0.076, 0.0284, 0.35458, 0.90834, 0.13383, 0.04823, 0.01566, 0.83777) * sample; sample = (sample * (sample + 0.0245786) - 0.000090537) / (sample * (0.983729 * sample + 0.432951) + 0.238081); return mat3(1.60475, -0.10208, -0.00327, -0.53108, 1.10813, -0.07276, -0.07367, -0.00605, 1.07602) * sample; }
原版ACESFilmicToneMapping代码
// source: https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs vec3 RRTAndODTFit( vec3 v ) { vec3 a = v * ( v + 0.0245786 ) - 0.000090537; vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081; return a / b; } // this implementation of ACES is modified to accommodate a brighter viewing environment. // the scale factor of 1/0.6 is subjective. see discussion in #19621. vec3 ACESFilmicToneMapping( vec3 color ) { // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT const mat3 ACESInputMat = mat3( vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source vec3( 0.35458, 0.90834, 0.13383 ), vec3( 0.04823, 0.01566, 0.83777 ) ); // ODT_SAT => XYZ => D60_2_D65 => sRGB const mat3 ACESOutputMat = mat3( vec3( 1.60475, -0.10208, -0.00327 ), // transposed from source vec3( -0.53108, 1.10813, -0.07276 ), vec3( -0.07367, -0.00605, 1.07602 ) ); color *= toneMappingExposure / 0.6; color = ACESInputMat * color; // Apply RRT and ODT color = RRTAndODTFit( color ); color = ACESOutputMat * color; // Clamp to [0, 1] return saturate( color ); }
核心差异与技术建议
核心差异点
- 缺失曝光缩放逻辑:原版开头的
color *= toneMappingExposure / 0.6;是适配更亮观看环境的关键调整,简化版完全省略后,高动态范围场景下的亮度表现会和原版出现明显偏差——比如暗部细节丢失、亮部压制不足。 - 缺少颜色饱和截断:原版最后用
saturate(color)将颜色值限制在[0,1]区间,避免超范围像素出现显示异常;简化版无此步骤,极端场景下可能出现颜色溢出(比如过曝区域变成异常色调)。 - 细微矩阵精度差异:原版输入矩阵的第二个元素是
0.07600,简化版写成0.076,数值精度差异极小,对视觉效果的影响几乎可以忽略。
实用技术建议
- 补全曝光控制:如果要保留简化版的简洁性,需在矩阵转换前添加曝光调整逻辑,比如:
测试时可将vec3 tMACES(vec3 sample, float exposure) { sample *= exposure / 0.6; // 对齐原版的曝光缩放比例 // 后续原有逻辑... }exposure设为1.0,对应原版默认效果。 - 添加颜色截断:在返回结果前必须加上颜色值限制:
避免极端场景下的颜色显示异常。sample = clamp(sample, 0.0, 1.0); // 和原版saturate功能一致 return ...; - 精准对比效果:
- 使用高动态范围测试图(包含极暗、极亮区域的场景),分别用两个函数渲染,对比暗部细节保留、亮部过曝压制、色彩还原三个维度的表现。
- 固定所有参数(如曝光值设为1.0),用图像差异工具(如Photoshop的差异图层)查看像素级区别,直观定位差异区域。
内容的提问来源于stack exchange,提问作者user19672105
相关产品推荐
相关产品推荐

