[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.):
And that is the way it appears like on Moto G, Oneplus One & some others:
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:
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:
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]