Shader to DrawNode

Whats the most simpliest way to apply .fsh shader to the DrawNode?

1 Like
auto canvas = DrawNode::create();
canvas->drawDot(Vec2(150,150), 100, Color4F(1,1,0,.5f));
addChild(canvas);

// custom shader similar to alpha test, but with normals and lighting
std::string shaderName = "res/STHologramShader";
auto glCache = GLProgramCache::getInstance();
GLProgram* prog = glCache->getGLProgram(shaderName);
if(! prog)
{
    auto fs = FileUtils::getInstance();
    auto fragPath = fs->fullPathForFilename(shaderName + ".fsh");
    auto vertPath = fs->fullPathForFilename(shaderName + ".vsh");
    std::string fragmentSource = fs->getStringFromFile(fragPath);
    std::string vertexSource = fs->getStringFromFile(vertPath);
    auto fragB = fragmentSource.c_str();
    auto vertB = vertexSource.c_str();
    prog = GLProgram::createWithByteArrays(vertB,fragB);
    glCache->addGLProgram(prog, shaderName);
}
canvas->setGLProgram(prog);
prog->use();

HologramShader.fsh

#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
varying mediump vec2 v_screenY;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
varying float v_screenY;
#endif

void main()
{
    vec4 texColor = v_fragmentColor;// * step(0.0, 1.0 - length(v_texCoord));;
    if(texColor.a < 0.2)
        discard;

    if(mod(v_screenY + CC_SinTime[1], 0.005) > 0.0025)
        discard;

    gl_FragColor = vec4(texColor.xyz, 0.2);
}

Hologram.vsh

attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;

#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
varying mediump vec2 v_texCoord2;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
varying float v_screenY;
#endif

void main()
{
    float alpha = 1.0;
    if(CC_Random01[0] < 0.2)
        alpha = 0.0;

    float blueshade = 1.0;
    v_fragmentColor = vec4(0.0, 0.5 * blueshade, blueshade, alpha);
    v_texCoord = a_texCoord;
    gl_Position = CC_MVPMatrix * a_position;
    v_screenY = gl_Position.y;
}

Edit: There’s usually a way to not need discard by forcing alpha to zero (0) and setting blending and visit order correctly. Also, the c++ code is more verbose in order to prevent line wrapping (personal preference for my forum style code).

4 Likes

thanks, for your reply! I will try it!

Here prog get null. Why? I checked paths but it still doesnt work.

Did the shader file load into string work correctly? Have you checked that fragmentSource and fragB contain the expected string/characters?

yep, I did.

do logs show any shader compiler errors? what platform are you testing on?

I see some errors

cocos2d: ERROR: 0:41: ‘v_screenY’ : undeclared identifier

cocos2d: ERROR: Failed to compile vertex shader

Windows 8.1 Universal App.

You are missing the varying inside the #ifdef GL_ES, and also if you ever compile for non-ES you’re also missing or have an extra v_texCoord2 as a varying. Make sure your varyings exist and match across vertex and frag shader.

It work for me too; Thanks stevetranby;

btw, do you know how to add the “time” factor to the shader with update(float delta)?

There’s vec4 CC_Time as well as cos/sin version.

Link (like many other for cocos2dx site) is no longer acceptable.
Can someone provide not-dead link to all uniforms available in shader with cocos2dx ? Or provide a way where I can find it by myself?

I’ll fix that dead link. It actually isn’t dead. Nginx isn’t re-writing it. I’ll try and see why.

I’m using shader on DrawNode too, however, if i don’t have drawDot before , the shader won’t be apply. Why?

Link still dead.
Can you do something about it?