图片Alpha预乘的作用[转]
Premultiplied Alpha 这个概念做游戏开发的人都不会不知道。Xcode 的工程选项里有一项 Compress PNG Files,会对 PNG 进行 Premultiplied Alpha,Texture Packer 中也有Premultiplied Alpha 的选项。那么问题来了,Premultiplied Alpha 是什么呢?我被这个问题困惑了很久,之前搜到过 Nvidia的这篇文章,其实说的很清楚,只是当时有很多相关概念没搞清楚,所以没看懂。直到前几天读《Real Time Rendering》时终于搞懂了。
Alpha Blending
要搞清楚这个问题,先得理解Alpha通道的工作原理,如果你已经了解可以直接跳过。
最常见的像素表示格式是RGBA8888即 (r, g, b, a),每个通道8位,0-255。例如红色60%透明度就是 (255, 0, 0, 153),为了表示方便alpha通道一般记成正规化后的0-1的浮点数,也就是 (255, 0, 0, 0.6)。而 Premultiplied Alpha 则是把RGB通道乘以透明度也就是 (r * a, g * a, b * a, a),50%透明红色就变成了(153, 0, 0, 0.6)。
透明通道在渲染的时候通过 Alpha Blending 产生作用,如果一个透明度为 as 的颜色 Cs 渲染到颜色 Cd上,混合后的颜色通过以下公式计算,
以60%透明的红色渲染到白色背景为例:
也就是说,从视觉上,(255, 0, 0, 0.6)渲染到白色背景上 和 (255, 102, 102) 是同一个颜色。如果颜色以 Premultiplied Alpha 形式存储,也就是Cs已经乘以透明度了,所以混合公式变成了:
为什么要 Premultiplied Alpha 呢?
Premultiplied Alpha 后的像素格式变得不直观,因为在画图的时候都是先从调色板中选出一个RGB颜色,再单独设置透明度,如果RGB乘以透明度就搞不清楚原色是什么了。从前面的 Alpha Blending 公式可以看出,Premultiplied Alpha 之后,混合的时候可以少一次乘法,这可以提高一些效率,但这并不是最主要的原因。最主要的原因是:
没有 Premultiplied Alpha 的纹理无法进行 Texture Filtering(除非使用最近邻插值)。
以最常见的 filtering 方式线性插值为例,一个宽2px高1px的图片,左边的像素是红色,右边是绿色10%透明度,如果把这个图片缩放到1x1的大小,那么缩放后1像素的颜色就是左右两个像素线性插值的结果,也就是把两个像素各个通道加起来除以2。如果使用没有 Premultiplied Alpha 的颜色进行插值,那么结果就是:
如果绿色 Premultiplied Alpha,也就是 (0, 255 * 0.1, 0, 0.1),和红色混合后:

从上面的图里第三个颜色是没有 Premultiplied Alpha 的混合结果,对比第四个 Premultiplied Alpha 后颜色的结果,显然第四个颜色更符合直觉,第三个颜色太绿了,因为绿色通道没有乘以透明度,所以在线性插值的时候占了过大的权重。
所以 Premultiplied Alpha 最重要的意义是使得带透明度图片纹理可以正常的进行线性插值。这样旋转、缩放或者非整数的纹理坐标才能正常显示,否则就会像上面的例子一样,在透明像素边缘附近产生奇怪的颜色。
纹理处理
我们使用的PNG图片纹理,一般是不会 Premultiplied Alpha 的。游戏引擎在载入PNG纹理后回手动处理,然后再glTexImage2D传给GPU,比如 Cocos2D-x 中的 CCImage::premultipliedAlpha:
void Image::premultipliedAlpha() {
unsigned int* fourBytes = (unsigned int*)_data;
for (int i = ; i < _width * _height; i++) {
unsigned char* p = _data + i * ;
fourBytes[i] = CC_RGB_PREMULTIPLY_ALPHA(p[], p[], p[], p[]);
}
_hasPremultipliedAlpha = true;
}
而GPU专用的纹理格式,比如 PVR、ETC 一般在生成纹理都是默认 Premultiplied Alpha 的,这些格式一般是GPU硬解码,引擎用CPU处理会很慢。
总之 glTexImage2D 传给 GPU 的纹理数据最好都是 Multiplied Alpha 的,要么在生成纹理时由纹理工具 Pre-multiplied,要么载入纹理后由游戏引擎或UI框架 Post-multiplied。
原文地址:http://boundary.cc/2015/07/why-premultiplied-alpha/
图片Alpha预乘的作用[转]的更多相关文章
- alpha预乘
将(r,g,b,a)变为(r*a,g*a,b*a,a)的操作称为alpha预乘. 对于alpha预乘的图片,应使用(One,OneMinusSrcAlpha)进行混合. 使用alpha预乘方式混合出来 ...
- 图片本地预览 flash html5
dataURI 一种能够在页面嵌入外部资源的URI方案.能够降低图片或者样式表的http请求数量,提高效率. ie8把dataURI 的属性值限制在32k以内. 图片本地预览: 由于安全原因,通过fi ...
- iOS HTML图片本地预览
引言 相信用过苹果手机的童鞋,会发现很多新闻类的应用,都可以实现HTML图片本地预览,那么这是如何实现的呢?本文将深入阐述其中的原理. 关于此功能,我还实现了一个DEMO,大家可以点击此访问更详细内容 ...
- 图像处理术语解释:什么是PRGBA和Alpha预乘(Premultiplied Alpha )
☞ ░ 前往老猿Python博文目录 ░ Alpha预乘(Premultiplied Alpha)和PRGBA 一般来说四通道图像数据保存的都是ARGB或RGBA,其R.G.B值还没有进行任何透明化处 ...
- 图像处理术语解释:灰度、色相、饱和度、亮度、明度、阿尔法通道、HSL、HSV、RGBA、ARGB和PRGBA以及Premultiplied Alpha(Alpha预乘)等基础概念详解
☞ ░ 前往老猿Python博文目录 ░ 一.引言 由于老猿以前没接触过图像处理,在阅读moviepy代码时,对类的有些处理方法代码看不懂是什么含义,为此花了4天时间查阅了大量资料,并加以自己的理解和 ...
- jQuery Lightbox图片放大预览
简介:jQuery Lightbox图片放大预览代码是一款可以在用户点击页面中的小图片时,将该图片的高清版本以Lightbox的方式放大显示在页面的中间,提高用户的体验度. 效果展示 http://h ...
- js实现FileUpload选择图片后预览功能
当asp.net的FileUpload选择一个图片后不需要上传就能显示出图片的预览功能, 代码: <%@ Page Language="C#" AutoEventWireup ...
- Android 举例说明自己的定义Camera图片和预览,以及前后摄像头切换
如何调用本地图片,并调用系统拍摄的图像上一博文解释(http://blog.csdn.net/a123demi/article/details/40003695)的功能. 而本博文将通过实例实现自己定 ...
- 巧用weui.gallery(),点击图片后预览图片
要在页面需要加载的JS文件: <script src="../js/libs/weui.min.js"></script> 可以去weui的文档中下载,这是 ...
随机推荐
- 深入详解美团点评CAT跨语言服务监控(七)消息分析器与报表(二)
CrossAnalyzer-调用链分析 在分布式环境中,应用是运行在独立的进程中的,有可能是不同的机器,或者不同的服务器进程.那么他们如果想要彼此联系在一起,形成一个调用链,在Cat中,CrossAn ...
- thinkphp5 列表页数据分页查询3-带搜索条件
先加载模板然后在前端HTML页面请求数据 /** * 加载列表页模板 * @author 冯广福 */ public function index() { LogWriteService::write ...
- Pullword 分词工具
def get_response(self, txt): """ 热词工具 """ datas = [] request_lists = [ ...
- SQL Server 数值四舍五入,小数点后保留2位
1.round() 函数是四舍五入用,第一个参数是我们要被操作的数据,第二个参数是设置我们四舍五入之后小数点后显示几位. 2.numeric 函数的2个参数,第一个表示数据长度,第二个参数表示小数点后 ...
- 基于tornado的文件上传demo
这里,web框架是tornado的4.0版本,文件上传组件,是用的bootstrap-fileinput. 这个小demo,是给合作伙伴提供的,模拟APP上摄像头拍照,上传给后台服务进行图像识别用,识 ...
- oracle rac的启动与停止
引言:这写篇文章的出处是因为我的一名学生最近在公司搭建RAC集群,但对其启动与关闭的顺序和原理不是特别清晰,我在教学工作中也发现了很多学员对RAC知识了解甚少,因此我在这里就把RAC里面涉及到的最常用 ...
- jquery位置问题
在页面中添加jquery时,一定要把jquery放在其他js文件前面!不然会出现"$ is not defined", 导致js无法正常运行.
- AM软件中reconfig的方法
1.先进入admin 2.选数据库名: 比如这个HULLBLOCK/AFTBLOCKS 3. 选好数据库后在命令栏依次输入以下命令,输入每一行后回车一下: FROM DB HULLBLOCK/AF ...
- windows 控制台cmd乱码(及永久修改编码)的解决办法
注册 windows 控制台cmd乱码(及永久修改编码)的解决办法 转载 2017年11月02日 22:49:52 1067 windows 控制台cmd乱码的解决办法 我本机的系统环境: OS Na ...
- win10和ubuntu16.04双系统Geom Error
报错信息: Geom Error Reboot and Select proper Boot device or Insert Boot Media in selected Boot device a ...