在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. 访问修饰符(C# 编程指南)

    所有类型和类型成员都具有可访问性级别,该级别可以控制是否可以从你的程序集或其他程序集中的其他代码中使用它们. 可以使用以下访问修饰符在进行声明时指定类型或成员的可访问性: public同一程序集中的任 ...

  2. 显卡、显卡驱动、CUDA、cuDNN之间的关系

    作者:冬瓜哥链接:https://www.zhihu.com/question/59184480/answer/166167659来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  3. 直方图与bin

    1.bin的含义 直方图中bin的含义:计算颜色直方图需要将颜色空间划分为若干小的颜色区间,即直方图的bin,通过计算颜色在每个小区间内德像素得到颜色直方图,bin越多,直方图对颜色的分辨率越强,但增 ...

  4. JAVA 是否会发生内存泄露(转)

    原文链接: JAVA 是否会发生内存泄露 几次面试,面试官都问到了这个问题,于是搜集了答案.总结出虽然java自身有垃圾回收机制,但是很多情况下还是发生内存泄露的. java导致内存泄露的原因很明确: ...

  5. javascript中的分支判断与循环

    分支判断与循环 分支结构 单一选择结构(if) 二路选择结构(if/else) 内联三元运算符 ?: 多路选择结构(switch) var condition = true; if (conditio ...

  6. HTML中的转义字符 (转)

    HTML中<, >,&等有特殊含义,(前两个字符用于链接签,&用于转义),不能直接使用.使用这三个字符时,应使用它们的转义序列,如下所示: & 或 & &a ...

  7. [leetcode]Partition List @ Python

    原题地址:https://oj.leetcode.com/problems/partition-list/ 题意: Given a linked list and a value x, partiti ...

  8. Hadoop视频教程汇总

    一 慕课网 1.Hadoop大数据平台架构与实践--基础篇(已学习) 链接:https://www.imooc.com/learn/391 2.Hadoop进阶(已学习) 链接:https://www ...

  9. centos6安装ElasticSearch5.6.5错误记录

    在centos6安装ES的时候遇到不少问题.这里记录日志.以后安装一定要升级centos7,别说啥稳定问题了,该升级就升级. [1]: max file descriptors [4096] for ...

  10. 前后端协调处理checkbox

    需求:页面属于一个弹出窗体,查询结果,用checkbox展示,选择后,把选中的结果传递给调用页面. 由于要取得后端写的checkbox控件的值,所以在后端处理最后的提交事件,用这个语句把结果传递到页面 ...