Can I use this shader on cocos2dx 4.0 also?
Converted old plasma (shadertoy.com)
What is to do?
Thanks for some hints.
Can I use this shader on cocos2dx 4.0 also?
Converted old plasma (shadertoy.com)
What is to do?
Thanks for some hints.
As far as I know cocos2dx dose do shaders but in what format it uses I not shore it doesn’t look too different from the javascript your looking at…
check the ShaderTest in Cocos Tests Dir maybe you can adapt it.
/cocos2dx-4.0/tests/cpp-tests/ShaderTest/
If you scroll down the comments on that page you linked, you’ll see a post with a simpler implementation of the shader:
void mainImage( out vec4 O, vec2 U )
{
float t = iTime/.1 + iMouse.x;
vec2 R = iResolution.xy, S = vec2(160,100),
p = ( U+U - R ) / R * S,
q = vec2(cos(-t / 165.), cos( t / 45.)) * S - p;
t = 1. + cos( length( vec2(cos( t / 98.), sin( t / 178.)) * S - p ) / 30.)
+ cos( length( vec2(sin(-t / 124.), cos( t / 104.)) * S - p ) / 20.)
+ sin( length(q) / 25. ) * sin(q.x / 20.) * sin(q.y / 15.);
O = .5 + .5* cos( (iTime+iMouse.y) / vec4(63,78,45,1) + ( t + vec4(0,1,-.5,0) ) *3.14 );
}
That’s easily adapted to Cocos2d-x v4 or the axmol fork (same code):
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform float u_time; // time in seconds
uniform vec2 u_resolution;
uniform vec2 u_position;
const float MATH_PI = float(3.14159265359);
void main()
{
float t = u_time / .1 + u_position.x;
vec2 R = u_resolution.xy, S = vec2(160,100),
p = (v_texCoord + v_texCoord - R) / R * S,
q = vec2(cos(-t / 165.), cos( t / 45.)) * S - p;
t = 1. + cos( length( vec2(cos( t / 98.), sin( t / 178.)) * S - p ) / 30.)
+ cos( length( vec2(sin(-t / 124.), cos( t / 104.)) * S - p ) / 20.)
+ sin( length(q) / 25. ) * sin(q.x / 20.) * sin(q.y / 15.);
gl_FragColor = .5 + .5 * cos((u_time + u_position.y) / vec4(63, 78, 45, 1) + ( t + vec4(0, 1, -.5, 0) ) * MATH_PI);
}
To use the shader, create the program first:
auto* program = Device::getInstance()->newProgram(positionTextureColor_vert, plasma_frag);
then get a programState from it:
_plasmaProgramState= new (std::nothrow) ProgramState(program);
Then set up the required uniforms:
_plasmaTimeLoc = _plasmaProgramState->getUniformLocation("u_time");
_plasmaResolutionLoc = _plasmaProgramState->getUniformLocation("u_resolution");
_plasmaPosLoc = _plasmaProgramState->getUniformLocation("u_position");
// Set initial values
auto time = 0.f;
_plasmaProgramState->setUniform(_plasmaTimeLoc, &time, sizeof(time));
auto resolution = Vec2(node->getContentSize()) / node->getContentSize().width;
_plasmaProgramState->setUniform(_plasmaResolutionLoc, &resolution, sizeof(resolution));
// It's equivalent to iMouse in the original shader. You can use touch coordinates if you want to get the
// same effect.
auto position = Vec2(node->getContentSize()) / 2;
_plasmaProgramState->setUniform(_plasmaPosLoc, &position, sizeof(position));
Then schedule an update to handle the time:
void update(float dt)
{
_timeInSeconds += dt;
_plasmaProgramState->setUniform(_plasmaTimeLoc, &_timeInSeconds, sizeof(_timeInSeconds));
}