一、封装工具类

Shader.h
Shader.cpp
ShaderNode.cpp
ShaderNode.h
使用方法如下:

  1. auto sprite = ShaderSprite::create(......);
  2. auto shader = Shader::createWithSrc(......);
  3. shader->drawCallOnSprite = function; // 在Sprite的draw中执行的回调,一般就是gl call指令
  4. shader->setUniformsAndAttribs = function; // 设置shader程序的uniform变量、attribute变量
  5. // ******************* 方 法 一:设置Sprite的shader
  6. // shader->setUniformsAndAttribs(); // 别忘了先设置好shader需要的数据
  7. sprite->setMainShader(shader); // 设置sprite的Shader
  8. // ******************* 方 法 二:给Sprite额外的shader,多个效果叠加
  9. // 在Sprite的draw中,先执行zorder<0的shader,再执行sprite的shader,然后执行zorder>=0的shader
  10. shader->setLocalZorder(...); // 设置zorder
  11. sprite->addShader(shader); // 添加到队列中。
  12. addChild(sprite);

二、多纹理(MultiTexture)

GIF.gif

C++:

  1. const auto textureFile1 = "Images/grossini_sister1.png";
  2. const auto textureFile1 = "Images/grossini_sister2.png";
  3. const auto vShaderFile = "shaders/multiTexture.vsh";
  4. const auto fShaderFile = "shaders/multiTexture.fsh";
  5. const auto winSize = Director::getInstance()->getWinSize();
  6. auto texture1 = TextureCache::getInstance()->addImage(textureFile1);
  7. auto texture2 = TextureCache::getInstance()->addImage(textureFile2);
  8. auto sprite = Sprite::createWithTexture(texture1);
  9. // autorelease对象。如果我们要直接访问program,要自己retain起来维护,
  10. auto program = GLProgram::createWithFileNames(vShaderFile, fShaderFile);
  11. // programState已经缓存,且缓存中通过cocos2d::Map retain住了program
  12. // 因此program不会被销毁。programState也是autorelease对象,因此也要自己retain起来维护。
  13. auto programState = GLProgramState::getOrCreateWithGLProgram(program);
  14. float factor = 0.5f;
  15. sprite->setPosition(Vec2(winSize.width>>1, winSize.height>>1));
  16. addChild(sprite);
  17. // 设置自定义的Shader
  18. programState->retain(); // 我们自己retain起来,GLProgramStateCache可能会清掉它。
  19. sprite->setProgramState(programState);
  20. // 在程序中动态设置shader的uniform值
  21. programState->setUniformFloat("factor", factor);
  22. programState->setUniformTexture("texture1", texture2);

顶点着色器:

  1. ccPositionTextureColor_noMVP_vert
  2. // #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
  3. // Position Texture Color without MVP shader
  4. //
  5. // gl_Position = CC_PMatrix * a_position
  6. // gl_FragColor = texutreColor * a_color
  7. //

片段着色器:

  1. uniform float factor;
  2. uniform sampler2D texture1;
  3. // 下面是GLProgram内部自动添加,对应Sprite::create(texture)里的texture
  4. // uniform Sampler2D CC_Texture0;
  5. #ifdef GL_ES
  6. precision mediump float;
  7. #endif
  8. varying vec4 v_fragmentColor;
  9. varying vec2 v_texCoord;
  10. void main(){
  11. gl_FragColor = v_fragmentColor *
  12. mix(texture2D(CC_Texture0, v_texCoord),
  13. texture2D(texture1, v_texCoord),
  14. factor);
  15. }

三、Lens Flare:镜头光晕

GIF.gif
C++:

  1. const auto winSize = Director::getInstance()->getWinSize();
  2. const auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();
  3. const auto visibleSize = Director::getInstance()->getVisibleSize();
  4. const auto retinaFactor = Director::getInstance()->getOpenGLView()->getRetinaFactor();
  5. const auto SizeX = 256;
  6. const auto SizeY = 256;
  7. const auto _resolution = Vec2( SizeX, SizeY );
  8. auto shaderNode = NodeShader::createWithFile( "", "Shaders/shadertoy_LensFlare.fsh" );
  9. auto position = Vec2( winSize.width / 2, winSize.height / 2 );
  10. auto _center = Vec2( position.x * frameSize.width / visibleSize.width * retinaFactor,
  11. position.y * frameSize.height / visibleSize.height * retinaFactor );
  12. shaderNode->setAnchorPoint( Vec2( 0.5f, 0.5f ) );
  13. shaderNode->setPosition( position );
  14. shaderNode->setContentSize( winSize / 2 );
  15. addChild( shaderNode );
  16. shaderNode->setDrawCall(
  17. [=]( GLProgramState * const programState, const Mat4 & transform, uint32_t flags ) {
  18. GLfloat vertices[12] = { 0, 0,
  19. SizeX, 0,
  20. SizeX, SizeY,
  21. 0, 0,
  22. 0, SizeY,
  23. SizeX, SizeY
  24. };
  25. programState->setUniformVec2( "resolution", _resolution );
  26. programState->setUniformVec2( "center", _center );
  27. programState->setVertexAttribPointer( "a_position", 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid * ) vertices );
  28. programState->apply( transform );
  29. glDrawArrays( GL_TRIANGLES, 0, 6 );
  30. CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES( 1, 6 );
  31. } );

顶点着色器:

  1. ccPositionTextureColor_vert
  2. // #include "renderer/ccShader_PositionTextureColor.vert"
  3. // Position Texture Color shader
  4. //
  5. // gl_Position = CC_MVPMatrix * a_position(顶点数据传入的顶点坐标)
  6. // gl_FragColor = texutreColor * a_color(顶点数据传入的color)
  7. //

片段着色器:

  1. uniform vec2 center;
  2. uniform vec2 resolution;
  3. //uniform float iChannelTime[4]; // channel playback time (in seconds)
  4. //uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
  5. vec4 iMouse = vec4(0,0,0,0); // mouse pixel coords. xy: current (if MLB down), zw: click
  6. //uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
  7. /*by musk License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
  8. Trying to get some interesting looking lens flares.
  9. 13/08/13:
  10. published
  11. muuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuusk!*/
  12. float noise(float t)
  13. {
  14. return 0.;
  15. }
  16. float noise(vec2 t)
  17. {
  18. return 0.;
  19. }
  20. vec3 lensflare(vec2 uv,vec2 pos)
  21. {
  22. vec2 main = uv-pos;
  23. vec2 uvd = uv*(length(uv));
  24. float ang = atan(main.x,main.y);
  25. float dist=length(main); dist = pow(dist,.1);
  26. float n = noise(vec2(ang*16.0,dist*32.0));
  27. float f0 = 1.0/(length(uv-pos)*16.0+1.0);
  28. f0 = f0+f0*(sin(noise((pos.x+pos.y)*2.2+ang*4.0+5.954)*16.0)*.1+dist*.1+.8);
  29. float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;
  30. float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),.0)*00.25;
  31. float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*00.23;
  32. float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),.0)*00.21;
  33. vec2 uvx = mix(uv,uvd,-0.5);
  34. float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),.0)*6.0;
  35. float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),.0)*5.0;
  36. float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),.0)*3.0;
  37. uvx = mix(uv,uvd,-.4);
  38. float f5 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;
  39. float f52 = max(0.01-pow(length(uvx+0.4*pos),5.5),.0)*2.0;
  40. float f53 = max(0.01-pow(length(uvx+0.6*pos),5.5),.0)*2.0;
  41. uvx = mix(uv,uvd,-0.5);
  42. float f6 = max(0.01-pow(length(uvx-0.3*pos),1.6),.0)*6.0;
  43. float f62 = max(0.01-pow(length(uvx-0.325*pos),1.6),.0)*3.0;
  44. float f63 = max(0.01-pow(length(uvx-0.35*pos),1.6),.0)*5.0;
  45. vec3 c = vec3(.0);
  46. c.r+=f2+f4+f5+f6; c.g+=f22+f42+f52+f62; c.b+=f23+f43+f53+f63;
  47. c = c*1.3 - vec3(length(uvd)*.05);
  48. c+=vec3(f0);
  49. return c;
  50. }
  51. vec3 cc(vec3 color, float factor,float factor2) // color modifier
  52. {
  53. float w = color.x+color.y+color.z;
  54. return mix(color,vec3(w)*factor,w*factor2);
  55. }
  56. void main(void)
  57. {
  58. vec2 iResolution = resolution; // viewport resolution (in pixels)
  59. float iGlobalTime = CC_Time[1]; // shader playback time (in seconds)
  60. //vec2 uv = gl_FragCoord.xy / iResolution.xy - 0.5;
  61. vec2 uv = (gl_FragCoord.xy - center.xy) / iResolution.xy;
  62. uv.x *= iResolution.x/iResolution.y; //fix aspect ratio
  63. vec3 mouse = vec3(iMouse.xy/iResolution.xy - 0.5,iMouse.z-.5);
  64. mouse.x *= iResolution.x/iResolution.y; //fix aspect ratio
  65. if (iMouse.z<.5)
  66. {
  67. mouse.x=sin(iGlobalTime)*.5;
  68. mouse.y=sin(iGlobalTime*.913)*.5;
  69. }
  70. vec3 color = vec3(1.4,1.2,1.0)*lensflare(uv,mouse.xy);
  71. color -= noise(gl_FragCoord.xy)*.015;
  72. color = cc(color,.5,.1);
  73. gl_FragColor = vec4(color,1.0);
  74. }

四、Gaussian blur:高斯模糊

GIF.gif
C++:

  1. auto blurShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert, FileUtils::getInstance()->getStringFromFile( FileUtils::getInstance()->fullPathForFilename( "Shaders/example_Blur.fsh" ) ) );
  2. auto programState = blurShader->getGLProgramState();
  3. blurShader->drawCallOnSprite = [blurShader, programState](
  4. cocos2d::Sprite * target,
  5. cocos2d::Renderer * render,
  6. const cocos2d::Mat4 & transform,
  7. std::uint32_t flags,
  8. float globalZOrder,
  9. cocos2d::Texture2D * texture,
  10. cocos2d::BlendFunc & blendFunc,
  11. cocos2d::V3F_C4B_T2F_Quad * quad,
  12. TrianglesCommand::Triangles * triangles )
  13. {
  14. blurShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );
  15. render->addCommand( &blurShader->quadCommand );
  16. };
  17. blurShader->setUniformsAndAttribs = [shaderSprite, programState]
  18. {
  19. Size size = shaderSprite->getTexture()->getContentSizeInPixels();
  20. programState->setUniformVec2( "resolution", size );
  21. #if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
  22. programState->setUniformFloat( "blurRadius", 10 ); // 模板半径
  23. programState->setUniformFloat( "sampleNum", 5 ); // 采样数
  24. #endif
  25. };

顶点着色器:

  1. ccPositionTextureColor_noMVP_vert
  2. // #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
  3. // Position Texture Color without MVP shader
  4. //
  5. // gl_Position = CC_PMatrix * a_position
  6. // gl_FragColor = texutreColor * a_color
  7. //

片段着色器:

  1. #ifdef GL_ES
  2. precision mediump float;
  3. #endif
  4. varying vec4 v_fragmentColor;
  5. varying vec2 v_texCoord;
  6. uniform vec2 resolution;
  7. uniform float blurRadius;
  8. uniform float sampleNum;
  9. vec4 blur(vec2);
  10. void main(void)
  11. {
  12. vec4 col = blur(v_texCoord); //* v_fragmentColor.rgb;
  13. gl_FragColor = vec4(col) * v_fragmentColor;
  14. }
  15. vec4 blur(vec2 p)
  16. {
  17. if (blurRadius > 0.0 && sampleNum > 1.0)
  18. {
  19. vec4 col = vec4(0);
  20. vec2 unit = 1.0 / resolution.xy;
  21. float r = blurRadius;
  22. float sampleStep = r / sampleNum;
  23. float count = 0.0;
  24. for(float x = -r; x < r; x += sampleStep)
  25. {
  26. for(float y = -r; y < r; y += sampleStep)
  27. {
  28. float weight = (r - abs(x)) * (r - abs(y));
  29. col += texture2D(CC_Texture0, p + vec2(x * unit.x, y * unit.y)) * weight;
  30. count += weight;
  31. }
  32. }
  33. return col / count;
  34. }
  35. return texture2D(CC_Texture0, p);
  36. }

五、heart:心跳

GIF.gif
C++:

  1. const auto winSize = Director::getInstance()->getWinSize();
  2. const auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();
  3. const auto visibleSize = Director::getInstance()->getVisibleSize();
  4. const auto retinaFactor = Director::getInstance()->getOpenGLView()->getRetinaFactor();
  5. const auto SizeX = 256;
  6. const auto SizeY = 256;
  7. const auto _resolution = Vec2( SizeX, SizeY );
  8. auto shaderNode = NodeShader::createWithFile( "", "Shaders/example_Heart.fsh" );
  9. auto position = Vec2( winSize.width / 2, winSize.height / 2 );
  10. auto _center = Vec2( position.x * frameSize.width / visibleSize.width * retinaFactor,
  11. position.y * frameSize.height / visibleSize.height * retinaFactor );
  12. shaderNode->setAnchorPoint( Vec2( 0.5f, 0.5f ) );
  13. shaderNode->setPosition( position );
  14. shaderNode->setContentSize( winSize / 2 );
  15. addChild( shaderNode );
  16. shaderNode->setDrawCall(
  17. [ = ]( GLProgramState * const programState, const Mat4 & transform, uint32_t flags )
  18. {
  19. GLfloat vertices[12] = { 0, 0,
  20. SizeX, 0,
  21. SizeX, SizeY,
  22. 0, 0,
  23. 0, SizeY,
  24. SizeX, SizeY
  25. };
  26. programState->setUniformVec2( "resolution", _resolution );
  27. programState->setUniformVec2( "center", _center );
  28. programState->setVertexAttribPointer( "a_position", 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid * ) vertices );
  29. programState->apply( transform );
  30. glDrawArrays( GL_TRIANGLES, 0, 6 );
  31. CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES( 1, 6 );
  32. } );

顶点着色器:

  1. ccPositionTextureColor_vert
  2. // #include "renderer/ccShader_PositionTextureColor.vert"
  3. // Position Texture Color shader
  4. //
  5. // gl_Position = CC_MVPMatrix * a_position(顶点数据传入的顶点坐标)
  6. // gl_FragColor = texutreColor * a_color(顶点数据传入的color)
  7. //

片段着色器:

  1. // Shader from http://www.iquilezles.org/apps/shadertoy/
  2. #ifdef GL_ES
  3. precision highp float;
  4. #endif
  5. uniform vec2 center;
  6. uniform vec2 resolution;
  7. void main(void)
  8. {
  9. float time = CC_Time[1];
  10. vec2 p = 2.0 * (gl_FragCoord.xy - center.xy) / resolution.xy;
  11. // animate
  12. float tt = mod(time,2.0)/2.0;
  13. float ss = pow(tt,.2)*0.5 + 0.5;
  14. ss -= ss*0.2*sin(tt*6.2831*5.0)*exp(-tt*6.0);
  15. p *= vec2(0.5,1.5) + ss*vec2(0.5,-0.5);
  16. float a = atan(p.x,p.y)/3.141593;
  17. float r = length(p);
  18. // shape
  19. float h = abs(a);
  20. float d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);
  21. // color
  22. float f = step(r,d) * pow(1.0-r/d,0.25);
  23. gl_FragColor = vec4(f,0.0,0.0,1.0);
  24. }

六、Glow:荧光

GIF.gif
C++:

  1. const auto winSize = Director::getInstance()->getWinSize();
  2. const auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();
  3. const auto visibleSize = Director::getInstance()->getVisibleSize();
  4. const auto retinaFactor = Director::getInstance()->getOpenGLView()->getRetinaFactor();
  5. const auto SizeX = 256;
  6. const auto SizeY = 256;
  7. const auto _resolution = Vec2( SizeX, SizeY );
  8. auto shaderNode = NodeShader::createWithFile( "", "Shaders/shadertoy_Glow.fsh" );
  9. auto position = Vec2( winSize.width / 2, winSize.height / 2 );
  10. auto _center = Vec2( position.x * frameSize.width / visibleSize.width * retinaFactor,
  11. position.y * frameSize.height / visibleSize.height * retinaFactor );
  12. shaderNode->setAnchorPoint( Vec2( 0.5f, 0.5f ) );
  13. shaderNode->setPosition( position );
  14. shaderNode->setContentSize( winSize / 2 );
  15. addChild( shaderNode );
  16. shaderNode->setDrawCall(
  17. [ = ]( GLProgramState * const programState, const Mat4 & transform, uint32_t flags )
  18. {
  19. GLfloat vertices[12] = { 0, 0,
  20. SizeX, 0,
  21. SizeX, SizeY,
  22. 0, 0,
  23. 0, SizeY,
  24. SizeX, SizeY
  25. };
  26. programState->setUniformVec2( "resolution", _resolution );
  27. programState->setUniformVec2( "center", _center );
  28. programState->setVertexAttribPointer( "a_position", 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid * ) vertices );
  29. programState->apply( transform );
  30. glDrawArrays( GL_TRIANGLES, 0, 6 );
  31. CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES( 1, 6 );
  32. } );

顶点着色器:

  1. ccPositionTextureColor_vert
  2. // #include "renderer/ccShader_PositionTextureColor.vert"
  3. // Position Texture Color shader
  4. //
  5. // gl_Position = CC_MVPMatrix * a_position(顶点数据传入的顶点坐标)
  6. // gl_FragColor = texutreColor * a_color(顶点数据传入的color)
  7. //

片段着色器:

  1. uniform vec2 center;
  2. uniform vec2 resolution;
  3. //uniform float iChannelTime[4]; // channel playback time (in seconds)
  4. //uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
  5. vec4 iMouse = vec4(0,0,0,0); // mouse pixel coords. xy: current (if MLB down), zw: click
  6. //uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
  7. void main(void)
  8. {
  9. vec2 iResolution = resolution; // viewport resolution (in pixels)
  10. float iGlobalTime = CC_Time[1]; // shader playback time (in seconds)
  11. float pointRadius = 0.06;
  12. float linkSize = 0.04;
  13. float noiseStrength = 0.08; // range: 0-1
  14. float minDimension = min(iResolution.x, iResolution.y);
  15. vec2 bounds = vec2(iResolution.x / minDimension, iResolution.y / minDimension);
  16. //vec2 uv = gl_FragCoord.xy / minDimension;
  17. vec2 uv = (2. * gl_FragCoord.xy - center.xy) / iResolution.xy;
  18. vec3 pointR = vec3(0.0, 0.0, 1.0);
  19. vec3 pointG = vec3(0.0, 0.0, 1.0);
  20. vec3 pointB = vec3(0.0, 0.0, 1.0);
  21. // Make the points orbit round the origin in 3 dimensions.
  22. // Coefficients are arbitrary to give different behaviours.
  23. // The Z coordinate should always be >0.0, as it's used directly to
  24. // multiply the radius to give the impression of depth.
  25. pointR.x += 0.32 * sin(1.32 * iGlobalTime);
  26. pointR.y += 0.3 * sin(1.03 * iGlobalTime);
  27. pointR.z += 0.4 * sin(1.32 * iGlobalTime);
  28. pointG.x += 0.31 * sin(0.92 * iGlobalTime);
  29. pointG.y += 0.29 * sin(0.99 * iGlobalTime);
  30. pointG.z += 0.38 * sin(1.24 * iGlobalTime);
  31. pointB.x += 0.33 * sin(1.245 * iGlobalTime);
  32. pointB.y += 0.3 * sin(1.41 * iGlobalTime);
  33. pointB.z += 0.41 * sin(1.11 * iGlobalTime);
  34. // Centre the points in the display
  35. vec2 midUV = vec2(bounds.x * 0.5, bounds.y * 0.5);
  36. pointR.xy += midUV;
  37. pointG.xy += midUV;
  38. pointB.xy += midUV;
  39. // Calculate the vectors from the current fragment to the coloured points
  40. vec2 vecToR = pointR.xy - uv;
  41. vec2 vecToG = pointG.xy - uv;
  42. vec2 vecToB = pointB.xy - uv;
  43. vec2 dirToR = normalize(vecToR.xy);
  44. vec2 dirToG = normalize(vecToG.xy);
  45. vec2 dirToB = normalize(vecToB.xy);
  46. float distToR = length(vecToR);
  47. float distToG = length(vecToG);
  48. float distToB = length(vecToB);
  49. // Calculate the dot product between vectors from the current fragment to each pair
  50. // of adjacent coloured points. This helps us determine how close the current fragment
  51. // is to a link between points.
  52. float dotRG = dot(dirToR, dirToG);
  53. float dotGB = dot(dirToG, dirToB);
  54. float dotBR = dot(dirToB, dirToR);
  55. // Start with a bright coloured dot around each point
  56. gl_FragColor.x = 1.0 - smoothstep(distToR, 0.0, pointRadius * pointR.z);
  57. gl_FragColor.y = 1.0 - smoothstep(distToG, 0.0, pointRadius * pointG.z);
  58. gl_FragColor.z = 1.0 - smoothstep(distToB, 0.0, pointRadius * pointB.z);
  59. gl_FragColor.w = 1.0;
  60. // We want to show a coloured link between adjacent points.
  61. // Determine the strength of each link at the current fragment.
  62. // This tends towards 1.0 as the vectors to each point tend towards opposite directions.
  63. float linkStrengthRG = 1.0 - smoothstep(dotRG, -1.01, -1.0 + (linkSize * pointR.z * pointG.z));
  64. float linkStrengthGB = 1.0 - smoothstep(dotGB, -1.01, -1.0 + (linkSize * pointG.z * pointB.z));
  65. float linkStrengthBR = 1.0 - smoothstep(dotBR, -1.01, -1.0 + (linkSize * pointB.z * pointR.z));
  66. // If the current fragment is in a link, we need to know how much the
  67. // linked points contribute of their colour.
  68. float sumDistRG = distToR + distToG;
  69. float sumDistGB = distToG + distToB;
  70. float sumDistBR = distToB + distToR;
  71. float contribRonRG = 1.0 - (distToR / sumDistRG);
  72. float contribRonBR = 1.0 - (distToR / sumDistBR);
  73. float contribGonRG = 1.0 - (distToG / sumDistRG);
  74. float contribGonGB = 1.0 - (distToG / sumDistGB);
  75. float contribBonGB = 1.0 - (distToB / sumDistGB);
  76. float contribBonBR = 1.0 - (distToB / sumDistBR);
  77. // Additively blend the link colours into the fragment.
  78. gl_FragColor.x += (linkStrengthRG * contribRonRG) + (linkStrengthBR * contribRonBR);
  79. gl_FragColor.y += (linkStrengthGB * contribGonGB) + (linkStrengthRG * contribGonRG);
  80. gl_FragColor.z += (linkStrengthBR * contribBonBR) + (linkStrengthGB * contribBonGB);
  81. // Use an underlying texture to provide some noise
  82. float noiseMin = 1.0 - noiseStrength;
  83. gl_FragColor.xyz *= (1.0 - noiseStrength) + (noiseStrength * 0.);
  84. }

七、outLine:描边

image.png
C++

  1. #define getFileData(a) FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(a))
  2. auto outlineShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert, getFileData( "Shaders/example_Outline.fsh" ) );
  3. auto programState = outlineShader->getGLProgramState();
  4. outlineShader->drawCallOnSprite = [outlineShader, programState](
  5. cocos2d::Sprite * target,
  6. cocos2d::Renderer * render,
  7. const cocos2d::Mat4 & transform,
  8. std::uint32_t flags,
  9. float globalZOrder,
  10. cocos2d::Texture2D * texture,
  11. cocos2d::BlendFunc & blendFunc,
  12. cocos2d::V3F_C4B_T2F_Quad * quad,
  13. cocos2d::TrianglesCommand::Triangles * triangles )
  14. {
  15. outlineShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );
  16. render->addCommand( &outlineShader->quadCommand );
  17. };
  18. outlineShader->setUniformsAndAttribs = [programState]
  19. {
  20. Vec3 color( 1.0f, 0.2f, 0.3f );
  21. GLfloat radius = 0.01f;
  22. GLfloat threshold = 1.75;
  23. programState->setUniformVec3( "u_outlineColor", color );
  24. programState->setUniformFloat( "u_radius", radius );
  25. programState->setUniformFloat( "u_threshold", threshold );
  26. };

顶点着色器

  1. ccPositionTextureColor_noMVP_vert

片段着色器

  1. /*
  2. Created by guanghui on 4/8/14.
  3. http://www.idevgames.com/forums/thread-3010.html
  4. */
  5. varying vec2 v_texCoord;
  6. varying vec4 v_fragmentColor;
  7. uniform vec3 u_outlineColor;
  8. uniform float u_threshold;
  9. uniform float u_radius;
  10. void main()
  11. {
  12. float radius = u_radius;
  13. vec4 accum = vec4(0.0);
  14. vec4 normal = vec4(0.0);
  15. normal = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y));
  16. accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y - radius));
  17. accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y - radius));
  18. accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y + radius));
  19. accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y + radius));
  20. accum *= u_threshold;
  21. accum.rgb = u_outlineColor * accum.a;
  22. accum.a = 1.0;
  23. normal = ( accum * (1.0 - normal.a)) + (normal * normal.a);
  24. gl_FragColor = v_fragmentColor * normal;
  25. }

八、noise:噪声点

GIF.gif
C++

  1. auto noiseShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert,
  2. FileUtils::getInstance()->getStringFromFile(
  3. FileUtils::getInstance()->fullPathForFilename( "Shaders/example_Noisy.fsh" ) ) );
  4. auto programState = noiseShader->getGLProgramState();
  5. noiseShader->drawCallOnSprite = [noiseShader, programState](
  6. cocos2d::Sprite * target,
  7. cocos2d::Renderer * render,
  8. const cocos2d::Mat4 & transform,
  9. std::uint32_t flags,
  10. float globalZOrder,
  11. cocos2d::Texture2D * texture,
  12. cocos2d::BlendFunc & blendFunc,
  13. cocos2d::V3F_C4B_T2F_Quad * quad,
  14. cocos2d::TrianglesCommand::Triangles * triangles )
  15. {
  16. noiseShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );
  17. render->addCommand( &noiseShader->quadCommand );
  18. };
  19. noiseShader->setUniformsAndAttribs = [ = ]
  20. {
  21. auto s = shaderSprite->getTexture()->getContentSizeInPixels();
  22. programState->setUniformVec2( "resolution", Vec2( s.width, s.height ) );
  23. }

顶点着色器

  1. ccPositionTextureColor_noMVP_vert

片段着色器

  1. // Shader taken from: http://webglsamples.googlecode.com/hg/electricflower/electricflower.html
  2. #ifdef GL_ES
  3. precision mediump float;
  4. #endif
  5. varying vec4 v_fragmentColor;
  6. varying vec2 v_texCoord;
  7. uniform vec2 resolution;
  8. const float intensity = 0.05;
  9. vec3 noise(vec2 uv)
  10. {
  11. vec2 p = abs(sin(uv * 13.0 + uv.x * CC_Time[1] * sin(uv.y)));
  12. 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))));
  13. }
  14. void main(void)
  15. {
  16. gl_FragColor.xyz = intensity * noise(gl_FragCoord.xy / sin(resolution.xy * CC_Time[1] * 0.01)) + (1. - intensity) *
  17. texture2D(CC_Texture0,v_texCoord.xy).xyz;
  18. gl_FragColor.w = 1.;
  19. }

九、边缘检测

image.png
C++

  1. auto edgeDetectShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert,
  2. FileUtils::getInstance()->getStringFromFile(
  3. FileUtils::getInstance()->fullPathForFilename( "Shaders/example_EdgeDetection.fsh" ) ) );
  4. auto programState = edgeDetectShader->getGLProgramState();
  5. edgeDetectShader->drawCallOnSprite = [edgeDetectShader, programState](
  6. cocos2d::Sprite * target,
  7. cocos2d::Renderer * render,
  8. const cocos2d::Mat4 & transform,
  9. std::uint32_t flags,
  10. float globalZOrder,
  11. cocos2d::Texture2D * texture,
  12. cocos2d::BlendFunc & blendFunc,
  13. cocos2d::V3F_C4B_T2F_Quad * quad,
  14. cocos2d::TrianglesCommand::Triangles * triangles )
  15. {
  16. edgeDetectShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );
  17. render->addCommand( &edgeDetectShader->quadCommand );
  18. };
  19. noiseShader->setUniformsAndAttribs = [ = ]
  20. {
  21. auto s = shaderSprite->getTexture()->getContentSizeInPixels();
  22. programState->setUniformVec2( "resolution", Vec2( s.width, s.height ) );
  23. };

顶点着色器

  1. ccPositionTextureColor_noMVP_vert

片段着色器

  1. #ifdef GL_ES
  2. precision mediump float;
  3. #endif
  4. varying vec4 v_fragmentColor;
  5. varying vec2 v_texCoord;
  6. uniform vec2 resolution;
  7. float lookup(vec2 p, float dx, float dy)
  8. {
  9. vec2 uv = p.xy + vec2(dx , dy ) / resolution.xy;
  10. vec4 c = texture2D(CC_Texture0, uv.xy);
  11. return 0.2126*c.r + 0.7152*c.g + 0.0722*c.b;
  12. }
  13. void main(void)
  14. {
  15. vec2 p = v_texCoord.xy;
  16. // simple sobel edge detection
  17. float gx = 0.0;
  18. gx += -1.0 * lookup(p, -1.0, -1.0);
  19. gx += -2.0 * lookup(p, -1.0, 0.0);
  20. gx += -1.0 * lookup(p, -1.0, 1.0);
  21. gx += 1.0 * lookup(p, 1.0, -1.0);
  22. gx += 2.0 * lookup(p, 1.0, 0.0);
  23. gx += 1.0 * lookup(p, 1.0, 1.0);
  24. float gy = 0.0;
  25. gy += -1.0 * lookup(p, -1.0, -1.0);
  26. gy += -2.0 * lookup(p, 0.0, -1.0);
  27. gy += -1.0 * lookup(p, 1.0, -1.0);
  28. gy += 1.0 * lookup(p, -1.0, 1.0);
  29. gy += 2.0 * lookup(p, 0.0, 1.0);
  30. gy += 1.0 * lookup(p, 1.0, 1.0);
  31. float g = gx*gx + gy*gy;
  32. gl_FragColor.xyz = vec3(1.-g);
  33. gl_FragColor.w = 1.;
  34. }

十、GrayScale:灰度图

image.png
C++

  1. auto grayScaleShader = Shader::createWithSrc( ccPositionTextureColor_noMVP_vert,
  2. FileUtils::getInstance()->getStringFromFile(
  3. FileUtils::getInstance()->fullPathForFilename( "Shaders/example_GreyScale.fsh" ) ) );
  4. auto programState = grayScaleShader->getGLProgramState();
  5. grayScaleShader->drawCallOnSprite = [grayScaleShader, programState](
  6. cocos2d::Sprite * target,
  7. cocos2d::Renderer * render,
  8. const cocos2d::Mat4 & transform,
  9. std::uint32_t flags,
  10. float globalZOrder,
  11. cocos2d::Texture2D * texture,
  12. cocos2d::BlendFunc & blendFunc,
  13. cocos2d::V3F_C4B_T2F_Quad * quad,
  14. cocos2d::TrianglesCommand::Triangles * triangles )
  15. {
  16. grayScaleShader->quadCommand.init( globalZOrder, texture->getName(), programState, blendFunc, quad, 1, transform, flags );
  17. render->addCommand( &grayScaleShader->quadCommand );
  18. };
  19. grayScaleShader->setUniformsAndAttribs = [ = ]
  20. {
  21. auto s = shaderSprite->getTexture()->getContentSizeInPixels();
  22. programState->setUniformVec2( "resolution", Vec2( s.width, s.height ) );
  23. };

顶点着色器

  1. ccPositionTextureColor_noMVP_vert

片段着色器

  1. #ifdef GL_ES
  2. precision mediump float;
  3. #endif
  4. varying vec4 v_fragmentColor;
  5. varying vec2 v_texCoord;
  6. void main(void)
  7. {
  8. vec4 c = texture2D(CC_Texture0, v_texCoord);
  9. gl_FragColor.xyz = vec3(0.2126*c.r + 0.7152*c.g + 0.0722*c.b);
  10. gl_FragColor.w = c.w;
  11. }

十一、Glare Lens Flare

image.png