Home Game Development libgdx – Weird shader habits on completely different units

libgdx – Weird shader habits on completely different units

0
libgdx – Weird shader habits on completely different units

[ad_1]

I’m making an attempt to mix an extraordinary shader with a Single Distance Field shader (for fonts and scalable icons) into one shader program.
The concept is easy – if uv.x is lower than 1.0, it’s drawn as regular, and if greater than 1.0 then SDF is used (utilizing GL_REPEAT uv.x and uv.x + 1.0 look related)

Fragment shader code:

precision mediump float;
precision mediump int;

uniform sampler2D u_texture;
various vec4 v_color;
various vec2 v_texCoords;
uniform float u_smoothing;

void foremost() {
  // SDF
  float distance = texture2D(u_texture, v_texCoords).a;
  float alpha = smoothstep(0.5 - u_smoothing, 0.5 + u_smoothing, distance);
  vec4 sdfColor = vec4(v_color.rgb, alpha * v_color.a);

  // Regular
  vec4 regularColor = v_color * texture2D(u_texture, v_texCoords);

  // Making a selection
  gl_FragColor = combine(regularColor, sdfColor, step(1.0, v_texCoords.x));
}

It works and appears fantastic on desktop and most of fashionable Android units however not on Oneplus One, Xiaomi Redmi 4A and Moto G units.
This is the way it should appear like and the way it truly appears on desktops and lots of different units (Samsung S8, Xiaomi 3s, Pixel 2 and so forth.):
Normaly rendered

And that is the way it appears like on Moto G, Oneplus One & some others:
enter image description here

I attempted to discover a problematic perform, however with out success.
First I attempted to make use of the same old situation as a substitute of combine():

void foremost() {
  // ...

  // Making a selection
  // gl_FragColor = combine(regularColor, sdfColor, step(1.0, v_texCoords.x));
  if (v_texCoords.x < 1.0) {
    gl_FragColor = regularColor;
  } else {
    gl_FragColor = sdfColor;
  }
}

Nothing has modified – this shader works effectively on most units and remains to be dangerous on some others.
I made a decision that the issue lies within the calculation of sdfColor and altered fragment shader code a bit to verify:

void foremost() {
  // ...

  // Making a selection
  gl_FragColor = sdfColor;  // Always utilizing SDF
}

But this shader labored equally on all units, which signifies that sdfColor is calculated accurately. This subsequent screenshot was taken on Moto G:
enter image description here

Then I attempted to distinguish the areas of textures with completely different colours:

void foremost() {
  // ...

  // Making a selection
  if (v_texCoords.x < 1.0) {
    gl_FragColor = regularColor;
    gl_FragColor.r = 1.0;  // Full crimson channel for normal texture areas with out SDF (UV.x < 1.0)
  } else {
    gl_FragColor = sdfColor;
    gl_FragColor.r = 0.0;  // No crimson channel for SDF 
  }
}

On Moto G and different units it appears as anticipated:
enter image description here

It appears to me that utilizing combine() or situations implicitly adjustments one thing else.

Update 1:

Using completely different precision qualifier (highp / lowp) or fully eradicating it did not assist and made no visible adjustments.

This bug begins to seem on desktop (OpenGL) if I add #model 100. Changing it to #model 110 or greater returns regular rendering.

When #model 100 is used on Android (OpenGL ES 2.0) it renders as if there have been no #model qualifier in any respect (precisely the identical as described in my query – on Nexus 5x it appears good, on Moto G it would not).

Using #model 300 es on Android (OpenGL ES 3.0, appears like it’s supported Moto G third) with respective adjustments to the code (uniform, various, texture2D changed by in, out, texture) would not repair the issue (good on Nexus, dangerous on Moto).

Precision qualifier was not utilized in each circumstances. Looks like #model does no impact to this drawback on Android however makes it seem on desktop when set to 100 (is it OpenGL 1.0?…)

Update 2:

Writing v_texCoords.x to the separate float and utilizing it in combine() fixes this bug however just for desktop when #model 100 can also be used:

#model 100
uniform sampler2D u_texture;
various vec4 v_color;
various vec2 v_texCoords;
uniform float u_smoothing;

void foremost() {
  float x = v_texCoords.x; // Writing to the separate float

  // SDF
  float distance = texture2D(u_texture, v_texCoords).a;
  float alpha = smoothstep(0.5 - u_smoothing, 0.5 + u_smoothing, distance);
  vec4 sdfColor = vec4(v_color.rgb, alpha * v_color.a);

  // Regular
  vec4 regularColor = v_color * texture2D(u_texture, v_texCoords);

  // Making a selection
  gl_FragColor = combine(regularColor, sdfColor, step(1.0, x)); // Using x as a substitute of v_texCoords.x
}

It would not repair the issue on Moto G. Also once I transfer float x = v_texCoords.x; to the road proper earlier than gl_FragColor = ... the issue stays on desktop:

void foremost() {
  // SDF
  float distance = texture2D(u_texture, v_texCoords).a;
  float alpha = smoothstep(0.5 - u_smoothing, 0.5 + u_smoothing, distance);
  vec4 sdfColor = vec4(v_color.rgb, alpha * v_color.a);

  // Regular
  vec4 regularColor = v_color * texture2D(u_texture, v_texCoords);

  // Making a selection
  float x = v_texCoords.x; // Writing to the separate float, this time it would not repair the bug
  gl_FragColor = combine(regularColor, sdfColor, step(1.0, x)); // Using x as a substitute of v_texCoords.x
}

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here