在Sprite中使用Shader做特殊的颜色处理比较简单,只需要把Shader程序绑定到Sprite上即可:

sprite.shaderProgram = alphaTestShader;

Cocos2d内置了一些Shader,详细可以看代码:

其中,CCShaderCache缓存了一些Shader实例,而GLProgram则对gl的api做了简单的封装让接口更友好。

需要注意的是,使用GLProgram编译shader程序时,cocos2d会自动加入了一些参数。

    _compileShader: function (shader, type, source) {
if (!source || !shader)
return false;
//var preStr = (type == this._glContext.VERTEX_SHADER) ? "precision highp float;\n" : "precision mediump float;\n";
source = "precision highp float; \n"
+ "uniform mat4 CC_PMatrix; \n"
+ "uniform mat4 CC_MVMatrix; \n"
+ "uniform mat4 CC_MVPMatrix; \n"
+ "uniform vec4 CC_Time; \n"
+ "uniform vec4 CC_SinTime; \n"
+ "uniform vec4 CC_CosTime; \n"
+ "uniform vec4 CC_Random01; \n"
+ "//CC INCLUDES END \n" + source;
this._glContext.shaderSource(shader, source);
this._glContext.compileShader(shader);
var status = this._glContext.getShaderParameter(shader, this._glContext.COMPILE_STATUS);
if (!status) {
cc.log("cocos2d: ERROR: Failed to compile shader:\n" + this._glContext.getShaderSource(shader));
if (type == this._glContext.VERTEX_SHADER)
cc.log("cocos2d: \n" + this.vertexShaderLog());
else
cc.log("cocos2d: \n" + this.fragmentShaderLog());
}
return ( status == 1 );
}

另外,绑定到sprite之后,cocos2d会自动设置一些值,我们只需要事先做个绑定即可,而这个绑定操作,也是有友好封装的。具体可以顺藤摸瓜看代码。

                program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);

在sprite上做效果,无非就是一些颜色变换或者说是滤镜而已。由于cocos没有原生的滤镜,不像flash那么方便,那么我们就要自己动手丰衣足食了。

下边实现两个灰度和造旧sepia的效果,类似Flash的ShaderFilter一样。

(绿色球就是原图,上下2个小球分别用不同的sepia参数得到的造旧效果)

var sugar4 = Sugar.create(0,0,2);
sugar4.x = size.width/4;
sugar4.y = size.height/1.5;
this.addChild(sugar4);
sugar4.scale = 3;
var sugar = Sugar.create(0,0,2);
sugar.x = size.width/2;
sugar.y = size.height/2;
this.addChild(sugar);
sugar.scale = 3;
var sugar2 = Sugar.create(0,0,2);
sugar2.x = size.width/3;
sugar2.y = size.height/3;
this.addChild(sugar2);
sugar2.scale = 2;
var sugar3 = Sugar.create(0,0,2);
sugar3.x = size.width/3*2;
sugar3.y = size.height/3*2;
this.addChild(sugar3);
sugar3.scale = 2;
Filter.grayScale(sugar);
Filter.sepia(sugar2, 0.5);
Filter.sepia(sugar3, 0.9);

Filter类的代码:

/**
* Created by kenkozheng on 2014/11/4.
*/
/**
* 只能用于控制Sprite的色调等,目标是实现类似Flash的内置基本滤镜
* 静态类
*/
var Filter = {
DEFAULT_VERTEX_SHADER:
"attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "varying mediump vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ " v_texCoord = a_texCoord; \n"
+ "}",
GRAY_SCALE_FRAGMENT_SHADER:
"varying vec2 v_texCoord; \n"
+ "uniform sampler2D CC_Texture0; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 texColor = texture2D(CC_Texture0, v_texCoord); \n"
+ " float gray = texColor.r * 0.299 + texColor.g * 0.587 + texColor.b * 0.114; \n"
+ " gl_FragColor = vec4(gray, gray, gray, texColor.a); \n"
+ "}",
SEPIA_FRAGMENT_SHADER:
"varying vec2 v_texCoord; \n"
+ "uniform sampler2D CC_Texture0; \n"
+ "uniform float u_degree; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 texColor = texture2D(CC_Texture0, v_texCoord); \n"
+ " float r = texColor.r * 0.393 + texColor.g * 0.769 + texColor.b * 0.189; \n"
+ " float g = texColor.r * 0.349 + texColor.g * 0.686 + texColor.b * 0.168; \n"
+ " float b = texColor.r * 0.272 + texColor.g * 0.534 + texColor.b * 0.131; \n"
+ " gl_FragColor = mix(texColor, vec4(r, g, b, texColor.a), u_degree); \n"
+ "}",
programs:{},
/**
* 灰度
* @param sprite
*/
grayScale: function (sprite) {
var program = Filter.programs["grayScale"];
if(!program){
program = new cc.GLProgram();
program.initWithVertexShaderByteArray(Filter.DEFAULT_VERTEX_SHADER, Filter.GRAY_SCALE_FRAGMENT_SHADER);
program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION); //cocos会做初始化的工作
program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
program.link();
program.updateUniforms();
Filter.programs["grayScale"] = program;
}
gl.useProgram(program.getProgram());
sprite.shaderProgram = program;
},
/**
* 造旧
* @param sprite
* @param degree 旧的程度 0~1
*/
sepia: function (sprite, degree) {
var program = Filter.programs["sepia"+degree];
if(!program){
program = new cc.GLProgram();
program.initWithVertexShaderByteArray(Filter.DEFAULT_VERTEX_SHADER, Filter.SEPIA_FRAGMENT_SHADER);
program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION); //cocos会做初始化的工作
program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
program.link();
program.updateUniforms();
var degreeLocation = program.getUniformLocationForName("u_degree");
program.setUniformLocationF32(degreeLocation, degree);
Filter.programs["sepia"+degree] = program;
}
gl.useProgram(program.getProgram());
sprite.shaderProgram = program;
}
};

cocos2d-js Shader系列2:在cc.Sprite上使用Shader(黑白、灰度、造旧效果)的更多相关文章

  1. 解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader

    上篇文章中我们掌握了表面剔除和剪裁模式 这篇文章将利用这些知识实现一个简单的,可是又非经常常使用的样例:把一张图片做成圆角矩形 例3:圆角矩形Shader 好吧我承认在做这个样例的时候走了不少弯路,因 ...

  2. [转]解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader

    上篇文章中我们掌握了表面剔除和剪裁模式这篇文章将利用这些知识实现一个简单的,但是又很常用的例子:把一张图片做成圆角矩形 例3:圆角矩形Shader好吧我承认在做这个例子的时候走了不少弯路,由于本人对矩 ...

  3. cocos2d js 利用texture packer生成sprite

    cc.spriteFrameCache.addSpriteFrames(res.winLose_plist,res.winLose_png); var frame = cc.spriteFrameCa ...

  4. cocos2d-js Shader系列4:Shader、GLProgram在jsb(native、手机)和html5之间的兼容问题。cocos2d-js框架各种坑。

    为了让jsb也能顺利跑起滤镜效果,在手机侧折腾了2天,因为每次在真机上运行总要耗那么半分钟,而且偶尔还遇到apk文件无法删除导致运行失败的情况. 这个调试起来,实在让人烦躁加沮丧. 还好,测试上百轮, ...

  5. cocos2d-js Shader系列3:多重纹理 multiple textures multiple samplers

    上一篇,我们学习了怎么便捷的控制sprite的颜色,而这个都是默认一个texture的,如果要实现类似mask的效果,或者更个性化的多纹理效果,怎么实现呢? 这就是这一节需要介绍的内容. 例如上图的效 ...

  6. cocos2d js ClippingNode 制作标题闪亮特效

    1.效果图: 之前在<Android 高仿 IOS7 IPhone 解锁 Slide To Unlock>中制作了文字上闪亮移动的效果,这次我们来看下怎样在cocos2d js 中做出类似 ...

  7. JS组件系列——BootstrapTable 行内编辑解决方案:x-editable

    前言:之前介绍bootstrapTable组件的时候有提到它的行内编辑功能,只不过为了展示功能,将此一笔带过了,罪过罪过!最近项目里面还是打算将行内编辑用起来,于是再次研究了下x-editable组件 ...

  8. cc.Sprite

    Classcc.Sprite Defined in: CCSprite.js Extends cc.NodeRGBA Class Summary Constructor Attributes Cons ...

  9. cocos2d.js

    1.节点是Cocos2d最基础的东西 2.坐标与普通数学坐标一致 3.children属性表示节点的孩子,父节点位置变化,它包含的子节点也会跟着变化,以整体的形势移动 4.层(layer), 新建层: ...

随机推荐

  1. [Web 前端] webstorm 快速搭建react项目

    cp from : https://blog.csdn.net/qq_39207948/article/details/79467144 前端新手如何安装webstorm ,初步搭建react项目 下 ...

  2. 使用ASP.NET AJAX与Bootstrap 弹窗解决方案

    我在做采购系统时,因为使用了ASP.NET AJAX的UpdatePanel的控件,可以使得页面局部刷新显示.但是使用起来问题还是很多. 下面列出了一种情况,花了将近5个小时才算解决,虽然不是很完美, ...

  3. 如何使用pycharm调试(debug) django的测试用例?

    一.django应用或者flask应用的调试: 结合debug模式,在代码处添加断点,即可实现断点调试功能 二. django应用或者flask应用测试用例的调试: 一般django应用的测试用例执行 ...

  4. 使用jupyter搭建golang的交互式界面:类似于ipython;jupyter还可以使用spark或者结合机器学习

    Jupyter Notebook The Jupyter notebook is a web-based notebook environment for interactive computing. ...

  5. Android studio 编译失败Error:Could not read entry &#39;:app:processDebugManifest&#39; from cache taskArtifacts.b

    Android studio 编译失败 Error:Could not read entry ':app:processDebugManifest' from cache taskArtifacts. ...

  6. Python/Shell 正则表达式与运用

    正则表达式用的地方是很多的.比如字符串处理过程中.最近遇到记录一下. 1. 比如在shell中 #!/bin/bash str="date:2017-11-28 os:centos blac ...

  7. freemarker怎么把数据显示到页面中?

    第一步  创建一个User.java文件 来两个变量       public class User {       private String userName;         private ...

  8. Spring系列:Scheduled注解学习笔记

    一.试验代码 //@Scheduled(fixedRate = 5000) //@Scheduled(fixedDelay = 5000) @Scheduled(cron ="*/5 * * ...

  9. ie7 z-index 失效问题

    解决办法: 父级元素加上position:relative;并设置z-index. 父级元素的z-index优先,其中包含的元素的z-index是相对于父级元素的index. <div styl ...

  10. iOS中的时钟动画

    iOS 动画效果非常多,我们在开发中可能会遇到很多动画特效,我们就会用到核心动画框架CoreAnimation,核心动画里面的动画效果有很多,都是在QuartzCore.framework框架里面,今 ...