cocos2d-x着色器基础之类似水纹效果的实现

来源:互联网 发布:ehviewer老是网络错误 编辑:程序博客网 时间:2024/05/28 06:05

近期在准备新的书稿,涉及到了着色器的基础部分,所以在此特地记录一个简单案例的实现——类似水纹效果。

准备工作:1>用3DMax做一个多顶点的长方体,需要更改顶点数。(长度分段及宽度分段等)

       2>随便找一张纹理图。

     由于cocos2d-x底层是封装的OpenGL ES,所以如果有基础的话,只需要将OpenGL ES的套路在cocos2d-x中套即可,只是将变量名换了一下而已。

     下面简要概述一下着色器语言的开发流程以及注意事项,尤其是第一次写着色器时踩过的坑,需要特别注意了。

      (1)创建精灵,并绑定着色器,具体代码如下所示。

    auto breast = Sprite3D::create("breast.obj","pic.png"); auto shader_l = GLProgram::createWithFilenames("b_vert.vert","b_frag.frag");state_l = GLProgramState::create(shader_l);state_l->setUniformFloat("uStartAngle", 0.1);<span style="white-space:pre"></span>     //传开始的角度给顶点着色器state_l->setUniformFloat("uWidthSpan",20.0);                         //将宽度传给顶点着色器breast->setGLProgramState(state_l);long offest_l = 0;auto attributeCount_l = breast->getMesh()->getMeshVertexAttribCount(); //获得网格包含顶点数量for(auto i = 0; i< attributeCount_l; i++)                              <span style="font-family: Arial, Helvetica, sans-serif;">//循环获得顶点的属性</span>{auto meshAttribute_l = breast->getMesh()->getMeshVertexAttribute(i);state_l->setVertexAttribPointer(s_attributeNames[meshAttribute_l.vertexAttrib],//顶点属性的名字meshAttribute_l.size,                       //每个顶点中需要更新的元素个数meshAttribute_l.type,                      //表示数组中每个元素的数据类型GL_FALSE,                                  //顶点数据是否在传递之前归一化breast->getMesh()->getVertexSizeInBytes(),//两个连续元素之间的偏移字节数(void*)offest_l                              //偏移量);offest_l += meshAttribute_l.attribSizeBytes;  }
(2)然后就是定时回调update方法改变起始角度即可。具体代码如下。

void My3DLayer::update(float delta){offest_l += 0.15;state_l->setUniformFloat("uStartAngle", offest_l);state_l->setUniformFloat("uWidthSpan",20.0);}
(3)下面先介绍一下顶点着色器的写法以及注意事项,先贴出代码,如下。

attribute vec3 a_position;attribute vec2 a_texCoord;uniform float uStartAngle;uniform float uWidthSpan;varying vec2 v_textureCoord;void main(){float angleSpan = 4.0 * 3.1415926;float startX = -uWidthSpan / 2.0;float currentAngle = uStartAngle + ((a_position.x - startX)/uWidthSpan) * angleSpan;float ty = sin(currentAngle) * 3.0; gl_Position = CC_MVPMatrix * vec4(a_position.x, ty, a_position.z, 1);v_textureCoord = a_texCoord;v_textureCoord.y = (1.0 - a_texCoord.y);<span style="white-space:pre"></span>//纹理取点的y坐标置反,(使用OpenGL ES的取纹理方式)}
  注:由于cocos2d-x引擎内部封装了一些OpenGL ES的一些内建变量并隐藏的声明了一些变量,需要特别注意,在后面需要将这些变量总体列出来,以备以后查阅。

(4)顶点着色器将顶点纹理图的坐标传递给片元着色器,片元着色器负责更改颜色,由于此案例比较基础,并未实现真正的水纹效果,后期再进行更改。具体代码如下。

precision mediump float;varying vec2 v_textureCoord;void main(){gl_FragColor = texture2D(CC_Texture0, v_textureCoord); //texture2D为OpenGL ES内部的方法}
(5)大体框架就是这样,下面列一下暂时用到的cocos2d-x引擎给提供的内建变量,如果后期用到更多的变量,在进行添加。具体图示如下。


    a_position : 为顶点在节点坐标系的位置

    a_texCoord : 为纹理坐标

    a_normal : 为法线方向

    CC_PMatrix : 为投影矩阵(P为projection)

    CC_MVPMatrix : 为变换总矩阵

    CC_NormalMatrix : 为法线矩阵

    CC_Texture0 : 为第一个纹理图

    基本变换矩阵:sprite->getNodeToWorldTransform()


      最后贴一个波涛汹涌的效果图。。。

    至此,结束。

0 0