Closed GoogleCodeExporter closed 9 years ago
Two more screenshots from other rendering backends. If you zoom in, you can see
the distortion in the ANGLE version.
Original comment by kevin.g...@gmail.com
on 17 Jun 2012 at 9:32
Attachments:
Possibly related to some other reports by the MapsGL team about blurred text
rendering on some hardware.
Original comment by kbr@chromium.org
on 17 Jun 2012 at 10:42
This could be caused by not sampling at texel centers. ANGLE uses a different
rounding for texture coordinates (which is completely within spec). The
solution is to add (0.5 / <texture width>, 0.5 / <texture height>) to your
texture coordinates. Does that fix the issue?
Original comment by nicolas....@gmail.com
on 18 Jun 2012 at 1:02
Unfortunately it does not.
I have another demo that tries to do pixel-perfect rendering and renders
EXTREMELY broken on this machine under WebGL. I spent two days or so on and off
experimenting with various texture coordinate biases, sampling parameters, etc
to try and get correct rendering and no reasonable combination I could think of
worked.
Off the top of my head, I remember trying:
Offsetting all pixel coordinates by a certain number of texels (0.1, 0.5, 1.0,
-0.1, -0.5, -1.0)
Offsetting the total dimensions of the texture rectangle by a certain number of
texels (-1, -2, +1, +2, +0.5, -0.5)
All of those just made the problem worse - for example, offsetting the
coordinates gave me the texel bleeding on the edges of quads that I would
expect of my texel coordinates were wrong.
As you can see, the bleeding in this demo only occurs in one pixel of each quad
(in the corner) and the pixel bleeding in is from an adjacent texel. This is
similar to how only a few pixels of the text quads in my text rendering are
mangled - it's not consistently off by some quantity of texels, and it's not
blurry as it would be if I were sampling at the wrong texel coordinates.
Original comment by kevin.g...@gmail.com
on 18 Jun 2012 at 1:17
Attachments:
Is mipmapping and multi-sampling enabled? ANGLE uses centroid sampling on some
hardware, which can cause pixels near edges or corners of triangles to use a
different mipmap level. It might be causing more harm than good so we're
looking into disabling this feature.
Original comment by nicolas....@gmail.com
on 18 Jun 2012 at 1:28
[deleted comment]
For reference, here is the setup code from the library I use (webgl-2d) that
sets texture states:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
// Enable Mip mapping on power-of-2 textures
if (isPOT(image.width) && isPOT(image.height)) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.generateMipmap(gl.TEXTURE_2D);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
Since I think these textures are all power of two, that means it's using
LINEAR_MIPMAP_LINEAR. I kind of want mip-mapping here, so that scaling bitmaps
down looks good.
I don't think it's doing anything else to enable multisampling, but I'm not
sure if it defaults to on - I think it does in modern versions of chrome and
firefox?
Original comment by kevin.g...@gmail.com
on 18 Jun 2012 at 1:31
Indeed multisampling is on by default, and since you're using mipmapping as
well I'll check whether the centroid sampling is causing the stray pixels...
Original comment by nicolas....@gmail.com
on 18 Jun 2012 at 1:42
Aha, if I do:
var contextParameters = {
antialias: false,
};
and then pass that as the second parameter to getContext (when was the second
parameter added? I had no idea it existed, or that the default was antialiasing
on...), then these artifacts go away.
Original comment by kevin.g...@gmail.com
on 18 Jun 2012 at 1:42
I've just confirmed that forcing centroid sampling off makes the issue go away.
Thanks for testing with antialiasing off. That further confirms the cause.
Since centroid sampling is supposed to be a useful feature I'll check whether
the right solution is to turn antialiasing off or whether centroid sampling
should be disabled (perhaps only in certain cases)...
Original comment by nicolas....@gmail.com
on 18 Jun 2012 at 1:55
FYI, I've updated my version of webgl-2d to disable antialiasing, so if you
need to reproduce this issue, let me know and I can change it back.
Original comment by kevin.g...@gmail.com
on 18 Jun 2012 at 2:06
Unfortunately disabling centroid sampling might not be straightforward. It
depends on the use of COLOR and TEXCOORD semantics for varyings in the
translated HLSL shader. We use COLOR, which enables centroid sampling, because
for point sprites it ensures that the varying values for the single vertex are
replicated for each fragment. TEXCOORD causes the coordinates to range from 0
to 1 for point sprite rendering (which we use to implement gl_PointCoord).
That said, the OpenGL ES 2.0 specification section 4.3.5 on varyings states
that: "If single-sampling, the interpolated value is for the fragment center.
If multi-sampling, the interpolated value can be anywhere within the pixel,
including the fragment center or one of the fragment samples."
So using centroid sampling is clearly within spec. It may just surprise people
to see a difference between WebGL using desktop OpenGL versus ANGLE. Part of
the problem is that WebGL defaults to enabling anti-aliasing.
Even if we only use COLOR semantics when rendering point sprites, so every
other primitive doesn't use centroid sampling, point sprites can still cause
unexpected results. Plus it's actually a big complication to use different
shaders depending on the primitive type. The other alternative would be to
render point sprites as quads, but this is also quite complex and could have
performance implications.
Original comment by nicolas....@gmail.com
on 18 Jun 2012 at 3:43
I think leaving centroid sampling on would be fine, provided there's a way to
work around the texture sampling artifacts when rendering 2D quads with
antialiasing enabled. Is there such a workaround? If it exists, documenting it
is probably enough - I was unable to find a workaround that was adequate, but I
hadn't considered the mip-mapping component.
Original comment by kevin.g...@gmail.com
on 18 Jun 2012 at 3:45
Yes this does look like artifacts we've seen on some machines using ANGLE. I
wrote these two variations on conformance tests that fail on the affected
machines:
http://www.billbaxter.com/samplertest/3.html (tests pixel precise rendering
with LINEAR filtering on)
http://www.billbaxter.com/samplertest/4.html (tests pixel precise rendering
with NEAREST and NPOT texture)
And also this mip-map with bias test also fails on that machine:
https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/tests/conforma
nce/glsl/samplers/glsl-function-texture2d-bias.html
(a green line from mip-level 1 appears along the seam between triangles which
should be rendered at mip level 0)
But these issues don't seem to affect all machines using ANGLE. I think we've
only seen it on ATI.
Original comment by wbax...@google.com
on 18 Jun 2012 at 4:43
... Note about the 3.html and 4.html tests above, currently they generate
output for every failed pixel so if your machine fails it horribly, it may
appear that the test just hangs.
Original comment by wbax...@google.com
on 18 Jun 2012 at 4:44
For my machine (GeForce GTX 670, latest drivers, W7, as mentioned above),
billbaxter test #3 and the khronos test both fail, but billbaxter #4 passes.
Original comment by kevin.g...@gmail.com
on 18 Jun 2012 at 4:45
That's what I've seen most commonly. NEAREST sampling is ok, but trying to do
LINEAR filtering with pixel precision fails. We've seen that on a ThinkPad
T400 with ATI Mobility Radeon HD 3400 Series, Windows 7.
But we have one machine, a ThinkPad X220 with Intel HD 3000 gpu running Windows
7, which fails test #4 as well (with every test pixel coming out as some
combination of red and green).
Original comment by wbax...@google.com
on 18 Jun 2012 at 5:07
Original comment by kbr@chromium.org
on 19 Jun 2012 at 1:29
On my laptop with a GeForce GT 330M, only test #3 doesn't succeed. When I force
anti-aliasing off or when forcing centroid sampling off, it succeed.
The issue is that WebGL enables anti-aliasing by default, and there is a lot of
"freedom" in how devices/drivers implement it. As quoted above, the spec allows
the interpolated [varying] value to be anywhere in the pixel! And this can
obviously affect texture sampling.
ANGLE is, as far as I can tell, a compliant implementation. And centroid
sampling can actually avoid multi-sampling artifacts in some cases.
Original comment by nicolas....@gmail.com
on 19 Jun 2012 at 2:27
The conformance tests have been updated to always disable anti-aliasing.
But we've decided to still go ahead and try to disable centroid sampling in
ANGLE to prevent unexpected artifacts when anti-aliasing is desired (such as
with MapsGL). The only other alternative we could think of was to render text
with a single triangle large enough to cover the text's enclosing rectangle (so
no edges cross the text and hence centroid sampling doesn't affect it). But
that's obviously a significant application side complication.
I will look into the feasibility of rewriting the binary shader to use COLOR
semantics only when rendering point sprites...
Original comment by nicolas....@gmail.com
on 28 Jun 2012 at 3:11
Thanks for disabling the centroid sampling -- is there a bug to track for the
implementation of that change?
Also -- I'm not sure the definition of centroid sampling but it seems odd that
any sampling strategy would cause a the green from level 1 of the mip-chain to
be chosen when a quad is being rendered at 1:1 texel:pixel scale and 0 lod
bias. (I.e. the first test case here:
https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/tests/conforma
nce/glsl/samplers/glsl-function-texture2d-bias.html)
Does that, in fact, make sense when using centroid sampling?
This page:
http://msdn.microsoft.com/en-us/library/windows/desktop/cc627092(v=vs.85).aspx#C
entroid_Sampling
says "it is recommended that you do not combine derivatives and centroid
sampling", but mip level calculations are essentially texCoord derivative
calculations. Should the derivatives for calculating texture LOD perhaps be
calculated without using centroidal sampling in any case?
Original comment by wbax...@google.com
on 28 Jun 2012 at 5:15
I'll keep you updated on the progress here.
I think I found an even simpler way to fix (improve) this issue: Shaders used
for point rendering write to gl_PointCoord, and since we already detect this it
will be straightforward to select between COLOR/TEXCOORD semantics based on
that. I will test this shortly.
Indeed centroid sampling and derivatives don't mix well. But it's not possible
to separate the two because the derivatives simply compute the difference
between the same variable's value of neighboring pixels. And this can be any
variable; a varying, a value computed from a varying, a sampled texture color,
etc. Centroid sampling affects varying interpolation only. So everything
between the varying interpolation and derivative would have to be recomputed.
This might be possible with the latest hardware, but only when done explicitly
in the shader.
Anyway, simply ensuring that centroid sampling is not used fixes the
derivatives. It means we don't benefit from centroid sampling's advantages for
some cases, but it appears this is a desirable compromise.
Original comment by nicolas....@gmail.com
on 4 Jul 2012 at 1:29
Fixed in r1192.
Original comment by nicolas....@gmail.com
on 4 Jul 2012 at 8:15
Original issue reported on code.google.com by
kevin.g...@gmail.com
on 17 Jun 2012 at 9:31Attachments: