cocos2dx的shader的工作流程

本篇文章旨在记录cocos2dx中的shader文件是如何组织和编译的,理清脉络后,更容易对shader进行扩展和自定义。
shader使用的文件包括GLProgram 、GLProgramState、GLProgramCache、GLProgramStateCache

GLProgramCache文件中的reloadDefaultGLPrograms()函数会编译所有的cocos内置的shader
cocos的shader文件定义在cocos/renderer下面,是用const char定义的全局变量,ccShader.cpp include “xxx.frag” 就可以在cpp文件展开。 调用initWithByteArrays()函数 编译shader
在shader中使用了一个STRINGIFY的宏 STRINGIFY(A)=#(A) "#"的意思是把()内的内容用字符串替代
ccShaders.h 定义全局的shader脚本字符串
CCGLProgram.h 定义shader的宏
MVP_MATRIX Model view projection matrix 模型视图投影矩阵
模型视图投影矩阵=投影矩阵×视图矩阵×模型矩阵
ShaderPositionTextureColor_noMVP 这些string类型定义在CCGLProgram.cpp中在reloadDefaultGLPrograms()函数中 作为 std::unordered_map<std::string, GLProgram
> _programs;的key 保存对应的program
调用node的setGLProgram()可以直接设置shader但是这样做不高效,每次都会编译和链接,需要用GLProgramCache来提高效率。GLProgramCache 中是一个map,字符串作为key,glProgram是value,先在GLProgramCache中查找,没有的话再创建,并且把它加到GLProgramCache中。 createWithFilenames()不如createWithByteArrays()高效。原因是使用file存储shader会查找磁盘,使用array不需要查找磁盘。

static const char * COCOS2D_SHADER_UNIFORMS =
"uniform mat4 CC_PMatrix;\n"
"uniform mat4 CC_MultiViewPMatrix[4];\n"
"uniform mat4 CC_MVMatrix;\n"
"uniform mat4 CC_MVPMatrix;\n"
"uniform mat4 CC_MultiViewMVPMatrix[4];\n"
"uniform mat3 CC_NormalMatrix;\n"
"uniform vec4 CC_Time;\n"
"uniform vec4 CC_SinTime;\n"
"uniform vec4 CC_CosTime;\n"
"uniform vec4 CC_Random01;\n"
"uniform sampler2D CC_Texture0;\n"
"uniform sampler2D CC_Texture1;\n"
"uniform sampler2D CC_Texture2;\n"
"uniform sampler2D CC_Texture3;\n"
"//CC INCLUDES END\n\n";

在这文件中的 bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source, const std::string& compileTimeHeaders, const std::string& convertedDefines) 这个函数中
有这样一行代码
const GLchar *sources[] = {
headersDef.c_str(),
COCOS2D_SHADER_UNIFORMS,
convertedDefines.c_str(),
source};
cocos会对传进来的shader添加一个头部 headersDef ,加一堆的uniform变量 ,uniform就是数组里的东西

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cocos 刮刮卡 shader 可以实现在图片或者精灵上进行刮开效果的特效。具体实现方法如下: 1. 用 cocos2d-x 创建一个新的项目。 2. 在项目中创建一个精灵,加载一张背景图片。 3. 创建一个 Shader 文件,命名为 ScratchCard.fsh。 4. 在 ScratchCard.fsh 中编写 shader 代码,实现刮开效果,代码如下: ``` varying vec2 v_texCoord; uniform sampler2D CC_Texture0; uniform sampler2D brushTexture; uniform float u_threshold; void main() { vec4 color = texture2D(CC_Texture0, v_texCoord); vec4 brush = texture2D(brushTexture, v_texCoord); float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114)); float mask = step(luminance, u_threshold); gl_FragColor = mix(color, vec4(0, 0, 0, 0), mask * brush.a); } ``` 5. 在 C++ 代码中加载 Shader 文件,将 Shader 绑定到精灵上。 ``` auto shader = GLProgram::createWithFilenames("ScratchCard.vsh", "ScratchCard.fsh"); auto sprite = Sprite::create("background.png"); sprite->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); sprite->setGLProgram(shader); this->addChild(sprite); ``` 6. 创建一个 Brush 精灵,用于擦除操作。 ``` auto brush = Sprite::create("brush.png"); brush->setVisible(false); this->addChild(brush); ``` 7. 在触摸事件中实现刮开效果,将 Brush 精灵的位置设置为触摸点的位置,并且将 Brush 精灵显示出来。 ``` bool HelloWorld::onTouchBegan(Touch* touch, Event* event) { brush->setPosition(touch->getLocation()); brush->setVisible(true); return true; } void HelloWorld::onTouchMoved(Touch* touch, Event* event) { brush->setPosition(touch->getLocation()); } void HelloWorld::onTouchEnded(Touch* touch, Event* event) { brush->setVisible(false); } ``` 8. 在每帧更新中将 Brush 精灵的位置传递给 Shader,用于在精灵上实现擦除效果。 ``` void HelloWorld::update(float delta) { auto shader = sprite->getGLProgram(); shader->use(); shader->setUniformTexture("brushTexture", brush->getTexture()); shader->setUniformLocationWith1f(shader->getUniformLocation("u_threshold"), 0.7f); shader->setUniformLocationWith2f(shader->getUniformLocation("u_brushPosition"), brush->getPositionX(), brush->getPositionY()); } ``` 这样就实现了 cocos 刮刮卡 shader 效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值