Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Color issue with DirectX11 on specific target applications #1927

Closed
koemeet opened this issue Jul 5, 2018 · 5 comments
Closed

Color issue with DirectX11 on specific target applications #1927

koemeet opened this issue Jul 5, 2018 · 5 comments

Comments

@koemeet
Copy link

koemeet commented Jul 5, 2018

Version/Branch of Dear ImGui:
7b2662d

Back-end file/Renderer/OS:
Windows 10, version 1803

My Issue/Question:
On certain d3d11 targets, when I use ImGui, the colors seem to be a lot more light than they should be. Here an example of the issue I am trying to explain. I ran the same ImGui sample code on two different d3d11 targets (first row of squares is on an existing d3d11 application and the second row is on my own regular d3d11 test application):

Colors used (in order of the squares):
rgb(28, 30, 37) rgb(255, 0, 0) rgb(255, 0, 255) rgb(255, 0, 100) rgb(100, 0, 100)

afbeelding

As you can see the last application displays the colors as they should be. But the first d3d11 target seems to make the ending colors way more light than they are in reality. The DX11 setup of the failing application is likely rather complex and sets up certain stuff which likely conflicts with ImGui (maybe lightning etc.).

It is good to know that the first application is an already existing d3d11 program, which I hook into, to provide a GUI on top of this application. Likely this application calls some DX api in its render loop which makes ImGui behave in an unexpected way.

I have also attached a screenshot of the demo window on the failing d3d11 application to display the color bug in more detail.

Standalone, minimal, complete and verifiable example:

  // inside render loop ...
  ImGuiIO& io = ImGui::GetIO();
  io.DisplaySize = ImVec2(1920.f, 1080.f);

  ImGui_ImplDX11_NewFrame();
  ImGui::NewFrame();

  ImGui::Text("Hello, world!");

  ImGui::Render();
  ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

Screenshots/Video
This is how the demo window looks like on the failing d3d11 target (as you can see its way way to light than it should be):
afbeelding

@koemeet koemeet changed the title [Bug] Color issue on DirectX11 on [Bug] Color issue with DirectX11 on specific target applications Jul 5, 2018
@ocornut
Copy link
Owner

ocornut commented Jul 5, 2018

Hello,

Possibly the issues are related to sRGB vs Linear Blending and Gamma Correction.
You'll need to read #1724 and #578.

Possibly you may get away with undoing gamma correction by applying a powf(color, 1.0f/2.2f) to the pixel colors. Otherwise you may need to adjust the imgui style.

Or maybe you are rendering into a render target which the game itself is using as a texture with a post-process pass.

-Omar

@ocornut ocornut changed the title [Bug] Color issue with DirectX11 on specific target applications Color issue with DirectX11 on specific target applications Jul 5, 2018
@koemeet
Copy link
Author

koemeet commented Jul 5, 2018

Thank you! This information helps me a lot understanding what is going on.

I saw for directx9 its fixable by doing the following before rendering imgui:

device->SetRenderState(D3DRS_SRGBWRITEENABLE, false);

Is something like this also possible in dx11, so that I don't have to edit the pixel shader.

@koemeet
Copy link
Author

koemeet commented Jul 5, 2018

I was able to fix it properly, by preparing my own render target view in the correct DXGI Format:

D3D11_RENDER_TARGET_VIEW_DESC desc = {};
memset(&desc, 0, sizeof(desc));
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // most important change!
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;

device->CreateRenderTargetView(render_target_texture, &desc, &render_target_view);

@Sewer56
Copy link

Sewer56 commented Nov 14, 2019

In the case of OpenGL:

// Disable and store SRGB state.
const bool srgbEnabled = glIsEnabled(GL_FRAMEBUFFER_SRGB);
glDisable(GL_FRAMEBUFFER_SRGB);

/* Insert Dear Imgui Render Code Here */

// Re-enable SRGB if necessary.
if (srgbEnabled)
    glEnable(GL_FRAMEBUFFER_SRGB);

@planetchili
Copy link

My quick fix that yielded acceptable results for me.

// gamma-correct style
const auto ToLinear = [](float x) {
  if (x <= 0.04045f)
  {
    return x / 12.92f;
  }
  else
  {
    return std::pow((x + 0.055f) / 1.055f, 2.4f);
  }
};
for (auto& c : std::span{ ImGui::GetStyle().Colors, size_t(ImGuiCol_COUNT) })
{
  c = { ToLinear(c.x), ToLinear(c.y), ToLinear(c.z), c.w };
}

Just do this after you initialize ImGui.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants