Frustrating transparency issues

Hi,

I’m having some frustrating issues with transparency. I’m creating some grass that basically consist of a lot of faces with a partially-transparent texture on it.
Here’s how it looks: (click to enlarge)

Looks good so far. The problem occurs when I clear model nodes and then call flattenStrong. (I need that because otherwise the number of meshes becomes too much)
The alpha is set to MAlpha, MBinary and MDual, respectively. Click to enlarge.

Any ideas how I can merge the grass planes into one mesh but still keep correct transparency sorting? MBinary is the only setting that looks correct but unfortunately it doesn’t seem to respect 0.0 < alpha < 1.0 values.

Clearly, once you have flattened the nodes into one mesh, alpha sorting is no longer possible (because correct alpha sorting would now require breaking apart the mesh and re-sorting it internally according to the viewing direction, completely defeating the advantage of flattening it in the first place).

So, you need a transparency mode that doesn’t require sorting at all to give correct results. MBinary is one such mode, but as you have observed, it doesn’t respect grayscale alpha values, so it looks pixelly.

You could also try MMultisample. This requires “framebuffer-multisample 1” and “multisamples 2” (or better). I haven’t tried it in a long time, so I’m not 100% sure it still works.

David

I did try MMultisample and MMultisampleMask, but they give exactly the same result as MBinary, with and without the config variables you suggested.
It appears to be broken or so. Multisample antialiasing doesn’t work either.
Any ideas where I should start debugging, or is there maybe a better idea to do sorting in my case?

Hmm, MMultisample does work for me on my Windows box, but not on my Linux box. It looks like I’m not getting any multisamples on my Linux box, regardless of the setting of framebuffer-multisample. (Check base.win.getFbProperties() to see if you get any either.)

This might be a bug in glxdisplay window creation, or it might just mean that my Linux hardware doesn’t support multisamples. I’ll look a little closer later today.

David

Nope, printing the fb properties turns out that it didn’t give me any multisamples.

In case it helps any, this does give me multisamples:

from pandac.PandaModules import *
loadPrcFileData("", "window-type none")
from direct.directbase import DirectStart
base.makeDefaultPipe()
winprops = WindowProperties.size(512, 512)
props = FrameBufferProperties()
props.setMultisamples(1)
a=base.graphicsEngine.makeOutput(base.pipe, "window", 0, props, winprops, GraphicsPipe.BFRequireWindow)
print a.getType(), a.getFbProperties()
run()

It prints:

glxGraphicsWindow depth_bits=24 color_bits=24 accum_bits=64 multisamples=2 indexed_color=1 force_hardware=1

However, when I call props.setRgbColor(1) as well, suddenly makeOutput returns None.

I’ve just checked in some additional debugging output to glxdisplay. Now, when you have “notify-level-display debug” enabled, when you open a window it prints a list of the available frame buffer configs. For instance, on my silly little GeForce 5200, I get this:

:display:glxdisplay(debug): 11: depth_bits=24 color_bits=24 accum_bits=64 force_hardware=1 force_software=1  (pbuffer) (pixmap) (slow)
:display:glxdisplay(debug): 12: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 force_hardware=1 force_software=1  (pbuffer) (pixmap) (slow)
:display:glxdisplay(debug): 13: depth_bits=24 color_bits=24 accum_bits=64 force_hardware=1 force_software=1  (pbuffer) (pixmap) (slow)
:display:glxdisplay(debug): 14: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 force_hardware=1 force_software=1  (pbuffer) (pixmap) (slow)
:display:glxdisplay(debug): 15: depth_bits=24 color_bits=24 stencil_bits=8 accum_bits=64 force_hardware=1 force_software=1  (pbuffer) (pixmap) (slow)
:display:glxdisplay(debug): 16: depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 accum_bits=64 force_hardware=1 force_software=1  (pbuffer) (pixmap) (slow)

And so on. (Further down the list, it starts to indentify the configs that have multisamples.)

Interestingly, every single one of my available framebuffer configs is tagged “(slow)”, which isn’t precisely defined in the glx spec, but is supposed to mean there’s something slower about this config than the other configs. The Panda configurator is designed to filter out the (slow) configs, unless all of them are tagged (slow). My suspicion is that on your system, the multisample configs happen to be tagged (slow), and the non-multisample configs are not, so that it ends up filtering out all the multisample configs.

Can you confirm this suspicion?

David

Yes, I can confirm this on my GeForce 8600M (laptop):

$ pview 2>&1 | grep multisample | sed 's/:display:glxdisplay(debug): //g'
68: depth_bits=24 color_bits=24 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
69: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
70: depth_bits=24 color_bits=24 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
71: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
72: depth_bits=24 color_bits=24 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
73: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
74: depth_bits=24 color_bits=24 stencil_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
75: depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
76: depth_bits=24 color_bits=24 stencil_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
77: depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
78: depth_bits=24 color_bits=24 stencil_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
79: depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 accum_bits=64 multisamples=2 force_hardware=1 force_software=1  (pbuffer) (slow)
80: depth_bits=24 color_bits=24 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
81: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
82: depth_bits=24 color_bits=24 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
83: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
84: depth_bits=24 color_bits=24 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
85: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
86: depth_bits=24 color_bits=24 stencil_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
87: depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
88: depth_bits=24 color_bits=24 stencil_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
89: depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
90: depth_bits=24 color_bits=24 stencil_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
91: depth_bits=24 color_bits=24 alpha_bits=8 stencil_bits=8 accum_bits=64 multisamples=4 force_hardware=1 force_software=1  (pbuffer) (slow)
92: depth_bits=24 color_bits=24 accum_bits=64 multisamples=2 back_buffers=1 force_hardware=1 force_software=1  (pbuffer) (slow)
93: depth_bits=24 color_bits=24 alpha_bits=8 accum_bits=64 multisamples=2 back_buffers=1 force_hardware=1 force_software=1  (pbuffer) (slow)

Looks like there’s either a bug in the code that detects whether it’s ‘slow’ or not, or, we’d have to make the code still accept ‘slow’ framebuffer modes (if no ‘fast’ mode can be found to satisfy the user’s request)
(We could maybe create a config var for that, something like allow-slow-configs)

EDIT: Yay! If I change this line in glxGraphicsStateGuardian.cxx:

slow = true;

and replace ‘true’ with ‘false’, I can see sweet antialiasing and the transparency works, too! :slight_smile:

Ah, turns out there was a bug in that logic. It was assuming that GLX_SLOW_CONFIG was a bitmask, but it’s not, it’s a discrete value. Treating as a bitmask gives a false positive.

I’ve just checked in the fix, and now none of my framebuffer configs are tagged “(slow)”.

David

Any chance of screenshots to see the difference?

@drwr: I’ve tested it and it works now indeed. :slight_smile: Thanks alot!

@radioact1ve: here’s a screenshot, click to enlarge:

This was with just 4 multisamples, since my card doesn’t support more than that.

Hmm, it suddenly doesn’t seem to work anymore. Debug output does print the right modes, without (slow), but I’m getting “FrameBufferProperties available less than requested.” even if I just request 2 multisamples and nothing more.

Strange. Can you show me the debug output? And also in python, can you print:

FrameBufferProperties.getDefault(); base.win.getFbProperties()

I’d like to see if it’s apparent why it’s selecting a given configuration.

David

Wait, there’s something VERY odd going on.
When I run it with ‘notify-level-display debug’, I do get multisamples:
pastebin.ubuntu.com/132109/
When I run it at ‘info’, I don’t get multisamples:
pastebin.ubuntu.com/132114/

This is the used code:

from pandac.PandaModules import *
loadPrcFileData("","framebuffer-multisample 1")
loadPrcFileData("","multisamples 2")
loadPrcFileData("","notify-level-display debug")
from direct.directbase import DirectStart
print "Default:", FrameBufferProperties.getDefault()
print base.win.getType(), base.win.getFbProperties()
run()

Hmm, yet it’s working for me. This might just mean that there is a problem somewhere with an uninitialized variable or something along those lines, so that randomly shaking the box (by running with different debug settings, for instance) might be enough to change whether the coin falls heads-up or tails-up.

Oh, I just saw the links. I’ll see if I can figure out anything from your logs.

David

Hmm, I don’t see anything obviously wrong. Would you mind putting a cerr statement in glxGraphicsStateGuardian.cxx, choose_pixel_format() function, to show the quality value it computes for each fbconfig? It’s supposed to choose the fbconfig with the highest quality value, and if you see it reporting a different set of quality values with debug output enabled, then the particular values it’s reporting in each case will be a clue as to exactly where it’s going wrong.

David

Ha. This:

      cerr << fbprops << " - Q: " << quality << "\n";

actually makes it print out correct quality values (and it works then).
But this:

      cerr << " - Q: " << quality << "\n";

always prints out 0.

Wow, that’s delicious. Compiler bug? It’s been a long time since I’ve run across a good compiler bug, but this one is starting to smell like one. What is your output for “gcc -v”? I get:

gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC)

Usually compiler bugs are triggered by weird once-in-a-blue-moon combinations of variable and loop optimizations. Working around them means changing things up just enough to not trigger the bug any more. Try declaring the quality variable “atomic”, or even “static”, and/or scoping it outside of the loop, or changing its type to a long long, or things along these lines.

David

$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu12' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)

I’ve tried renaming, moving it out of the loop, making it a “double” or so, casting it to three different types first, declaring static, but to no avail.
This is even weirder: redefining it doesn’t even give a warning in the compiler. (Though I’m certain HAVE_GLXFBCONFIG is defined.)

Darn it, I just hope this won’t delay 1.6.0 too much. If you want, I can set up an ssh sandbox on my machine so you can access it while I’m asleep.
Or maybe we can find a workaround by moving some stuff around (or even outputting the fb_props to a stringstream and then do nothing with it).

My full gcc -v output:

Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-cpu=generic --build=i386-redhat-linux
Thread model: posix
gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC) 

Maybe this is a bug related to the i64 version of gcc only; that’s plausible.

What if you take out the is_debug() check, and always write the fbprops to glxdisplay_cat.debug()? That results in the same effort of formatting the fbprops for output and so on, but it gets dropped on the floor at the end of the output.

David