Cocos2d-js使用ETC1格式的图片

一、前言

关于为什么使用ETC1格式的图片以及ETC纹理压缩和Alpah通道处理。在这里不再细说。有兴趣的朋友可以看看下面的文章:

1、http://blog.csdn.net/langresser_king/article/details/9339313

2、http://malideveloper.arm.com/resources/sample-code/etcv1-texture-compression-and-alpha-channels/

从技术上来说,主要是通过工具和程序来解决ETC1格式的不带alpha信息和透明问题。

工具可以用:

Mali(http://malideveloper.arm.com/resources/tools/mali-gpu-texture-compression-tool/)

TexutrePacker(http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/TexturePacker.shtml)

程序主要用工具生成带有alpha信息的纹理图片。编写shade代码来实现。

 

二、使用一张纹理图片

1、创建一张原始图片和带有alpha通道的纹理图片。可以使用Mali工具生成。创建的时候选择Create atlas。

                                          

     原图                              新图

2、编写具体的Shader代码。得到压缩后的纹理图片后,代码中唯一需要的就是在着色器上重新映射纹理坐标。将上半部分的图像,移到下半部分获取Alpha通道信息。

顶点着色器(vertex shader):test.vsh

attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
varying vec2 v_alphaCoord;

void main()
{
    gl_Position = CC_PMatrix * a_position;
    v_texCoord = a_texCoord * vec2(1.0, 1.0);
    v_alphaCoord = a_texCoord + vec2(0.0, 0.5);
}

片段着色器(fragment shader):test.fsh

varying vec2 v_texCoord;
varying vec4 v_fragmentColor;
varying vec2 v_alphaCoord;

void main()
{
    vec4 v4Colour = texture2D(CC_Texture0, v_texCoord);
    v4Colour.a = texture2D(CC_Texture0, v_alphaCoord).r;
    v4Colour.xyz = v4Colour.xyz * v4Colour.a;
    gl_FragColor = v4Colour;
}

测试用例:

var sprite = new cc.Sprite("res/grossini.pkm", cc.rect(0, 0, 40, 40));
sprite.x = cc.winSize.width  / 2;
sprite.y = cc.winSize.height / 2;
this.addChild(sprite);

var shader = new cc.GLProgram('res/shaders/test.vsh', 'res/shaders/test.fsh'); shader.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION); shader.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS); shader.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR); shader.link(); shader.updateUniforms(); sprite.shaderProgram = shader;

 

二、使用两张纹理图片

一张原始图片,一张存放alpha信息。渲染的时候加载这两张纹理。通过shader将alpha信息的图片传入到原始图片。

                              

      原图                                             新图                    

1、顶点着色器(vertex shader):test.vsh

attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

void main()
{
    gl_Position = CC_PMatrix * a_position;
    v_fragmentColor = a_color;
    v_texCoord = a_texCoord;
}

2、片段着色器(fragment shader):test.fsh

varying vec2 v_texCoord;
varying vec4 v_fragmentColor;

uniform sampler2D u_alphaTexture;

void main()
{
    vec4 v4Colour = texture2D(CC_Texture0, v_texCoord);
    v4Colour.a = texture2D(u_alphaTexture, v_texCoord).r;
    v4Colour.xyz = v4Colour.xyz * v4Colour.a;
    gl_FragColor = v4Colour;
}

 3、测试用例:

var sprite = new cc.Sprite("res/grossini.pkm");
sprite.x = cc.winSize.width  / 2;
sprite.y = cc.winSize.height / 2;
this.addChild(sprite);
var shader = new cc.GLProgram("res/shaders/test.vsh", "res/shaders/test.fsh"); shader.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION); shader.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS); shader.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR); shader.link(); shader.updateUniforms(); var alphaTexture = cc.textureCache.addImage("res/grossini_alpha.pkm"); var glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shader); glProgramState.setUniformTexture("u_alphaTexture", alphaTexture); sprite.setGLProgramState(glProgramState);

 

四、其他

将alpha作为原始的8位单通道图像提供,在着色器中和纹理合并。

 

你可能感兴趣的:(Cocos2d-js使用ETC1格式的图片)