You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think I've just found that by using the same kind of fragment shader that is commonly used to display signed distance fonts (SDF), we can achieve anti-aliasing in unmodified Dear ImGui (almost) for free (at least on my NVIDIA card...)!
The main drawback, aside from an expected performance drop, is that we lose all the intermediate values between 0 and 1 in the alpha component of the bound textures (e.g. of the main font texture used by ImGui internally and of all user textures that are passed to ImGui::Image(...) and ImGui::ImageButton(...)).
However I'm not sure if ImGui is using these intermediate values or not.
User textures that contain alpha values inside the range (0,1) are the main problem: thay can't be displayed correctly with the SDF shader.
Code:
In "imgui/examples/opengl3_example/imgui_impl_glfw_gl3.cpp"
replace the main function of the fragment shader with the following:
"void main(void) {\n""vec4 texColor = texture2D(Texture, Frag_UV.st);\n""float width = fwidth(texColor.a);\n""float alpha = smoothstep(0.5 - width, 0.5 + width, texColor.a);\n""Out_Color = vec4(Frag_Color.rgb*texColor.rgb,Frag_Color.a*alpha);\n""}\n";
// Note that we could just comment out the 3rd line and calculate alpha trivially as://"float alpha = smoothstep(0.0, 1.0, texColor.a);\n" // to speed up things a bit,// but fwidth computes the derivates [abs (dFdx (p)) + abs (dFdy (p));] // and 'should' smooth things better, generating intermediate alpha values AFAIK. [We should test this]
It can easily be adapted for OpenGL version 2, OpenGLES, WebGL (and probably converted to Direct3D too).
P.S. Using the default, non-SDF shader together with a filter like GL_NEAREST we get a worse result (but without the texture alpha channel degradation problem).
These images have been taken using the embedded imgui font scaled at the maximum size allowed by: ImGui::GetIO().FontAllowUserScaling = true;
non-SDF shader + GL_NEAREST
SDF shader + GL_LINEAR
People from this issue #618 might be interested in this topic too.
The text was updated successfully, but these errors were encountered:
On a second thought I'm not sure that this hack is really useful 😒.
In fact the default setting of the opengl3_example
non-SDF shader + GL_LINEAR
does not look much worse than my "upgraded version"!
I still have to understand why in my projects scaled text looks way blurrier than in this demo... and my hack seemed to work better... 👎
[Edit:]
IN SHORT
An SDF-shader makes sense only if we can generate a SDF Font texture for ImGui.
GL_NEAREST seems to be a good solution (maybe with oversampling of 1:1, or at least squared).
If we need a shader (with GL_LINEAR filtering) to improve scaled fonts, a simple and fast alpha-sharpening shader (without derivatives) is often enough:
However all the shaders that modify the texture alpha value, slightly modify the appearance of the unscaled text too, and of all the textures with (alpha!=0.0 && alpha!=1.0). So additional care must be taken into account.
I think I've just found that by using the same kind of fragment shader that is commonly used to display signed distance fonts (SDF), we can achieve anti-aliasing in unmodified Dear ImGui (almost) for free (at least on my NVIDIA card...)!
The main drawback, aside from an expected performance drop, is that we lose all the intermediate values between 0 and 1 in the alpha component of the bound textures (e.g. of the main font texture used by ImGui internally and of all user textures that are passed to ImGui::Image(...) and ImGui::ImageButton(...)).
However I'm not sure if ImGui is using these intermediate values or not.
User textures that contain alpha values inside the range (0,1) are the main problem: thay can't be displayed correctly with the SDF shader.
Code:
In "imgui/examples/opengl3_example/imgui_impl_glfw_gl3.cpp"
replace the main function of the fragment shader with the following:
It can easily be adapted for OpenGL version 2, OpenGLES, WebGL (and probably converted to Direct3D too).
P.S. Using the default, non-SDF shader together with a filter like GL_NEAREST we get a worse result (but without the texture alpha channel degradation problem).
These images have been taken using the embedded imgui font scaled at the maximum size allowed by:
ImGui::GetIO().FontAllowUserScaling = true;
non-SDF shader + GL_NEAREST

SDF shader + GL_LINEAR

People from this issue #618 might be interested in this topic too.
The text was updated successfully, but these errors were encountered: