虽然添加的 saturate
调用不会神奇地使数值不精确度完美,但它至少可以改善超出有效 [0,1] 范围的 nonPMAGamma.rgb
值(如 gammaPMAColor.rgb / gammaPMAColor.a <= 1.0
非添加剂 PMA 颜色)。不幸的是,我想不出在线性色彩空间中启用PMA Vertex Color
的代码路径的完美解决方案。但是,由于只有非常低的不透明度值会触发数值问题(您提到的 1/255 PMA rgb 值,较低的 rgb*a 值到达顶点着色器时为 0),我认为这应该不会太成问题.我假设因为应该在输出上保持输入值的升序,较低的输入值会导致较低的输出值而不会将 1、2、3 更改为 1、3、2。或者您认为在某些情况下它会使情况变得更糟?如果是这样,请告诉我们您的想法(也描述输入 rgba 颜色值)。
一般来说,您是正确的,不幸的是 PMA 将低于 1/255 的 PMA 值丢弃为 0,其中直接 alpha 顶点颜色仍然可以将它们传输到顶点着色器。就像例如r*a = 10/255 * 10/255。这些值在 gamma 空间中无关紧要,因为在输出合并阶段,当 0.39/255 将作为 0 混合到目标缓冲区时,它们会产生 0 影响。虽然这些值可以在浮点缓冲区的线性空间中相加,请考虑低伽马空间值在转换为线性空间值后会导致更低的值。例如。 0.39/255 gamma 等于 6.47e-7 或 0.000165/255 线性,而 1/255 gamma 的下一个可显示(8 位)更高的 gamma 值是线性空间中的 5.08e-6 或 0.0013/255。我认为这实际上永远不会成为一个真正的问题。理论上在 10 位显示设备上可能是这样,但前提是整个场景完全黑暗。
不幸的是,您提到的其他解决方案都有其缺点(性能成本),因此我们不想简单地强迫用户使用其他代码路径:
1) 您当然可以使用直接 alpha 并禁用PMA Vertex Color
,但是这将需要对附加插槽进行额外的绘制调用。
2)您可以使用tint black``canvas group compatible
工作流程单独传递alpha值。不幸的是,这为目标画布上所有传入的网格顶点数据添加了一个顶点属性,需要“画布”“附加着色器通道”。在某些情况下这可能可以忽略不计(或者它可能已经在使用中),但对于其他一些情况可能非常糟糕。
总而言之,不幸的是,我知道没有涵盖所有情况且没有缺点的完美解决方案。 PMA Vertex Color
可能不是您情况的最佳解决方案,因此您可能希望使用所讨论的任何其他解决方案。
如果我忘记了什么或误解了你,请告诉我,如果我写的任何东西不清楚并且在机器翻译中丢失了。我们很乐意尽可能解决任何问题。
也感谢您的客气话! 🙂 我也祝愿您、您的项目、您的团队和您的家人一切顺利! 🙂
While the added saturate
call not magically makes the numerical imprecisions perfect, it at least improves nonPMAGamma.rgb
values that exceed the valid [0,1] range (as gammaPMAColor.rgb / gammaPMAColor.a <= 1.0
for non-additive PMA colors). Unfortunately I cannot think of a perfect solution for the PMA Vertex Color
enabled codepath in linear color space. However, as only very low opacity values are triggering the numerical issue (1/255 PMA rgb values as you mentioned, with lower rgb*a values arriving at the vertex shader as 0), I don't think that this should be too problematic. I assume that because ascending order of input values should be maintained on the output, lower input values resulting in lower output values without changing 1,2,3 to 1, 3, 2. Or do you think it makes the situation worse for some cases? If so, please let us know what situation you have in mind (also describing input rgba color values).
In general you are correct that unfortunately PMA is discarding PMA values below 1/255 as 0 where straight alpha vertex color can still transfer them to the vertex shader. Like e.g. r*a = 10/255 * 10/255. Such values didn't matter in gamma space, since they would have 0 effect during the output merger stage when 0.39/255 would be blended to the destination buffer as 0. While these values could add up in linear space in a floating point buffer, please consider that low gamma space values result in even much lower values after being converted to linear space values. E.g. 0.39/255 gamma being equal to 6.47e-7 or 0.000165/255 linear while the next displayable (8bit) higher gamma value of 1/255 gamma is 5.08e-6 or 0.0013/255 in linear space. I assume that this will in reality not ever be a real problem. Theoretically on 10 bit display devices it could be, however only if the whole scene is completely dark.
The other solutions that you mentioned unfortunately all have their drawbacks (performance cost), so we do not want to simply force the user to use another code path:
1) You can use straight alpha of course and disable PMA Vertex Color
, this however will then require additional draw calls for additive slots.
2) You can use the tint black
canvas group compatible
workflow to pass the alpha value separately. Unfortunately this comes with an added vertex attribute for all passed in mesh vertex data at the target Canvas, requiring the Canvas
Additional shader channel
. This may be negligible in some cases (or it may be in use already), but may be very bad for some other scenarios.
So to summarize, unfortunately I know of no perfect solution that covers all cases and has no drawbacks. PMA Vertex Color
may of not be the best solution for your case, so you might want to use any of the other solutions discussed.
If I forgot something or misunderstood you, please let me know, also if anything that I wrote is unclear and lost in machine translation. We are happy to fix any issues wherever possible.
Thanks also for your kind words! 🙂 I also wish you all the best for you, your project, your team and your families! 🙂