[SOLVED]RGBA pngs and setTransparency() - model is invisible

EDIT: Was caused by wrong material settings.

model = loader.loadModel('model')
model.reparentTo(render)
model.setTransparency(TransparencyAttrib.MAlpha, 1)

The thing is if my png has alpha, even if its not used, the model is invisible. I have some parts of the model where I need alpha, and some parts where I dont.

If I make a PNG with GIMP and add an alpha channel to it, the saved texture won’t cause the model to disappear. But in some cases, for example generating a PNG with PIL, the PNG file will cause this.

So yeah pretty confused. It seems like there are different kinds of png files that behave differently in Panda3d?
Anyone have any knowledge on this?

If your PNG has an alpha channel, and that alpha channel is zero (black), then when you enable transparency on the model the model will become invisible.

If you don’t want this to happen you should ensure that the alpha channel is one (white).

David

Im afraid Im reading the pixels from another source which i can’t change. I cant just ignore alpha channel because it is used sometimes.
So what can be done?

Maybe store the Texture into an PNMImage, modify it with setAlpha or something like that and write the PNMImage back.

Hmm, perhaps you can simply set the texture format to FRgb?

Hm, I cant find any info about “FRGB”, whats the F stand for?

The F stands for Format. Just use setFormat(Texture.FRgb).

Im not using PNMImage,

and is FRGB just plain RGB without A?

Hmm PNMImage is a class for modifing imagedata. Example:

        pnm = PNMImage()
        texture.store(pnm)
        pnm.removeAlpha()
        text.load(pnm)

But if the Texture format can be manipulated that easy stick with rdbs proposal.

I thought what rdb said was a function for PNMImage, not Texture. And Im not using PNMImage, thats what i meant.

texture.set.setFormat(Texture.FRgb)

gives very weird results as when I tried replacing the image channels.
Maybe if “FRGB” was explained Id have a better idea if its useful here.

FRgb is one of the many texture formats supported by Panda. This just defines how the bytes are arranged within the texture buffer. The F is just a prefix that stands for “format”, to differentiate these symbols from those for, say, wrap mode or filter type or whatever. Panda uses a similar convention for all of its enumerated types. The full set of available formats is listed in the source code in texture.h:

  enum Format {
    F_depth_stencil = 1,
    F_color_index,
    F_red,
    F_green,
    F_blue,
    F_alpha,
    F_rgb,     // any suitable RGB mode, whatever the hardware prefers

    // The following request a particular number of bits for the GSG's
    // internal_format (as stored in the framebuffer), but this
    // request is not related to the pixel storage within the Texture
    // object itself, which is always get_num_components() *
    // get_component_width().
    F_rgb5,    // 5 bits per R,G,B channel
    F_rgb8,    // 8 bits per R,G,B channel
    F_rgb12,   // 12 bits per R,G,B channel
    F_rgb332,  // 3 bits per R & G, 2 bits for B

    F_rgba,    // any suitable RGBA mode, whatever the hardware prefers

    // Again, the following bitdepth requests are only for the GSG;
    // within the Texture object itself, these are all equivalent.
    F_rgbm,    // as above, but only requires 1 bit for alpha (i.e. mask)
    F_rgba4,   // 4 bits per R,G,B,A channel
    F_rgba5,   // 5 bits per R,G,B channel, 1 bit alpha
    F_rgba8,   // 8 bits per R,G,B,A channel
    F_rgba12,  // 12 bits per R,G,B,A channel

    F_luminance,
    F_luminance_alpha,      // 8 bits luminance, 8 bits alpha
    F_luminance_alphamask,  // 8 bits luminance, only needs 1 bit of alpha

    F_rgba16,  // 16 bits per R,G,B,A channel
    F_rgba32,  // 32 bits per R,G,B,A channel

    F_depth_component,
    F_depth_component16,
    F_depth_component24,
    F_depth_component32,
  };

Unfortunately, format FRgb (or F_rgb as it appears in C++ code) implicitly means that there are only three components, not four, so if you set a four-channel image to FRgb you will indeed get weird results.

If you have a texture that contains an alpha channel with bad data (i.e. all black), and you don’t want this bad data to influence the rendering, then you have exactly two choices: (a) correct or remove the bad data, or (b) tell Panda to ignore it.

For (a), you can either correct the problem before it gets into Panda, which you say you can’t do; or you can save the image into an in-memory PNMImage, remove the alpha, and then load it back. This operation is too slow to do every frame, but you can do it every once in a while without too much trouble.

For (b), you have lots of options, but all of them involve disabling conventional transparency. If other parts of the same texture have good data in the alpha channel, then you will have to separate the parts of your model that reference the good data from the parts of your model that reference the bad data, and enable transparency only on the parts of the model that reference the good data.

David

Seems like all options are bad for either performance reasons or not knowing which texture actually needs alpha.

I might have everything wrong though, because all the images not appear in Panda, but appear correctly in image viewers.

Just in case, I have

nodepath.setTransparency(TransparencyAttrib.MDual, 1)

and

nodepath.setTwoSided(True)

on the generated node.

Image viewers don’t always respect the alpha channel, so that doesn’t mean anything. You can inspect the image with a program like GIMP to see what the alpha channel actually contains.

But, yeah, you do need to know whether you have real data in the alpha channel or you have junk. How could it be otherwise? Either you want Panda to respect the alpha channel, or you don’t. You can’t ask Panda to respect the alpha channel only when the alpha channel isn’t wrong.

David

Hm, I opened some in GIMP and it showed correctly in the editor, and the alpha channel appears white.
Then I assigned the image to a model in Blender and it appeared normal in OpenGL render mode, then exported to egg and and it appeared normal in Pview.

Guess the poblem is with me.
The difference is in my application the geometry which gets assigned the textures is created from scratch. But I have no idea why allowing transparency on the generated nodepath makes it invisible.

When you create the geometry from scratch, you wouldn’t happen to be adding a color column with a 0 alpha value, would you?

Is the geometry still invisible if you don’t apply the texture?

David

Im not adding any vertex color data, just

addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint)
addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CVector)
addColumn(InternalName.make('texcoord'), 2, Geom.NTFloat32, Geom.CTexcoord)

Without texture its visible, but its also visible with texture (but the alpha isn’t there), its only invisible when I do

nodepath.setTransparency(TransparencyAttrib.MDual, 1)

But is it visible if you have transparency enabled but textures disabled?

Perhaps you have a setColor or setColorScale somewhere with the alpha set to 0?

It sure does sound like your texture has a black alpha channel. Is it also invisible if you just use MAlpha or MBinary? You’re not using some exotic TextureStage settings?

What happens if you save the texture with something like:

texture.write('foo.png')

and then examine foo.png in GIMP?

David

Yeah, I did. Weird thing is it appears white in GIMP:

And yeah, other alpha modes are the same

Can you post a simple and complete sample program that demonstrates the problem?

David