【复习笔记】 cocos2d-x 2.x 渲染特效实现 七 辉光效果
来源:互联网 发布:linux命令行 删除 编辑:程序博客网 时间:2024/06/06 14:21
辉光效果经常用来做一些物体的自发光,这种发光效果不需要光照计算,只是在贴图上进行发光的模拟效果,所以有着很好的效率。辉光效果意味着贴图会变亮。为了对发光的部分做计算,需要一张glowmap贴图,当我们使用src和dst都为GL_ONE的方式,混合glowmap和原图时,原图就会对按照glowmap的样子变亮了~但是作为辉光的效果,仅仅只有变亮是不够的,由于光线在穿过空气时亮度会衰减,所以周围会有一圈逐渐消失的光晕。所以我们利用原图的模糊贴图的做glowmap,这样辉光就会有很好的光晕效果了~因为简单模糊效果不够细腻,光晕效果会不是很好,所以我们用高斯模糊来实现~
这次,我们需要对一个节点树的做高斯模糊处理,原因是这样之后,可以实现节点树的辉光效果,另外,单张贴图图片边缘不能模糊延伸的问题也可以得到解决~由于之前高斯模糊是需要做一次RTT才能实现的,而在这之前,要得到节点树的整屏贴图也要做一次RTT,所以,这次渲染过程中包含有两次RTT,按照先后顺序,具体作用分别是:生成节点树的贴图,做横向的高斯模糊。
void CCEffectSprite::visitGlow(){float blursDis[2] = {_pixelSpan/_screenBufferSize.width, _pixelSpan/_screenBufferSize.height};GLint size = sizeof(ccV3F_C4B_T2F); long data = (long)&m_sQuad;/**/ // gen a empty texture glGenTextures(1, &_texture); glBindTexture(GL_TEXTURE_2D, _texture);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _screenBufferSize.width, _screenBufferSize.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // gen a off-screen framebuffer GLint oldFBO; glGetIntegerv(GL_RENDERBUFFER_BINDING, &oldFBO); glGenFramebuffers(1, &_framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {CCLOG("glCheckFramebufferStatus ERROR! 0x%04x", glCheckFramebufferStatus(GL_FRAMEBUFFER));} // ************ first draw ******************CCNode::visit(); // ****************************************** // gen a empty textureGLuint _texture2; glGenTextures(1, &_texture2); glBindTexture(GL_TEXTURE_2D, _texture2);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _screenBufferSize.width, _screenBufferSize.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // gen a off-screen framebuffer GLuint _framebuffer2; glGenFramebuffers(1, &_framebuffer2); glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer2); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture2, 0);if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {CCLOG("glCheckFramebufferStatus ERROR! 0x%04x", glCheckFramebufferStatus(GL_FRAMEBUFFER));} // ************** second draw *****************// reset stackkmGLMatrixMode(KM_GL_MODELVIEW);kmGLPushMatrix();kmGLLoadIdentity();kmGLMatrixMode(KM_GL_PROJECTION);kmGLPushMatrix();kmGLLoadIdentity();glViewport(0, 0, _screenBufferSize.width, _screenBufferSize.height);CC_NODE_DRAW_SETUP();ccGLBlendFunc(m_sBlendFunc.src, m_sBlendFunc.dst);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, _texture); ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);// uniformsglUniform2f(_uniforms[kUniformBlurDis], blursDis[0], 0.0f); // attributesccV3F_C4B_T2F_Quad tempQuad;memset(&tempQuad, 0, sizeof(tempQuad));tempQuad.tl.vertices = vertex3(-1, 1, -1);tempQuad.bl.vertices = vertex3(-1, -1, -1);tempQuad.tr.vertices = vertex3(1, 1, -1);tempQuad.br.vertices = vertex3(1, -1, -1);tempQuad.tl.colors = ccc4(255, 255, 255, 255);tempQuad.bl.colors = ccc4(255, 255, 255, 255);tempQuad.tr.colors = ccc4(255, 255, 255, 255);tempQuad.br.colors = ccc4(255, 255, 255, 255);tempQuad.tl.texCoords = tex2(0, 1);tempQuad.bl.texCoords = tex2(0, 0);tempQuad.tr.texCoords = tex2(1, 1);tempQuad.br.texCoords = tex2(1, 0);data = (long)&tempQuad; glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, size, (GLvoid *)data); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, size, (GLvoid *)(data + sizeof(ccVertex3F))); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, size, (GLvoid *)(data + sizeof(ccVertex3F) + sizeof(ccColor4B))); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // **************************************// ************** third draw *****************glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);CC_NODE_DRAW_SETUP();ccGLBlendFunc(m_sBlendFunc.src, m_sBlendFunc.dst);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, _texture2); ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);// uniformsglUniform2f(_uniforms[kUniformBlurDis], 0.0f, blursDis[1]);// attributesglVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, size, (GLvoid *)data); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, size, (GLvoid *)(data + sizeof(ccVertex3F))); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, size, (GLvoid *)(data + sizeof(ccVertex3F) + sizeof(ccColor4B)));glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);// ************************************** // restore stackkmGLMatrixMode(KM_GL_PROJECTION);kmGLPopMatrix();kmGLMatrixMode(KM_GL_MODELVIEW);kmGLPopMatrix();CCDirector::sharedDirector()->setViewport();/**/ glDeleteTextures(1, &_texture); glDeleteFramebuffers(1, &_framebuffer);glDeleteTextures(1, &_texture2); glDeleteFramebuffers(1, &_framebuffer2);}由于在shader中重用了高斯模糊,横向和纵向两次的渲染代码,所以利用u_BlurDis[1]变量还区分是当前是横向处理还是纵向处理,并且在第二次纵向处理最终可以生成高斯模糊之后,顺便使模糊贴图透明,发亮,并用一般混合方式(ONE,ONE减SCR ALPHA)在发亮贴图下混合源贴图。fragment shader代码如下:
uniform sampler2D CC_Texture0;uniform sampler2D u_Texture1;uniform sampler2D u_Texture2;uniform vec2 u_BlurDis;varying vec4 v_Color;varying vec2 v_TexCoord;void main(){/**/ vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0); finalColor += texture2D(CC_Texture0, v_TexCoord - u_BlurDis * 4.0) * 0.05; finalColor += texture2D(CC_Texture0, v_TexCoord - u_BlurDis * 3.0) * 0.09; finalColor += texture2D(CC_Texture0, v_TexCoord - u_BlurDis * 2.0) * 0.12; finalColor += texture2D(CC_Texture0, v_TexCoord - u_BlurDis * 1.0) * 0.15; finalColor += texture2D(CC_Texture0, v_TexCoord) * 0.18; finalColor += texture2D(CC_Texture0, v_TexCoord + u_BlurDis * 1.0) * 0.15; finalColor += texture2D(CC_Texture0, v_TexCoord + u_BlurDis * 2.0) * 0.12; finalColor += texture2D(CC_Texture0, v_TexCoord + u_BlurDis * 3.0) * 0.09; finalColor += texture2D(CC_Texture0, v_TexCoord + u_BlurDis * 4.0) * 0.05; if (u_BlurDis[1] == 0.0) {gl_FragColor = v_Color * finalColor;} else {vec4 originColor = texture2D(CC_Texture0, v_TexCoord);vec4 blurColor = v_Color * finalColor;vec4 glowColor = blurColor * 0.5;glowColor.a = glowColor.a * 0.1;gl_FragColor = glowColor + (1.0 - glowColor.a) * originColor;}}代码中,利用高斯模糊贴图像素乘以0.5,并把其透明变为原来的0.1倍后才作为glowmap使用~这样会有好一点的发亮效果~最终效果如下:
0 0
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 七 辉光效果
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 二 简单模糊效果
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 三 高斯模糊效果一
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 四 高斯模糊效果二
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 五 节点树的模糊效果
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 六 节点树的描边效果
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 八 流光效果
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 一 基础回顾
- Cocos2d-x 3.x 图形学渲染系列七
- Cocos2d-x 3.x 图形学渲染系列七
- Cocos2d-x 粒子编辑器使用和渲染特效
- 【Cocos2d-x】实现翻牌效果
- cocos2d-x实现亮片效果
- cocos2d-x实现打字机效果
- cocos2d-x学习笔记(9)--effect(特效)
- cocos2d-x初学笔记10:特效Effect
- 【Cocos2d-x 3.0学习笔记】精灵特效
- 关于cocos2d-x 3.3网格特效笔记
- C、C++中的关键字总结
- POJ-2752
- Objective-C 判断两个矩形是否相交
- UVa 10006 - Carmichael Numbers
- leetcode——137—— Single Number II
- 【复习笔记】 cocos2d-x 2.x 渲染特效实现 七 辉光效果
- android按返回键和Home键都进入后台
- The user specified as a definer ('test'@'%') does not exist
- 图像处理的坐标变换必备的矩阵知识
- Dism 错误 0x800f0806
- 排序
- 安卓handler学习
- 地理定位(iOS 8.0)
- CodeForces 665E Beautiful Subarrays(Trie)