cocos2d的Shader也就是差不多直接跟GPU打交道了,跟Flash的Stage3D(AGAL)类似,不过没有AGAL这么恶心,不需要直接编写汇编语言。而Fragment Shader又跟Flash的pixelbender类似。

本文以cocos2d-js为例,但cocos2dx其他版本也是同理的,只是函数名略有不同而已。

当然还是得先复习或者学习一下GPU的原理,至少得知道vertex shader和fragment shader的作用和区别。

详细可以看看大神的说明:

http://www.opengpu.org/bbs/forum.php?mod=viewthread&tid=7550&extra=page%3D1

http://www.opengpu.org/bbs/forum.php?mod=viewthread&tid=7376&extra=page%3D1

cocos2d的Shader步骤还是类似的:

1、编写vertex shader和fragment shader

2、定义顶点坐标和纹理坐标

3、定义纹理、绑定纹理

4、设置shader的参数

5、每帧draw的时候,gl.drawArrays推送到GPU绘制

1、Shader语法


语法有点类似Flash的pixelbender,但是一个更完整的C程序,可以按照C程序的语法来编写。main函数最终输出结果到一个指定变量中,都是矢量的点乘、加减等。

vertext shader最后赋值一个vec4给gl_Position,表示该点最终绘制到屏幕上的位置;fragment shader最后赋值vec4给gl_FragColor,表示颜色rgba。

详细介绍:

http://blog.csdn.net/hgl868/article/details/7846269

http://blog.csdn.net/wangyuchun_799/article/details/7770500


attribute、uniform、varying区别:http://blog.csdn.net/jackers679/article/details/6848085

uniform变量是外部application程序传递给(vertex和fragment)shader的变量,类似常量

attribute变量是只能在vertex shader中使用的变量。(它不能在fragment shader中声明attribute变量,也不能被fragment shader中使用)

varying变量是vertex和fragment shader之间做数据传递用的。一般vertex shader修改varying变量的值,然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。Varying can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, mat4. (arrays of them too.)

2、定义顶点坐标和纹理坐标

var squareVertexPositionBuffer = this.squareVertexPositionBuffer = gl.createBuffer();     //创建一个buffer,并记录下来,后续每帧draw的时候调用
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); //绑定位置,后一句bufferData就设置这个位置的数据
vertices = [ //这里是4个顶点
256, 256,
0, 256,
256, 0,
0, 0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); /* gl.STATIC_DRAW The data store contents are modified once, and used many times as the source for WebGL drawing commands.
gl.DYNAMIC_DRAW The data store contents are repeatedly respecified, and used many times as the source for WebGL drawing commands.
gl.STREAM_DRAW The data store contents are specified once, and used occasionally as the source of a WebGL drawing command. */
gl.bindBuffer(gl.ARRAY_BUFFER, null);

3、绑定纹理

        //定义纹理
var texture = this.my_texture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture );
var pixels = new Uint8Array(4096); //正好是32*32的图片,每个像素4个byte
for( var i=0; i<pixels.length; ) {
pixels[i++] = i/4; // Red
pixels[i++] = i/16; // Green
pixels[i++] = i/8; // Blue
pixels[i++] = 255; // Alpha
}
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels); //每帧draw之前绑定纹理 gl.bindTexture(gl.TEXTURE_2D, this.my_texture);

    

    对应的fragment shader写法

precision lowp float;
varying vec2 v_texCoord;
uniform sampler2D CC_Texture0; void main() {
gl_FragColor = texture2D(CC_Texture0, v_texCoord);
}

4、设置shader参数

//在初始化的时候记录shader程序,记录参数的入口位置

        this.shader = cc.GLProgram.create(vertexShader, framentShader);
this.shader.retain();
this.shader.addAttribute("aVertex", cc.VERTEX_ATTRIB_POSITION); //添加一个新参数到shader中,并指定为第几个
this.shader.link();
this.shader.updateUniforms(); //表示使用cocos2d默认附加的一些参数,其实在_compileShader的时候添加到shader程序的
var program = this.shader.getProgram();
this.uniformCenter = gl.getUniformLocation( program, "center"); //记录Uniform参数入口 this.uniformResolution = gl.getUniformLocation( program, "resolution"); //override原来的draw函数,在每帧draw的时候调用: this.shader.use();
this.shader.setUniformsForBuiltins(); //如果shader中使用了cocos2d默认附加的一些uniform参数,就需要每帧设置(例如TIME等),具体参数意义参考CCGLProgram.setUniformsForBuiltins
this.shader.setUniformLocationF32( this.uniformCenter, winSize.width/2, winSize.height/2);
this.shader.setUniformLocationF32( this.uniformResolution, 256, 256); //设置uniform参数,CCGLProgram类对opengl底层的接口做了封装。例如这个就是对应uniform2f gl.bindBuffer(gl.ARRAY_BUFFER, this.squareVertexPositionBuffer);
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, 0); //设置attribute参数

参数参考:

http://msdn.microsoft.com/zh-cn/library/ie/dn302460(v=vs.85).aspx

函数第一个参数:表示shader程序的第几个attribute参数

5、draw call

gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

参数参考:

http://msdn.microsoft.com/zh-cn/library/ie/dn302460(v=vs.85).aspx

http://msdn.microsoft.com/zh-cn/library/ie/dn302395(v=vs.85).aspx



最后附上cocos2dx官方的一些教程:

http://cn.cocos2d-x.org/tutorial/show?id=1336

http://cn.cocos2d-x.org/tutorial/show?id=1337

cocos2d-js Shader系列1:cocos2d-js Shader和OpenGL ES2.0的更多相关文章

  1. Cocos2d-x中使用OpenGL ES2.0编写shader

    这几天在看子龙山人的关于OpenGL的文章,先依葫芦画瓢,能看到些东西,才能慢慢深入了解,当入门文章不错,但是其中遇到的一些问题,折腾了一些时间,为了方便和我一样的小白们,在这篇文章中进行写补充. O ...

  2. js基础系列框架:JS重要知识点(转载)

    这里列出了一些JS重要知识点(不全面,但自己感觉很重要).彻底理解并掌握这些知识点,对于每个想要深入学习JS的朋友应该都是必须的. 讲解还是以示例代码搭配注释的形式,这里做个小目录: JS代码预解析原 ...

  3. node.js入门系列(一)--Node.js简介

    什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. 每一种解析器都是一 ...

  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 Shader系列2:在cc.Sprite上使用Shader(黑白、灰度、造旧效果)

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

  7. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一)

    前言:出于某种原因,需要学习下Knockout.js,这个组件很早前听说过,但一直没尝试使用,这两天学习了下,觉得它真心不错,双向绑定的机制简直太爽了.今天打算结合bootstrapTable和Kno ...

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

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

  9. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面

    前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽.于是研究了下T4 ...

随机推荐

  1. 记一个js中的map数据结构

    <html><body> <script type="text/javascript">let arr =[{demo1:123,demo2:& ...

  2. 伯努利分布、二项分布、Beta分布、多项分布和Dirichlet分布与他们之间的关系,以及在LDA中的应用

    在看LDA的时候,遇到的数学公式分布有些多,因此在这里总结一下思路. 一.伯努利试验.伯努利过程与伯努利分布 先说一下什么是伯努利试验: 维基百科伯努利试验中: 伯努利试验(Bernoulli tri ...

  3. django外键以及主表和子表的相互查询

    Django的外键使用 from django.db import models # Create your models here. class Category(models.Model): na ...

  4. jQuery EasyUI Datagrid性能优化专题(转)

    jQuery  EasyUI的Datagrid组件功能算是很强大了,不过性能确实不怎么乐观,而对于性能问题,网络上几乎也找不到相关的优化资料,所谓的牛人们可能 都望而却步了.本博客以后会带着分析Dat ...

  5. Laravel学习笔记之Session源码解析(中)

    说明:在上篇中学习了session的启动过程,主要分为两步,一是session的实例化,即\Illuminate\Session\Store的实例化:二是从session存储介质redis中读取id ...

  6. TOJ 1220 填数字游戏 / 深搜

    填数字游戏 时间限制(普通/Java):1000MS/10000MS     运行内存限制:65536KByte 描述 有个小游戏,让你填写以下方框,要求: a1+a2+a3+M=b1+b2+b3+M ...

  7. Python3 使用 matplotlib 画折线图

    ChartUtil.py import matplotlib.pyplot as plt from pylab import mpl def plotLine(xData,yData,xLabel,c ...

  8. -webkit-margin-before

    原文:https://www.cnblogs.com/guyw/p/4369653.html ----------------------------------------------- -webk ...

  9. c#:winform从一个toolstriptool上拖动一个图标到一个自定义usercontrol内。

    效果: 在一个winform工程中,添加一个ToolStrip然后给它添加一个ToolStripButton(tsbStart,它就是红色框圈选的图标) this.toolStripTools = n ...

  10. Eclipse 文件太长,导致着色异常问题

    1. 把C/C++ ->Editor->Scalability, 对应红框中的数字调大.