-
-
Notifications
You must be signed in to change notification settings - Fork 11.2k
Description
TL;DR
When using OpenGL ES, the default Vertex Shader precision causes wobbly / skewed rendering on large displays.
This happens on master and docking branches, with the base example and a single change:
This line here:
const char* glsl_version = "#version 130"; |
changed to:
const char* glsl_version = "#version 300 es";
This now leads the backend to select a vertex shader that has mediump
precision:
imgui/backends/imgui_impl_opengl3.cpp
Line 628 in e3988a8
"precision mediump float;\n" |
With a highp
precision instead, the problem goes away. I don't believe having highp
on the vertex shader should cause significant problems. It's okay to keep the pixel shader in mediump.
Example of the demo window in this state:
Screenshots / explanation
On a 4k display, the absolute position values can grow quite large. When the drawing happens closer to (0, 0)
, the Vertex Shader's medium precision works fine, but the more the rendering goes towards the opposite end of the screen, the more the shader's vectors will lose precision, resulting in bad skewing of the sprites positions.
These screenshots / videos are taking with a simple demo code that draws a simple window with the coordinates, and a higher font, for readability. My setup is 3 monitors, one in 4k, and 2 in 1080p, so mixed DPI mode (which explains the resolution change in the screenshots / video). My graphics card is an RTX 3090.
if (ImGui::Begin("Skewing demo")) {
auto w = ImGui::GetCurrentWindow();
ImGui::Text("Location: (%.3f, %.3f)", w->Pos.x, w->Pos.y);
}
ImGui::End();
Here are various screenshots of this window in various locations:
Close to (0, 0), it looks fairly normal:
A bit further away, you can already see the i
in the title being squeezed, compared with the i
in the Location
:
And when farther away enough, the window is totally skewed:
Here's a video of me moving the window horizontally across my monitors (you can notice the monitor change during the resizing):
imgui-skew.mp4
Resolution / proposed solution
Obviously, selecting a different shader version passed to ImGui_ImplOpenGL3_Init
solves the issue. Passing nullptr
isn't really an option for software that have their own shaders for other non-imgui rendering, as some GPU OpenGL drivers don't like mixing multiple shader versions within the same context. This has the unfortunate consequence of forcing software using 300 es
as their shader version for portability to rework their code.
Changing the vertex shader to highp
in the ImGui OpenGL3 backend however seems like the better solution. I don't believe it'd have any huge performance impact to only change the vertex shader this way.