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), 新建层: ...
随机推荐
- Java并发编程的艺术(四)——线程的状态
线程的状态 初始态:NEW 创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态. 运行态:RUNNABLE 在Java中,运行态包括就绪态 和 运行态. 就绪态 该状态下的线 ...
- SpiderMonkey js引擎的静态编译与使用, SpiderMonkey的使用
SpiderMonkey js引擎的静态编译与使用 2017年10月02日 02:51:22 yaolixing01 阅读数:536 原文出处: http://yaolixing.oltag.co ...
- 5句mysql语句
显示表的结构: mysql> DESCRIBE MYTABLE; 往表中加入记录 mysql> insert into MYTABLE values ("hyq",&q ...
- 对拍练习:A+B
源程序: /* Problem: OJ: User: S.B.S. Time: Memory: Length: */ #include<iostream> #include<cstd ...
- linux驱动编写(电源管理驱动)
对于嵌入式设备来说,合适的电源管理,不仅可以延长电池的寿命,而且可以省电,延长设备运行时间,在提高用户体验方面有很大的好处.所以,各个soc厂家在这方面花了很多的功夫.下面,我们可以看看linux是如 ...
- Threejs 开发3D地图实践总结【转】
Threejs 开发3D地图实践总结 前段时间连续上了一个月班,加班加点完成了一个3D攻坚项目.也算是由传统web转型到webgl图形学开发中,坑不少,做了一下总结分享. 1.法向量问题 法线是垂 ...
- 如何统计NFS的client在一段时间内收到了多少个字节?
可使用的命令如下: nfsstat –c nfsiostat 参考资料 ============= https://www.systutorials.com/docs/linux/man/8-nfss ...
- 如何确定一个NFS的mount是v3还是v4?
命令如下: nfsstat –m nfsstat –m | grep /home/mymnt 参考资料 ============ https://unix.stackexchange.com/ques ...
- CSS-图像映射
图像映射是将一些区域变成热点,我们在网上获取搜索图片,图片上会有关于任务的简短信息介绍,还有一个接触更多的就是QQ空间的相册,浏览QQ空间照片鼠标滑动到人物头像的时候让你选择标记人物,都是将图片和内容 ...
- Scramble String leetcode java
题目: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty subs ...