quick中使用JPG+mask文件制作刀塔传奇中的遮罩效果

大家都知道,刀塔传奇中使用了大量的jpg图片加mask遮罩来达到图片透明的效果。
这样做最大的好处就是包小,因为jpg格式比png格式小太多,尤其是大图,即便加上mask文件也小很多,因为mask文件的特殊性,其大小真的小的可怜!
首先,我们需要一张jpg图片和一个mask文件,mask文件如何制作呢?请参考下面的文章,看了文章之后,你也就知道为啥我说mask文件的真的很小了!
http://www.cnblogs.com/U-tansuo/p/JPG-Mask.html?ADUIN=25584762&ADSESSION=1422190686&ADTAG=CLIENT.QQ.5389_.0&ADPUBNO=26441
现在,我们就有两个文件了,我的两个文件是这个样子滴:
发现传上来的图很容就挂了啊,大家自行去一楼下载附件,所用资源都再里面

有了这两文件之后,我们还需要一个shader文件,内容如下:
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D u_mask_texture;

void main() {
vec4 mask_FragColor = texture2D(u_mask_texture, v_texCoord);
gl_FragColor = v_fragmentColor*texture2D(CC_Texture0, v_texCoord);
gl_FragColor.a = mask_FragColor.r;
}
三个后面会传个附件。
有了这三个文件后在你的MainScene中添加如下代码:


 self.shipBody = display.newSprite("b1302.jpg"):addTo(self)
 self.shipBody:setPosition(display.cx, display.cy)
 local fileUtiles = cc.FileUtils:getInstance()
 local defaultVert = fileUtiles:getStringFromFile("default.vsh")
 local maskFrag = fileUtiles:getStringFromFile("mask.fsh")
 local glprogram  = cc.GLProgram:createWithByteArrays(defaultVert, maskFrag)
 local glprogramstate = cc.GLProgramState:getOrCreateWithGLProgram(glprogram)
 cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_I8)
 local texture = cc.Director:getInstance():getTextureCache():addImage("b1302_mask.png")
 cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_RGB_A8888)
 glprogramstate:setUniformTexture("u_mask_texture", texture)
 self.shipBody:setGLProgramState(glprogramstate)





```
代码很简单,就是加载shader然后设置mask文件,再赋给精灵

需要注意的是加载mask的时候设置下加载的格式,因为mask只是一个位图,所以用I8格式加载就好。关于如何使用指定格式加载图片,参考我前面的帖子
http://www.cocoachina.com/bbs/read.php?tid-283098.html
总的来说代码很简单,没啥特别的地方。
另外推荐一篇文章,可以阅读以下,其中提到了如何在C++中直接做处理。
http://www.hippyless.com/blog/?p=245

附件在此=====================

:2: 这个必须精!

刀哥。厉害啊。先。MARK 。明天看

从技术上来讲,是好文章,开阔了思路。 之前页游大多数有这样做的,目的是web传输下载更快捷。

但从实用角度来讲,

这个代价太大,只是为了减小发布包大小。

1.要制作png & mask
2.jpg 导致的内存上涨
3.shader合成的代价
4.代码复杂度
等等

如果大家想把发布包弄的很小,建议优化png. 使用pngquant来压缩PNG 一般压缩可以达到 70% 左右。
再配合热更新方案,发布包可以做的很小。

恩,我这里应为有个场景只有一张图片有这个特殊需求,所以就用了这种方式!

pngquant是个好东东啊,之前竟然不知道! :12:

嗯, pngquant 的方案,代价小, 很实用。

不存在平台兼容性。已使用多年。

其实zrong = jacky 兄弟之前提供过MaskedSprite

在display.lua
function display.newMaskedSprite(__mask, __pic)

恩,jacky写的filter也都看过来了!之前写filter的文章的只用描边的例子讲解了下!
因为有时候不是直接初始化一个精灵,而是从某个地方取图片,然后再进行处理,所以就尝试直接调用gl来做,顺便分享下!

你可以看看 function display.newMaskedSprite(__mask, __pic) 顺便测试下效果。 和你的效果应该是一模一样的。
免得你去封装了, quick已经提供了 :2: , 哈哈。

这个处理完全是为了减少包大小,如果不是有这种极限要求的话还是不要用了,增加美术程序工作量

我勒个去!这个工具绝壁爽歪歪了,简单高效压缩,效果堪称无损啊

绝壁是个好东东啊

pngquant 我们就是使用的这个。不过如果用pngquant+上刀哥的办法是不是能让包更小?我们现在压缩完包有23M 我们的要求是10M。。。。

display.newMaskedSprite(__mask, __pic) 在3.3里好像没有, 我看3.2还有呢,为什么去掉了?还是改名字了?

自己仿照3.2的,封装一个。

mark--------必须支持啊

pngquant 是把png转成了png8,质量会变差,和fireworks转成png8的效果差不多。

视觉上真心看不出来