一、封装工具类
Shader.h
Shader.cpp
ShaderNode.cpp
ShaderNode.h
使用方法如下:
auto sprite = ShaderSprite::create(......);auto shader = Shader::createWithSrc(......);shader->drawCallOnSprite = function; // 在Sprite的draw中执行的回调,一般就是gl call指令shader->setUniformsAndAttribs = function; // 设置shader程序的uniform变量、attribute变量// ******************* 方 法 一:设置Sprite的shader// shader->setUniformsAndAttribs(); // 别忘了先设置好shader需要的数据sprite->setMainShader(shader); // 设置sprite的Shader// ******************* 方 法 二:给Sprite额外的shader,多个效果叠加// 在Sprite的draw中,先执行zorder<0的shader,再执行sprite的shader,然后执行zorder>=0的shadershader->setLocalZorder(...); // 设置zordersprite->addShader(shader); // 添加到队列中。addChild(sprite);
二、多纹理(MultiTexture)
C++:
const auto textureFile1 = "Images/grossini_sister1.png";const auto textureFile1 = "Images/grossini_sister2.png";const auto vShaderFile = "shaders/multiTexture.vsh";const auto fShaderFile = "shaders/multiTexture.fsh";const auto winSize = Director::getInstance()->getWinSize();auto texture1 = TextureCache::getInstance()->addImage(textureFile1);auto texture2 = TextureCache::getInstance()->addImage(textureFile2);auto sprite = Sprite::createWithTexture(texture1);// autorelease对象。如果我们要直接访问program,要自己retain起来维护,auto program = GLProgram::createWithFileNames(vShaderFile, fShaderFile);// programState已经缓存,且缓存中通过cocos2d::Map retain住了program// 因此program不会被销毁。programState也是autorelease对象,因此也要自己retain起来维护。auto programState = GLProgramState::getOrCreateWithGLProgram(program);float factor = 0.5f;sprite->setPosition(Vec2(winSize.width>>1, winSize.height>>1));addChild(sprite);// 设置自定义的ShaderprogramState->retain(); // 我们自己retain起来,GLProgramStateCache可能会清掉它。sprite->setProgramState(programState);// 在程序中动态设置shader的uniform值programState->setUniformFloat("factor", factor);programState->setUniformTexture("texture1", texture2);
顶点着色器:
ccPositionTextureColor_noMVP_vert// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"// Position Texture Color without MVP shader//// gl_Position = CC_PMatrix * a_position// gl_FragColor = texutreColor * a_color//
片段着色器:
uniform float factor;uniform sampler2D texture1;// 下面是GLProgram内部自动添加,对应Sprite::create(texture)里的texture// uniform Sampler2D CC_Texture0;#ifdef GL_ESprecision mediump float;#endifvarying vec4 v_fragmentColor;varying vec2 v_texCoord;void main(){gl_FragColor = v_fragmentColor *mix(texture2D(CC_Texture0, v_texCoord),texture2D(texture1, v_texCoord),factor);}
三、Lens Flare:镜头光晕

C++:
const auto winSize = Director::getInstance()->getWinSize();const auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();const auto visibleSize = Director::getInstance()->getVisibleSize();const auto retinaFactor = Director::getInstance()->getOpenGLView()->getRetinaFactor();const auto SizeX = 256;const auto SizeY = 256;const auto _resolution = Vec2( SizeX, SizeY );auto shaderNode = NodeShader::createWithFile( "", "Shaders/shadertoy_LensFlare.fsh" );auto position = Vec2( winSize.width / 2, winSize.height / 2 );auto _center = Vec2( position.x * frameSize.width / visibleSize.width * retinaFactor,position.y * frameSize.height / visibleSize.height * retinaFactor );shaderNode->setAnchorPoint( Vec2( 0.5f, 0.5f ) );shaderNode->setPosition( position );shaderNode->setContentSize( winSize / 2 );addChild( shaderNode );shaderNode->setDrawCall([=]( GLProgramState * const programState, const Mat4 & transform, uint32_t flags ) {GLfloat vertices[12] = { 0, 0,SizeX, 0,SizeX, SizeY,0, 0,0, SizeY,SizeX, SizeY};programState->setUniformVec2( "resolution", _resolution );programState->setUniformVec2( "center", _center );programState->setVertexAttribPointer( "a_position", 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid * ) vertices );programState->apply( transform );glDrawArrays( GL_TRIANGLES, 0, 6 );CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES( 1, 6 );} );
顶点着色器:
ccPositionTextureColor_vert// #include "renderer/ccShader_PositionTextureColor.vert"// Position Texture Color shader//// gl_Position = CC_MVPMatrix * a_position(顶点数据传入的顶点坐标)// gl_FragColor = texutreColor * a_color(顶点数据传入的color)//
片段着色器:
uniform vec2 center;uniform vec2 resolution;//uniform float iChannelTime[4]; // channel playback time (in seconds)//uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)vec4 iMouse = vec4(0,0,0,0); // mouse pixel coords. xy: current (if MLB down), zw: click//uniform sampler2D iChannel0; // input channel. XX = 2D/Cube/*by musk License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.Trying to get some interesting looking lens flares.13/08/13:publishedmuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuusk!*/float noise(float t){return 0.;}float noise(vec2 t){return 0.;}vec3 lensflare(vec2 uv,vec2 pos){vec2 main = uv-pos;vec2 uvd = uv*(length(uv));float ang = atan(main.x,main.y);float dist=length(main); dist = pow(dist,.1);float n = noise(vec2(ang*16.0,dist*32.0));float f0 = 1.0/(length(uv-pos)*16.0+1.0);f0 = f0+f0*(sin(noise((pos.x+pos.y)*2.2+ang*4.0+5.954)*16.0)*.1+dist*.1+.8);float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),.0)*00.25;float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*00.23;float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),.0)*00.21;vec2 uvx = mix(uv,uvd,-0.5);float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),.0)*6.0;float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),.0)*5.0;float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),.0)*3.0;uvx = mix(uv,uvd,-.4);float f5 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;float f52 = max(0.01-pow(length(uvx+0.4*pos),5.5),.0)*2.0;float f53 = max(0.01-pow(length(uvx+0.6*pos),5.5),.0)*2.0;uvx = mix(uv,uvd,-0.5);float f6 = max(0.01-pow(length(uvx-0.3*pos),1.6),.0)*6.0;float f62 = max(0.01-pow(length(uvx-0.325*pos),1.6),.0)*3.0;float f63 = max(0.01-pow(length(uvx-0.35*pos),1.6),.0)*5.0;vec3 c = vec3(.0);c.r+=f2+f4+f5+f6; c.g+=f22+f42+f52+f62; c.b+=f23+f43+f53+f63;c = c*1.3 - vec3(length(uvd)*.05);c+=vec3(f0);return c;}vec3 cc(vec3 color, float factor,float factor2) // color modifier{float w = color.x+color.y+color.z;return mix(color,vec3(w)*factor,w*factor2);}void main(void){vec2 iResolution = resolution; // viewport resolution (in pixels)float iGlobalTime = CC_Time[1]; // shader playback time (in seconds)//vec2 uv = gl_FragCoord.xy / iResolution.xy - 0.5;vec2 uv = (gl_FragCoord.xy - center.xy) / iResolution.xy;uv.x *= iResolution.x/iResolution.y; //fix aspect ratiovec3 mouse = vec3(iMouse.xy/iResolution.xy - 0.5,iMouse.z-.5);mouse.x *= iResolution.x/iResolution.y; //fix aspect ratioif (iMouse.z<.5){mouse.x=sin(iGlobalTime)*.5;mouse.y=sin(iGlobalTime*.913)*.5;}vec3 color = vec3(1.4,1.2,1.0)*lensflare(uv,mouse.xy);color -= noise(gl_FragCoord.xy)*.015;color = cc(color,.5,.1);gl_FragColor = vec4(color,1.0);}
四、Gaussian blur:高斯模糊

C++:
auto blurShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert, FileUtils::getInstance()->getStringFromFile( FileUtils::getInstance()->fullPathForFilename( "Shaders/example_Blur.fsh" ) ) );auto programState = blurShader->getGLProgramState();blurShader->drawCallOnSprite = [blurShader, programState](cocos2d::Sprite * target,cocos2d::Renderer * render,const cocos2d::Mat4 & transform,std::uint32_t flags,float globalZOrder,cocos2d::Texture2D * texture,cocos2d::BlendFunc & blendFunc,cocos2d::V3F_C4B_T2F_Quad * quad,TrianglesCommand::Triangles * triangles ){blurShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );render->addCommand( &blurShader->quadCommand );};blurShader->setUniformsAndAttribs = [shaderSprite, programState]{Size size = shaderSprite->getTexture()->getContentSizeInPixels();programState->setUniformVec2( "resolution", size );#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)programState->setUniformFloat( "blurRadius", 10 ); // 模板半径programState->setUniformFloat( "sampleNum", 5 ); // 采样数#endif};
顶点着色器:
ccPositionTextureColor_noMVP_vert// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"// Position Texture Color without MVP shader//// gl_Position = CC_PMatrix * a_position// gl_FragColor = texutreColor * a_color//
片段着色器:
#ifdef GL_ESprecision mediump float;#endifvarying vec4 v_fragmentColor;varying vec2 v_texCoord;uniform vec2 resolution;uniform float blurRadius;uniform float sampleNum;vec4 blur(vec2);void main(void){vec4 col = blur(v_texCoord); //* v_fragmentColor.rgb;gl_FragColor = vec4(col) * v_fragmentColor;}vec4 blur(vec2 p){if (blurRadius > 0.0 && sampleNum > 1.0){vec4 col = vec4(0);vec2 unit = 1.0 / resolution.xy;float r = blurRadius;float sampleStep = r / sampleNum;float count = 0.0;for(float x = -r; x < r; x += sampleStep){for(float y = -r; y < r; y += sampleStep){float weight = (r - abs(x)) * (r - abs(y));col += texture2D(CC_Texture0, p + vec2(x * unit.x, y * unit.y)) * weight;count += weight;}}return col / count;}return texture2D(CC_Texture0, p);}
五、heart:心跳

C++:
const auto winSize = Director::getInstance()->getWinSize();const auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();const auto visibleSize = Director::getInstance()->getVisibleSize();const auto retinaFactor = Director::getInstance()->getOpenGLView()->getRetinaFactor();const auto SizeX = 256;const auto SizeY = 256;const auto _resolution = Vec2( SizeX, SizeY );auto shaderNode = NodeShader::createWithFile( "", "Shaders/example_Heart.fsh" );auto position = Vec2( winSize.width / 2, winSize.height / 2 );auto _center = Vec2( position.x * frameSize.width / visibleSize.width * retinaFactor,position.y * frameSize.height / visibleSize.height * retinaFactor );shaderNode->setAnchorPoint( Vec2( 0.5f, 0.5f ) );shaderNode->setPosition( position );shaderNode->setContentSize( winSize / 2 );addChild( shaderNode );shaderNode->setDrawCall([ = ]( GLProgramState * const programState, const Mat4 & transform, uint32_t flags ){GLfloat vertices[12] = { 0, 0,SizeX, 0,SizeX, SizeY,0, 0,0, SizeY,SizeX, SizeY};programState->setUniformVec2( "resolution", _resolution );programState->setUniformVec2( "center", _center );programState->setVertexAttribPointer( "a_position", 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid * ) vertices );programState->apply( transform );glDrawArrays( GL_TRIANGLES, 0, 6 );CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES( 1, 6 );} );
顶点着色器:
ccPositionTextureColor_vert// #include "renderer/ccShader_PositionTextureColor.vert"// Position Texture Color shader//// gl_Position = CC_MVPMatrix * a_position(顶点数据传入的顶点坐标)// gl_FragColor = texutreColor * a_color(顶点数据传入的color)//
片段着色器:
// Shader from http://www.iquilezles.org/apps/shadertoy/#ifdef GL_ESprecision highp float;#endifuniform vec2 center;uniform vec2 resolution;void main(void){float time = CC_Time[1];vec2 p = 2.0 * (gl_FragCoord.xy - center.xy) / resolution.xy;// animatefloat tt = mod(time,2.0)/2.0;float ss = pow(tt,.2)*0.5 + 0.5;ss -= ss*0.2*sin(tt*6.2831*5.0)*exp(-tt*6.0);p *= vec2(0.5,1.5) + ss*vec2(0.5,-0.5);float a = atan(p.x,p.y)/3.141593;float r = length(p);// shapefloat h = abs(a);float d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);// colorfloat f = step(r,d) * pow(1.0-r/d,0.25);gl_FragColor = vec4(f,0.0,0.0,1.0);}
六、Glow:荧光

C++:
const auto winSize = Director::getInstance()->getWinSize();const auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();const auto visibleSize = Director::getInstance()->getVisibleSize();const auto retinaFactor = Director::getInstance()->getOpenGLView()->getRetinaFactor();const auto SizeX = 256;const auto SizeY = 256;const auto _resolution = Vec2( SizeX, SizeY );auto shaderNode = NodeShader::createWithFile( "", "Shaders/shadertoy_Glow.fsh" );auto position = Vec2( winSize.width / 2, winSize.height / 2 );auto _center = Vec2( position.x * frameSize.width / visibleSize.width * retinaFactor,position.y * frameSize.height / visibleSize.height * retinaFactor );shaderNode->setAnchorPoint( Vec2( 0.5f, 0.5f ) );shaderNode->setPosition( position );shaderNode->setContentSize( winSize / 2 );addChild( shaderNode );shaderNode->setDrawCall([ = ]( GLProgramState * const programState, const Mat4 & transform, uint32_t flags ){GLfloat vertices[12] = { 0, 0,SizeX, 0,SizeX, SizeY,0, 0,0, SizeY,SizeX, SizeY};programState->setUniformVec2( "resolution", _resolution );programState->setUniformVec2( "center", _center );programState->setVertexAttribPointer( "a_position", 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid * ) vertices );programState->apply( transform );glDrawArrays( GL_TRIANGLES, 0, 6 );CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES( 1, 6 );} );
顶点着色器:
ccPositionTextureColor_vert// #include "renderer/ccShader_PositionTextureColor.vert"// Position Texture Color shader//// gl_Position = CC_MVPMatrix * a_position(顶点数据传入的顶点坐标)// gl_FragColor = texutreColor * a_color(顶点数据传入的color)//
片段着色器:
uniform vec2 center;uniform vec2 resolution;//uniform float iChannelTime[4]; // channel playback time (in seconds)//uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)vec4 iMouse = vec4(0,0,0,0); // mouse pixel coords. xy: current (if MLB down), zw: click//uniform sampler2D iChannel0; // input channel. XX = 2D/Cubevoid main(void){vec2 iResolution = resolution; // viewport resolution (in pixels)float iGlobalTime = CC_Time[1]; // shader playback time (in seconds)float pointRadius = 0.06;float linkSize = 0.04;float noiseStrength = 0.08; // range: 0-1float minDimension = min(iResolution.x, iResolution.y);vec2 bounds = vec2(iResolution.x / minDimension, iResolution.y / minDimension);//vec2 uv = gl_FragCoord.xy / minDimension;vec2 uv = (2. * gl_FragCoord.xy - center.xy) / iResolution.xy;vec3 pointR = vec3(0.0, 0.0, 1.0);vec3 pointG = vec3(0.0, 0.0, 1.0);vec3 pointB = vec3(0.0, 0.0, 1.0);// Make the points orbit round the origin in 3 dimensions.// Coefficients are arbitrary to give different behaviours.// The Z coordinate should always be >0.0, as it's used directly to// multiply the radius to give the impression of depth.pointR.x += 0.32 * sin(1.32 * iGlobalTime);pointR.y += 0.3 * sin(1.03 * iGlobalTime);pointR.z += 0.4 * sin(1.32 * iGlobalTime);pointG.x += 0.31 * sin(0.92 * iGlobalTime);pointG.y += 0.29 * sin(0.99 * iGlobalTime);pointG.z += 0.38 * sin(1.24 * iGlobalTime);pointB.x += 0.33 * sin(1.245 * iGlobalTime);pointB.y += 0.3 * sin(1.41 * iGlobalTime);pointB.z += 0.41 * sin(1.11 * iGlobalTime);// Centre the points in the displayvec2 midUV = vec2(bounds.x * 0.5, bounds.y * 0.5);pointR.xy += midUV;pointG.xy += midUV;pointB.xy += midUV;// Calculate the vectors from the current fragment to the coloured pointsvec2 vecToR = pointR.xy - uv;vec2 vecToG = pointG.xy - uv;vec2 vecToB = pointB.xy - uv;vec2 dirToR = normalize(vecToR.xy);vec2 dirToG = normalize(vecToG.xy);vec2 dirToB = normalize(vecToB.xy);float distToR = length(vecToR);float distToG = length(vecToG);float distToB = length(vecToB);// Calculate the dot product between vectors from the current fragment to each pair// of adjacent coloured points. This helps us determine how close the current fragment// is to a link between points.float dotRG = dot(dirToR, dirToG);float dotGB = dot(dirToG, dirToB);float dotBR = dot(dirToB, dirToR);// Start with a bright coloured dot around each pointgl_FragColor.x = 1.0 - smoothstep(distToR, 0.0, pointRadius * pointR.z);gl_FragColor.y = 1.0 - smoothstep(distToG, 0.0, pointRadius * pointG.z);gl_FragColor.z = 1.0 - smoothstep(distToB, 0.0, pointRadius * pointB.z);gl_FragColor.w = 1.0;// We want to show a coloured link between adjacent points.// Determine the strength of each link at the current fragment.// This tends towards 1.0 as the vectors to each point tend towards opposite directions.float linkStrengthRG = 1.0 - smoothstep(dotRG, -1.01, -1.0 + (linkSize * pointR.z * pointG.z));float linkStrengthGB = 1.0 - smoothstep(dotGB, -1.01, -1.0 + (linkSize * pointG.z * pointB.z));float linkStrengthBR = 1.0 - smoothstep(dotBR, -1.01, -1.0 + (linkSize * pointB.z * pointR.z));// If the current fragment is in a link, we need to know how much the// linked points contribute of their colour.float sumDistRG = distToR + distToG;float sumDistGB = distToG + distToB;float sumDistBR = distToB + distToR;float contribRonRG = 1.0 - (distToR / sumDistRG);float contribRonBR = 1.0 - (distToR / sumDistBR);float contribGonRG = 1.0 - (distToG / sumDistRG);float contribGonGB = 1.0 - (distToG / sumDistGB);float contribBonGB = 1.0 - (distToB / sumDistGB);float contribBonBR = 1.0 - (distToB / sumDistBR);// Additively blend the link colours into the fragment.gl_FragColor.x += (linkStrengthRG * contribRonRG) + (linkStrengthBR * contribRonBR);gl_FragColor.y += (linkStrengthGB * contribGonGB) + (linkStrengthRG * contribGonRG);gl_FragColor.z += (linkStrengthBR * contribBonBR) + (linkStrengthGB * contribBonGB);// Use an underlying texture to provide some noisefloat noiseMin = 1.0 - noiseStrength;gl_FragColor.xyz *= (1.0 - noiseStrength) + (noiseStrength * 0.);}
七、outLine:描边

C++
#define getFileData(a) FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(a))auto outlineShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert, getFileData( "Shaders/example_Outline.fsh" ) );auto programState = outlineShader->getGLProgramState();outlineShader->drawCallOnSprite = [outlineShader, programState](cocos2d::Sprite * target,cocos2d::Renderer * render,const cocos2d::Mat4 & transform,std::uint32_t flags,float globalZOrder,cocos2d::Texture2D * texture,cocos2d::BlendFunc & blendFunc,cocos2d::V3F_C4B_T2F_Quad * quad,cocos2d::TrianglesCommand::Triangles * triangles ){outlineShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );render->addCommand( &outlineShader->quadCommand );};outlineShader->setUniformsAndAttribs = [programState]{Vec3 color( 1.0f, 0.2f, 0.3f );GLfloat radius = 0.01f;GLfloat threshold = 1.75;programState->setUniformVec3( "u_outlineColor", color );programState->setUniformFloat( "u_radius", radius );programState->setUniformFloat( "u_threshold", threshold );};
顶点着色器
ccPositionTextureColor_noMVP_vert
片段着色器
/*Created by guanghui on 4/8/14.http://www.idevgames.com/forums/thread-3010.html*/varying vec2 v_texCoord;varying vec4 v_fragmentColor;uniform vec3 u_outlineColor;uniform float u_threshold;uniform float u_radius;void main(){float radius = u_radius;vec4 accum = vec4(0.0);vec4 normal = vec4(0.0);normal = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y));accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y - radius));accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y - radius));accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y + radius));accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y + radius));accum *= u_threshold;accum.rgb = u_outlineColor * accum.a;accum.a = 1.0;normal = ( accum * (1.0 - normal.a)) + (normal * normal.a);gl_FragColor = v_fragmentColor * normal;}
八、noise:噪声点

C++
auto noiseShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert,FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename( "Shaders/example_Noisy.fsh" ) ) );auto programState = noiseShader->getGLProgramState();noiseShader->drawCallOnSprite = [noiseShader, programState](cocos2d::Sprite * target,cocos2d::Renderer * render,const cocos2d::Mat4 & transform,std::uint32_t flags,float globalZOrder,cocos2d::Texture2D * texture,cocos2d::BlendFunc & blendFunc,cocos2d::V3F_C4B_T2F_Quad * quad,cocos2d::TrianglesCommand::Triangles * triangles ){noiseShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );render->addCommand( &noiseShader->quadCommand );};noiseShader->setUniformsAndAttribs = [ = ]{auto s = shaderSprite->getTexture()->getContentSizeInPixels();programState->setUniformVec2( "resolution", Vec2( s.width, s.height ) );}
顶点着色器
ccPositionTextureColor_noMVP_vert
片段着色器
// Shader taken from: http://webglsamples.googlecode.com/hg/electricflower/electricflower.html#ifdef GL_ESprecision mediump float;#endifvarying vec4 v_fragmentColor;varying vec2 v_texCoord;uniform vec2 resolution;const float intensity = 0.05;vec3 noise(vec2 uv){vec2 p = abs(sin(uv * 13.0 + uv.x * CC_Time[1] * sin(uv.y)));return vec3(sin (0.2 * CC_Time[1] + sin(p * 0.5) * CC_Time[1] / cos(50.0)) * 10.0,0.3+0.5 * abs(sin(CC_Time[1] * tan(5.0))));}void main(void){gl_FragColor.xyz = intensity * noise(gl_FragCoord.xy / sin(resolution.xy * CC_Time[1] * 0.01)) + (1. - intensity) *texture2D(CC_Texture0,v_texCoord.xy).xyz;gl_FragColor.w = 1.;}
九、边缘检测

C++
auto edgeDetectShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert,FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename( "Shaders/example_EdgeDetection.fsh" ) ) );auto programState = edgeDetectShader->getGLProgramState();edgeDetectShader->drawCallOnSprite = [edgeDetectShader, programState](cocos2d::Sprite * target,cocos2d::Renderer * render,const cocos2d::Mat4 & transform,std::uint32_t flags,float globalZOrder,cocos2d::Texture2D * texture,cocos2d::BlendFunc & blendFunc,cocos2d::V3F_C4B_T2F_Quad * quad,cocos2d::TrianglesCommand::Triangles * triangles ){edgeDetectShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );render->addCommand( &edgeDetectShader->quadCommand );};noiseShader->setUniformsAndAttribs = [ = ]{auto s = shaderSprite->getTexture()->getContentSizeInPixels();programState->setUniformVec2( "resolution", Vec2( s.width, s.height ) );};
顶点着色器
ccPositionTextureColor_noMVP_vert
片段着色器
#ifdef GL_ESprecision mediump float;#endifvarying vec4 v_fragmentColor;varying vec2 v_texCoord;uniform vec2 resolution;float lookup(vec2 p, float dx, float dy){vec2 uv = p.xy + vec2(dx , dy ) / resolution.xy;vec4 c = texture2D(CC_Texture0, uv.xy);return 0.2126*c.r + 0.7152*c.g + 0.0722*c.b;}void main(void){vec2 p = v_texCoord.xy;// simple sobel edge detectionfloat gx = 0.0;gx += -1.0 * lookup(p, -1.0, -1.0);gx += -2.0 * lookup(p, -1.0, 0.0);gx += -1.0 * lookup(p, -1.0, 1.0);gx += 1.0 * lookup(p, 1.0, -1.0);gx += 2.0 * lookup(p, 1.0, 0.0);gx += 1.0 * lookup(p, 1.0, 1.0);float gy = 0.0;gy += -1.0 * lookup(p, -1.0, -1.0);gy += -2.0 * lookup(p, 0.0, -1.0);gy += -1.0 * lookup(p, 1.0, -1.0);gy += 1.0 * lookup(p, -1.0, 1.0);gy += 2.0 * lookup(p, 0.0, 1.0);gy += 1.0 * lookup(p, 1.0, 1.0);float g = gx*gx + gy*gy;gl_FragColor.xyz = vec3(1.-g);gl_FragColor.w = 1.;}
十、GrayScale:灰度图

C++
auto grayScaleShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert,FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename( "Shaders/example_GreyScale.fsh" ) ) );auto programState = grayScaleShader->getGLProgramState();grayScaleShader->drawCallOnSprite = [grayScaleShader, programState](cocos2d::Sprite * target,cocos2d::Renderer * render,const cocos2d::Mat4 & transform,std::uint32_t flags,float globalZOrder,cocos2d::Texture2D * texture,cocos2d::BlendFunc & blendFunc,cocos2d::V3F_C4B_T2F_Quad * quad,cocos2d::TrianglesCommand::Triangles * triangles ){grayScaleShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );render->addCommand( &grayScaleShader->quadCommand );};grayScaleShader->setUniformsAndAttribs = [ = ]{auto s = shaderSprite->getTexture()->getContentSizeInPixels();programState->setUniformVec2( "resolution", Vec2( s.width, s.height ) );};
顶点着色器
ccPositionTextureColor_noMVP_vert
片段着色器
#ifdef GL_ESprecision mediump float;#endifvarying vec4 v_fragmentColor;varying vec2 v_texCoord;void main(void){vec4 c = texture2D(CC_Texture0, v_texCoord);gl_FragColor.xyz = vec3(0.2126*c.r + 0.7152*c.g + 0.0722*c.b);gl_FragColor.w = c.w;}
十一、Glare Lens Flare


