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

前端之家收集整理的这篇文章主要介绍了cocos2d-x着色器基础之类似水纹效果的实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

准备工作: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()


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

至此,结束。

猜你在找的Cocos2d-x相关文章