微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 PBR 材料中生成适当的 alpha透明度值

如何解决从 PBR 材料中生成适当的 alpha透明度值

我正在编写 PBR 着色器,并且正在尝试确定生成图像输出的 alpha 值的正确方法。目标是获得“预乘 alpha”的最终图像,以便稍后可以将其与另一个过度合成操作一起使用(例如,将其合成到另一个背景图像上)。这一切都很好,除了透明表面上的镜面高光。

阅读这篇文章https://google.github.io/filament/Filament.md.html#lighting/transparencyandtranslucencylighting

特别是:

观察一个窗口,你会看到漫反射是 透明的。另一方面,镜面反射越亮, 窗口出现的不透明程度越低。这个效果可以看图 63:场景正确地反射到玻璃表面 但是 太阳的镜面高光足够亮,看起来不透明。

它们还包括代码片段:

// baseColor has already been premultiplied
vec4 shadeSurface(vec4 baseColor) {
    float alpha = baseColor.a;

    vec3 diffuseColor = evaluateDiffuseLighting();
    vec3 specularColor = evaluatespecularLighting();    

    return vec4(diffuseColor + specularColor,alpha);
}

渲染玻璃时,金属级别将为 0,因此它根本不会从 baseColor 中拉出,而只是使用镜面反射级别。这一切都是有道理的,这意味着即使在透明玻璃上仍会出现镜面高光,如上述引用。我不想在最后只乘以 alpha,因为我的 baseColor 纹理已经是一个预乘的 alpha 图像,例如包含贴花的东西。例如,假设我正在绘制一块玻璃板,上面贴有字母“A”的贴纸。

我的问题是:对于在玻璃的透明部分具有镜面高光的像素,alpha 值应该是多少才能在下游合成?根据上面的代码,alpha 将为 0,这将使 Over 操作稍后表现不佳。我这么说是因为预乘 alpha 的一个属性是 max(R,G,B) A。这将导致过度操作在镜面高光和它正在合成的背景之间添加,吹出最终图像。 我应该将 alpha 设置为 max(specular,alpha),以便为这些像素提供更有用的 alpha 值吗?有没有更“正确”的方法来处理这个问题? 谢谢

解决方法

预乘方法背后的想法是我们假设 alpha/不透明度仅影响漫反射(即进入材料/表面的光),而假设镜面反射不受影响(至少对于这种情况)电介质,光简单地从未着色的表面反射)。

本质上,你应该:

return vec4(diffuseColor * alpha + specularColor,alpha);

其中 alpha 与漫反射颜色“预乘”,而镜面反射颜色保持全强度(应该如此)。

您的混合模式也需要效仿:我的头顶一个/一个用于源/目标颜色,因为需要渲染颜色以叠加的方式。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。