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位單通道圖像提供,在着色器中和紋理合並。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM