0
\$\begingroup\$

I managed to implement an infinite 2d texture scrolling using the following shader. btw I'm using cocos2d-x 2.2.1.

The vertex shader:

attribute vec4 a_position;
attribute vec2 a_texCoord;

#ifdef GL_ES
varying mediump vec2 v_texCoord;
#else
varying vec2 v_texCoord;
#endif

void main()
{
    gl_Position = CC_MVPMatrix * a_position;
    v_texCoord = a_texCoord;
}

The fragment shader:

#ifdef GL_ES
precision lowp float;
#endif

uniform vec2 u_time;
uniform vec4 u_color;
varying vec2 v_texCoord;
uniform sampler2D CC_Texture0;

void main()
{
        gl_FragColor = texture2D(CC_Texture0, v_texCoord + u_time);
}

But once I try to add some uniform color the texture is no more repeated correctly (and performance decreases drastically):

/// Texture not repeated correctly and performance degradation 
gl_FragColor = texture2D(CC_Texture0, v_texCoord + u_time) * u_color; 

However the following repeat the texture correctly (but of course there's no scrolling)

gl_FragColor =  texture2D(CC_Texture0, v_texCoord) * u_color; 

What am I doing wrong?

\$\endgroup\$
  • \$\begingroup\$ You should mark your answer as accepted. \$\endgroup\$ – HolyBlackCat Nov 29 '17 at 17:06
0
\$\begingroup\$

I solved the problem by updating the texture coordinate in the vertex shader.

attribute vec4 a_position;
attribute vec2 a_texCoord;

uniform vec2 u_time;

#ifdef GL_ES
varying mediump vec2 v_texCoord;
#else
varying vec2 v_texCoord;
#endif

void main()
{
    gl_Position = CC_MVPMatrix * a_position;
    v_texCoord = a_texCoord + u_time;
}

Although it ran correctly on Android, updating the texture coordinate in the fragment shader didn't work on iOS.

\$\endgroup\$
  • 3
    \$\begingroup\$ Make sure you mark this as accepted if you solved the problem. \$\endgroup\$ – Jesse Dorsey Dec 16 '14 at 19:07
  • 2
    \$\begingroup\$ And make sure you wrap-around u_time to the interval [0 .. 1) in your application code so it doesn't become too large. If you want to see an exaggerated example of why, initialize u_time with (15000000, 15000000) or even less than that, and start scrolling from there. The texture sampler and/or perspective correction units will start to display terrible rounding errors. \$\endgroup\$ – Stephane Hockenhull Oct 29 '17 at 22:12
0
\$\begingroup\$

The problem is probably:

precision lowp float;

Which causes u_time to be 8bit unsigned fixed points with a range of only 0 to 1 or -2 to 2.

setting it to mediump would probably fix the scrolling issue but would still degrade performance greatly.

uniform mediump vec2 u_time;
uniform lowp vec4 u_color;

It's better to calculate UV coordinates in the vertex shader anyway as calculating them in the pixel shader prevents texture prefetching at the interpolation stage and stalls the GPU while it waits for the texture data in the pixel shader.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.