Skip to content

Instantly share code, notes, and snippets.

@stevetranby
Last active September 20, 2021 03:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevetranby/95231e6122aaf97179b3 to your computer and use it in GitHub Desktop.
Save stevetranby/95231e6122aaf97179b3 to your computer and use it in GitHub Desktop.
Converting the laser beam example on ShaderToy to cocos2d-x shaders.

Laser beam example from Shader Toy https://www.shadertoy.com/view/XtBXW3

Usage: laserbeam.cpp - put this code inside the init method of a new project within HelloWorld.cpp. laserbeam.vert - put this in PROJECT_ROOT/Resources/res/ laserbeam.frag - put this in PROJECT_ROOT/Resources/res/

using std::string;
// custom shader similar to alpha test, but with normals and lighting
string kShaderKey("laser_rainbow");
auto glCache = GLProgramCache::getInstance();
auto prog = glCache->getGLProgram(kShaderKey.c_str());
if(! prog)
{
prog = GLProgram::createWithFilenames("res/" + kShaderKey + ".vert",
"res/" + kShaderKey + ".frag");
glCache->addGLProgram(prog, kShaderKey);
}
// This is the display size of the quad where for the render beam (in pixels, not points)
Size texSize(400,80);
auto sprite = Sprite::create();//"res/laser_particle.png");
sprite->setPosition(Vec2(250,150));
//sprite->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
sprite->setTextureRect(Rect(0, 0, texSize.width, texSize.height));
sprite->setBlendFunc(BlendFunc::ADDITIVE);
//auto glprogram = GLProgram::createWithFilenames("water.vsh", "water.fsh");
auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(prog);
sprite->setGLProgramState(glprogramstate);
// note: iResolution is only "size of screen" because shadertoy applys to full view quad
auto scale_factor = Director::getInstance()->getContentScaleFactor();
Vec3 iResolution(texSize.width/(2.f / scale_factor),
texSize.height/(2.f / scale_factor),
scale_factor);
glprogramstate->setUniformVec3("iResolution", iResolution);
auto move = MoveBy::create(5.0f, Vec2(100,100));
auto seq = Sequence::create(move, move->reverse(), NULL);
sprite->runAction(RepeatForever::create(seq));
parent->addChild(sprite);
// frag
uniform vec3 iResolution;
varying vec2 v_texCoord;
varying float iGlobalTime;
vec3 Strand(in vec2 fragCoord, in vec3 color, in float hoffset, in float hscale, in float vscale, in float timescale)
{
float glow = 0.06 * iResolution.y;
float twopi = 6.28318530718;
float curve = 1.0 - abs(fragCoord.y - (sin(mod(fragCoord.x * hscale / 100.0 / iResolution.x * 1000.0 + iGlobalTime * timescale + hoffset, twopi)) * iResolution.y * 0.25 * vscale + iResolution.y / 2.0));
float i = clamp(curve, 0.0, 1.0);
i += clamp((glow + curve) / glow, 0.0, 1.0) * 0.4 ;
return i * color;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float timescale = 4.0;
vec3 c = vec3(0, 0, 0);
c += Strand(fragCoord, vec3(1.0, 0, 0), 0.7934 + 1.0 + sin(iGlobalTime) * 30.0, 1.0, 0.16, 10.0 * timescale);
c += Strand(fragCoord, vec3(0.0, 1.0, 0.0), 0.645 + 1.0 + sin(iGlobalTime) * 30.0, 1.5, 0.2, 10.3 * timescale);
c += Strand(fragCoord, vec3(0.0, 0.0, 1.0), 0.735 + 1.0 + sin(iGlobalTime) * 30.0, 1.3, 0.19, 8.0 * timescale);
c += Strand(fragCoord, vec3(1.0, 1.0, 0.0), 0.9245 + 1.0 + sin(iGlobalTime) * 30.0, 1.6, 0.14, 12.0 * timescale);
c += Strand(fragCoord, vec3(0.0, 1.0, 1.0), 0.7234 + 1.0 + sin(iGlobalTime) * 30.0, 1.9, 0.23, 14.0 * timescale);
c += Strand(fragCoord, vec3(1.0, 0.0, 1.0), 0.84525 + 1.0 + sin(iGlobalTime) * 30.0, 1.2, 0.18, 9.0 * timescale);
fragColor = vec4(c.r, c.g, c.b, 1.0);
}
void main(void)
{
vec2 fragCoord = v_texCoord;
mainImage(gl_FragColor.rgba, fragCoord); // gl_FragCoord.xy);
gl_FragColor += vec4(0.6,0,0,0.6);
}
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
varying float iGlobalTime;
void main()
{
// use CC_PMatrix not CC_MVPMatrix for 2D Sprites
gl_Position = CC_PMatrix * a_position;
v_texCoord = a_texCoord;
iGlobalTime = CC_Time[1];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment