cocos2d-js Shader系列2:在cc.Sprite上使用Shader(黑白、灰度、造旧效果)
在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(黑白、灰度、造旧效果)的更多相关文章
- 解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader
上篇文章中我们掌握了表面剔除和剪裁模式 这篇文章将利用这些知识实现一个简单的,可是又非经常常使用的样例:把一张图片做成圆角矩形 例3:圆角矩形Shader 好吧我承认在做这个样例的时候走了不少弯路,因 ...
- [转]解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader
上篇文章中我们掌握了表面剔除和剪裁模式这篇文章将利用这些知识实现一个简单的,但是又很常用的例子:把一张图片做成圆角矩形 例3:圆角矩形Shader好吧我承认在做这个例子的时候走了不少弯路,由于本人对矩 ...
- cocos2d js 利用texture packer生成sprite
cc.spriteFrameCache.addSpriteFrames(res.winLose_plist,res.winLose_png); var frame = cc.spriteFrameCa ...
- cocos2d-js Shader系列4:Shader、GLProgram在jsb(native、手机)和html5之间的兼容问题。cocos2d-js框架各种坑。
为了让jsb也能顺利跑起滤镜效果,在手机侧折腾了2天,因为每次在真机上运行总要耗那么半分钟,而且偶尔还遇到apk文件无法删除导致运行失败的情况. 这个调试起来,实在让人烦躁加沮丧. 还好,测试上百轮, ...
- cocos2d-js Shader系列3:多重纹理 multiple textures multiple samplers
上一篇,我们学习了怎么便捷的控制sprite的颜色,而这个都是默认一个texture的,如果要实现类似mask的效果,或者更个性化的多纹理效果,怎么实现呢? 这就是这一节需要介绍的内容. 例如上图的效 ...
- cocos2d js ClippingNode 制作标题闪亮特效
1.效果图: 之前在<Android 高仿 IOS7 IPhone 解锁 Slide To Unlock>中制作了文字上闪亮移动的效果,这次我们来看下怎样在cocos2d js 中做出类似 ...
- JS组件系列——BootstrapTable 行内编辑解决方案:x-editable
前言:之前介绍bootstrapTable组件的时候有提到它的行内编辑功能,只不过为了展示功能,将此一笔带过了,罪过罪过!最近项目里面还是打算将行内编辑用起来,于是再次研究了下x-editable组件 ...
- cc.Sprite
Classcc.Sprite Defined in: CCSprite.js Extends cc.NodeRGBA Class Summary Constructor Attributes Cons ...
- cocos2d.js
1.节点是Cocos2d最基础的东西 2.坐标与普通数学坐标一致 3.children属性表示节点的孩子,父节点位置变化,它包含的子节点也会跟着变化,以整体的形势移动 4.层(layer), 新建层: ...
随机推荐
- Android反编译工具的用法
Android的APK文件时可以反编译的,通过反编译我们就能查看到大体的代码,帮助学习.反编译仅仅提供的是学习的方式,禁止使用该技术进行非法活动. 其实就是两个命令: 1:运行(WIN+R)-> ...
- PHP检测及判断手机登录用户是安卓或爱疯(iPhone)客户端
<?php /* PHP 自动判断客户端平台(PC.安卓.iPhone.平板) * strtolower() 函数把字符串转换为小写: * strpos() 函数返回字符串在另一个字符串中第一次 ...
- 奇怪吸引子---AnishchenkoAstakhov
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- boost::asio::ip::tcp实现网络通信的小例子
同步方式: Boost.Asio是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型. 头文件 #include <boost/asio.hpp> 名空 ...
- 遭遇sql server 2005 启动包未能正确加载需要重新安装错误,重装.NET FRAMEWORK经历分析
开发的机器,系统情况如下: 1.server 2003 sp2 x86 2.补丁安装360 3.升级到IE8 因为担心server 2003 sp2 不能够自动update,最近都是用360打补丁,比 ...
- Lucene学习——IKAnalyzer中文分词
一.环境 1.平台:MyEclipse8.5/JDK1.5 2.开源框架:Lucene3.6.1/IKAnalyzer2012 3.目的:测试IKAnalyzer的分词效果 二.开发调试 1.下载框架 ...
- https://www.cnblogs.com/xubing-613/p/5895948.html
最近总是需要用matplotlib绘制一些图,由于是新手,所以总是需要去翻书来找怎么用,即使刚用过的,也总是忘.所以,想写一个入门的教程,一方面帮助我自己熟悉这些函数,另一方面有比我还小白的新手可以借 ...
- C++模拟键盘消息
实现功能:在现有DLL程序中向特定的EXE窗口中发送模拟键盘的消息 使用API根据窗口标题递归查找特定的窗口句柄,之后模拟调用. 注意:keybd_event函数不能在VS下使用,所以用SendInp ...
- C++类中的访问权限问题
纠结的东西: private,public,protected方法的访问范围.(public继承下)private: 只能由该类中的函数.其友元函数访问,不能被任何其他访问,该类的对象也不能访问. p ...
- Documentation/PCI/pci-iov-howto.txt
Chinese translated version of Documentation/PCI/pci-iov-howto.txt If you have any comment or update ...