2

I am trying to tile area with texture atlas and specific shaders but I get weird behavior on different devices.

Most of them (Samsung Galaxy Ace, Samsung Galaxy Gio etc) are ok, just bleeding occurs (hope I can fix it with half-pixel correction).

But Samsung Galaxy S3 gets next with distance:

Screenshots

(jumping from weaker to even worse distortion zone is also seemed, it happens exactly on regular atlas width or height passing)

  • OpenGL ES 2.0, Android SDK are used.
  • Atlas and texture part for tiling are both POT (1024 for atlas and 64 for texture part).
  • Texture filtering doesn't matter: tried both NEAREST and LINEAR
  • drawable-nodpi resources folder is used
  • mat4, vec2, vec4, sampler2D precisions change does nothing

What am I doing wrong? Is it possible to fix it?

Shaders:

Vertex:

    uniform mat4 u_viewmatrix;
    uniform mat4 u_modelmatrix;

    attribute vec4 a_position;

    varying vec2 v_texCoord;

    void main()
    {
        mat4 matrix = u_viewmatrix * u_modelmatrix;
        gl_Position = matrix * a_position;

        v_texCoord = a_position.xy;
    }

Fragment:

    precision highp float;

    uniform sampler2D u_texture;
    uniform float u_texpartx;
    uniform float u_texparty;
    uniform float u_texpartwidth;
    uniform float u_texpartheight;
    uniform float u_texwidth;
    uniform float u_texheight;
    varying vec2 v_texCoord;

    void main()
    {
        vec2 coord;

        coord.x = (u_texpartx + mod(v_texCoord.x, u_texpartwidth))/u_texwidth;
        coord.y = (u_texparty + mod(v_texCoord.y, u_texpartheight))/u_texheight;

        gl_FragColor = texture2D(u_texture, coord);
    }
genpfault
  • 51,148
  • 11
  • 85
  • 139
AskT
  • 66
  • 1
  • 2
  • 8

1 Answers1

1

Place your images in /assets, not in /res/drawable-nodpi. I place all my content in /assets and have no problems with scaled, optimized or distorted in any other way PNGs.

Related question: Android app loading images from /drawables-nodpi/ with scaling

You should check dimensions of your bitmap, however. If it is loaded with proper size then problem is not in scaled bitmap.

Also I'd recommend to update your shader - you should pass offsets to vertex shader and then pass final coordinates to fragment shader. They will interpolate correctly but you will have a whole lot less calculations in fragment shader (which possibly might affect precision on certain hardware, too).

Ultimately, you shouldn't make such calculations in shader at all - do this math in your Java code instead and just pass final coordinates for sampler into shader.

Community
  • 1
  • 1
keaukraine
  • 5,315
  • 29
  • 54
  • Unfortunately, migrating to _/assets_ did nothing too. Bitmap size is exactly 1024*1024. It is possible to tile every block separately, but would it be so efficiently as current fake-tiling tweak is? – AskT Feb 26 '14 at 10:28
  • 1
    OK then it might be caused by accumulated errors in calculations - you should pass ready calculated values into shader and see results. Have you tried using `highp` floats in vertex shader too? Or (the worst case) it is indeed bug of video driver. – keaukraine Feb 26 '14 at 13:02
  • I am afraid it is impossible to precalculate texture coordinates for fake-repeating outside the shader. Yep, highp in vertex shader is used now, but with no affect. Also, I found [this](http://stackoverflow.com/questions/8787483/repeated-textures-are-severely-distorted-shaking-when-rotating-camera) and [this](http://stackoverflow.com/questions/11370074/opengl-es-2-0-texture-distortion-on-large-geometry-gl-repeat?lq=1) questions, but i can't sort out the suggested solutions – AskT Feb 26 '14 at 23:19
  • 1
    If you do use large values for sampling textures with `sampler2D` together with `GL_REPEAT` textures then you should clamp these values somehow. I've encountered similar issue caused by lack of precision of samplers on Tegra2 GPU. – keaukraine Feb 27 '14 at 08:16
  • Seems like the same issue, the difference is my custom shader for atlas part repeating instead of GL_REPEAT parameter, but it's facing up the same precision problems on large floating values. I tried to reduce "unused" integer fake-repeats values part and started using negative values to make floats closer to 0 for vertices' texture coordinates values initialization and now large geometries are looking much better. @keaukraine, thank you for suggested ideas and good advice. – AskT Feb 27 '14 at 14:21