3D artifacts with Intel integrated GPUs
Closed this issue · 20 comments
Displaz doesn't seem to work well with intel graphics drivers on windows (+ possibly other platforms): points in the foreground go missing, and the depth testing is messed up with foreground points sometimes appearing behind background points.
The missing points can be made to come back by removing the use of gl_FragDepth
from the fragment shader. Not sure about the depth testing yet, it's mysterious.
@scottcarpenter FYI, I plan to stop brushing this one off ;-)
Ok, there's at least two separate things going on here:
- The Intel drivers are somehow unhappy about
glBlitFramebuffer()
, or about the format of the incremental framebuffer itself. It looks like depth testing is off for the incremental framebuffer. Disabling incremental rendering "fixes" this for small datasets. - The Intel driver seems to have a bug which causes the storage for
gl_FragDepth
andgl_PointSize
to alias each other or otherwise interfere somehow. Whatever it is, settinggl_FragDepth
causesgl_PointSize
to be corrupted. Example shader:
#version 130
// Copyright 2015, Christopher J. Foster and the other displaz contributors.
// Use of this code is governed by the BSD-style license found in LICENSE.txt
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelViewProjectionMatrix;
//------------------------------------------------------------------------------
#if defined(VERTEX_SHADER)
uniform float pointRadius = 0.1; //# uiname=Point Radius; min=0.001; max=10
// Point size multiplier to get from a width in projected coordinates to the
// number of pixels across as required for gl_PointSize
uniform float pointPixelScale = 0;
in vec3 position;
void main()
{
vec4 p = modelViewProjectionMatrix * vec4(position,1.0);
float pointScreenSize = clamp(2*pointPixelScale*pointRadius / p.w, 0, 400);
gl_PointSize = pointScreenSize;
gl_Position = p;
}
//------------------------------------------------------------------------------
#elif defined(FRAGMENT_SHADER)
out vec4 fragColor;
void main()
{
gl_FragDepth = gl_FragCoord.z;
fragColor = vec4(vec3(gl_PointCoord.y), 1);
}
#endif
Confrming the same visual artifacts on Intel(R) HD Graphics 3000, driver 9.17.10.3190, Windows 7 Service Pack 1(6.1.7601).
Have you every encountered the gl_PointSize/gl_FragDepth conflict? It's a bizarre one, and I couldn't find any reference to it online. Basically, the line
gl_FragDepth = glFragCoord.z;
Should be a noop, but it causes the fragColor to be set to something completely different.
Yeah, seems like a driver bug, on the face of it. It probably won't hurt to log the GLSL compiler output, to see if there are any breadcrumbs there. (ShaderProgram::setShader)
Nope, no joy from the GLSL logs. Oh well, it was worth checking.
cheers, thanks for looking. My only thought is to disable gl_FragDepth on intel using some #ifdef
s. It's not too much of a loss (other than making the shader ugly). I probably should figure out how to report it to intel too.
I guess the framebuffer issue is probably my bug (or qt's)
Bingo! I added some checking for QGLFramebufferObject, to check that the requested QGLFramebufferObjectFormat depth buffer was successfully attached. Alas, QGLFramebufferObject.attachment() == QGLFramebufferObject::NoAttachment
So it it reasonable to disable incremental rendering if FBO depth attachment isn't available?
- Nigel
I guess we could just render the first frame - people won't see all the points; I guess that's too bad.
Better though - figure out why the attachment fails, and whether it can be worked around.
Maybe QGLFramebufferObject
isn't doing some necessary incantation required for Intel - it could be abandoned, or maybe qt5 has fixed it.
Is this resolved?
There's still the need to disable the use of gl_FragDepth
for intel cards, or figure out a workaround.
I tried some shader fiddling and I couldn't get gl_FragDepth
and gl_PointSize
to work together, so that will be a bug report to intel I guess, and just disable the use of gl_FragDepth
for now on Intel + windows drivers.
Can you describe the visual manifestation of that issue? My impression was that the FBO workaround fixed that too, but perhaps I was only noticing the depth buffering problem.
It's definitely a distinct issue from the FBO problem. Visually, the points are not rounded in the foreground with the default shader, and all the low intensity points disappear when you zoom in. The oddness seems to boil down to the shader which I pasted in above: setting gl_FragDepth
seems to mangle the value of gl_PointCoord
so that values calculated from it come out wrong. One of those values is used to discard
fragments, which results in the wrong fragments getting discarded.
My test box has Intel HD graphics 4600. It looks like I have an old version of the driver since the official Lenovo version of the intel driver is old. I'll try installing the generic version from Intel to see whether that fixes things.
I don't think I've seen those artifacts on this Lenovo E430 with Intel HD 3000 GPU. I'd suggest installing the latest Intel GPU driver, as a next step.
I've installed what seems to be the latest driver (reported as 10.18.14.4222), but that doesn't help things. Must be hardware-dependent. Fun times :-/