Polygon hair render issue

Hi,

I am creating a nice multiplayer rpg. At the moment, I was testing hair on a character. It is a polygon hair with alpha texture. The problem is that it displays strangely. I have tried to play with the jme material settings, but none of which I tried seemed to work yet.

The hair looks like this: (Left: jme3, middle: blender render, right: blender gsls with backface culling enabled)

I checked that BlendMode is Alpha, QueueBucket is Transparent, set the CullHint.Never. I also tried the DepthWrite with true and false values but with no sufficient result.

Thanks for your help and support. :slight_smile:
PS: anyone knows if the jm3 textures, trees, etc are free to use in the end product?

Have you looked at the alpha cutoff?
Stuff gets clipped out if it’s “too transparent”, on the assumption that it shouldn’t matter; this could be one of the cases where the cutoff is too generous.
There might be more effects involved thougt, that “patchy” look doesn’t point right at alpha cutoff.

I had a similar effect once, where I played around with the material settings. And the reason was that there was some
“garbage” in the material file (I saw it when I display the source of the material). After I cleaned it up it worked like I
charm.

Dont know if you have the same issue…

@toolforger said: Have you looked at the alpha cutoff? Stuff gets clipped out if it's "too transparent", on the assumption that it shouldn't matter; this could be one of the cases where the cutoff is too generous. There might be more effects involved thougt, that "patchy" look doesn't point right at alpha cutoff.

Alpha cutoff is off by default and alphaThreshold is 0 by default. Edit: I do suppose it’s possible the blender loader started setting these by default but I haven’t seen that yet, personally.

It looks to me like the min filtering is just washing everything out. To the OP, you may have to mess with the material to turn off the min filter to see if that helps. It may produce other artifacts but it would help determine what is going on. I don’t know how to do it from a blender-loaded material, though. Not sure the SDK gives those options for textures when editing them in scene explorer.

pspeed, how do turn of a min filter of a material?

To add some info, in Blender, the hair mesh in blender has normals double sided(In the Object Data->Normals tab). Could this be the problem?

In the meantime, I have colored the hair texture for a better debug picture. At the moment it looks like this:
As it can be seen in the picture the yellow and pink hair with Opaque Bucket is rendered through head.
Also the cyan color is not present there at all. Well and the transparent bucket shows as little as possible.

In the SceneComposer under Geometry I found the material definition:

Material MyMaterial : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters {
DiffuseMap : Flip Repeat Models/long2_texture.png
AlphaMap : Flip Repeat Models/long2_texture.png
Minnaert : false
Specular : 1.0 1.0 1.0 0.0
Diffuse : 1.0 1.0 1.0 1.0
UseMaterialColors : true
ParallaxHeight : 0.05
Ambient : 0.0 0.0 0.0 0.0
Shininess : 20.0
WardIso : false
}
AdditionalRenderState {
FaceCull Off
Wireframe Off
DepthWrite On
PolyOffset 0.0 0.0
AlphaTestFalloff 0.0
Blend Alpha
PointSprite Off
ColorWrite On
DepthTest On
}
}

If your PNG already has alpha in it then take out the alphaMap reference… at best it’s not necessary and at worst it’s masking the wrong things.

thanks pspeed. That seems to solved half of the problem. Now the cyan hair shows too. I have managed to pinpoint out the other half:

For it I constructed a simple test case.

The 3 layer quad is one mesh. It is shown once from side up. And another one is shown from the opposite side. Now the one of right shows correctly. The one on left incorrectly. Basically what I need left is for the alpha to work correctly despite what angle I am looking at it.

Ahh, alpha discard will actually help you here.

Basically the plane on top is drawing first and filling the z buffer even when you drawing transparent pixels. The alpha discard threshold causes transparent pixels to be discard instead, so they are not put into the z buffer and then don’t block anything underneath from being drawn.

But… it will only get you part way there since the semi-transparent parts may still be strange looking.

Another approach is to turn off depth writing… which has its own separate consequences but it will look right for the hair. It means that if you have other transparent objects drawn after the hair that they won’t be properly z-sorted at the pixel level. But maybe that doesn’t come up (and there are harder solutions for that problem, also.)

Hmm, thanks guys. Alpha discard seems to work well with value 0.5, also turning on depth writing looks smooth, but as mentioned I can see the back hair through and possibly in this game many players with such hair with different colors would see strange things xD.

I wonder what another solution could be to the problem. But I suppose for now I am quite satisfied with putting alpha discard to 0.5, the hair looks little bit rough, but looks good enough for now.

Here is a screenshot of how the two look:

You should not turn depth write off, you may have other issues
For this kind of situation I guess you need to enable alpha to coverage in addition to the alpha discard threshold. It helps to anti alias jagged edges in transparent textures when pixels are discarded.
Try to enable it on the A.D. 0.5 test. Something like renderManager.getRenderer().setAlphaToCoverage(true) or enableAlphaToCoverage(true) i don’t remember and I can’t check right now.

@The Leo said: Hmm, thanks guys. Alpha discard seems to work well with value 0.5, also turning on depth writing looks smooth, but as mentioned I can see the back hair through and possibly in this game many players with such hair with different colors would see strange things xD.

I wonder what another solution could be to the problem. But I suppose for now I am quite satisfied with putting alpha discard to 0.5, the hair looks little bit rough, but looks good enough for now.

Here is a screenshot of how the two look:

Can you highlight specifically where the issue is on the picture to the right? Because I may be seeing issues that are not there. For example, this part of her hair:

Looks strange… like the head itself is being clipped or something. Can we see what the head would look like without hair at all? Is the head in the opaque bucket where it’s supposed to be?

And note: alpha to coverage only works when AA is on and it will not help with semi-transparent pixels… only with the hard edges.

to me, it’s no better a solution than turning off depth write because it has just as many limitations and anomalies. In your case, most the current anomalies could probably be sidestepped by rendering the inside before the outside (instead of all at once with both faces, render back faces first then front faces).

There are some other options for this sort of thing but JME doesn’t support them natively… at least not without jumping through some otherwise unnecessary hoops. You’d also have to write some custom shaders even if it did.

For example, you could render a version of the hair that outputs transparent color but also does alpha discard on the source image… with depth write on. Basically, you’d just be writing depth to the z-buffer for wherever the hair is drawn in your left picture. Then you could again draw the same mesh with the material you have on the right… but you’d have to be able to change the depth test function to “less or equal” which JME doesn’t let you do.

The artifacts would then be limited to the semi-transparent pixels less than alpha discard threshold where the hair overlaps other semi-transparent hair pixels with alpha less than discard threshold. I think the artifact would be almost unnoticeable for hair of nearly uniform color.

At any rate, none of that can be done without mucking with the materials in code. Not sure how important it is to you versus the trouble involved. alpha discard and alpha to coverage are probably the easiest compromises.

Trying 0.3 or 0.25 as the alpha discard value may smooth things out a bit. It may not - only way to be sure is to try it!

zarch - yea tried, seems 0.5 is the min, anything below, then rectangular squares start to pop out

pspeed-yes the head is in Opaque Bucket, actually the whole figure is one mesh, eyes another, hair another for now
I looked at it again, and yes with Depth Write Off the hair looks smooth, now I remember why I did not want it:
It causes another “artifact” that happens when looking on two objects at same time. Then the hair looks rough.
I tried rotating the camera and looking form different angles, the hair only switches to rough when A tree is seen on the camera.

how it looks with some settings now:

@The Leo said: zarch - yea tried, seems 0.5 is the min, anything below, then rectangular squares start to pop out

pspeed-yes the head is in Opaque Bucket, actually the whole figure is one mesh, eyes another, hair another for now
I looked at it again, and yes with Depth Write Off the hair looks smooth, now I remember why I did not want it:
It causes another “artifact” that happens when looking on two objects at same time. Then the hair looks rough.
I tried rotating the camera and looking form different angles, the hair only switches to rough when A tree is seen on the camera.

This shouldn’t happen. Somehow the one material is affecting the other and it shouldn’t. I wonder if the materials are somehow being shared.

Tell me, in the first picture is the tree there and just out of view or is there not even a tree?

…what version of JME are you running? Is it updated to the latest stable?

pspeed - yes the tree is just out of view, its a tree from jm3-tests -> Models/Tree/Tree.mesh.j3o
I am running jme 3.0RC2

@The Leo said: pspeed - yes the tree is just out of view, its a tree from jm3-tests -> Models/Tree/Tree.mesh.j3o I am running jme 3.0RC2

Make sure you are up to date with the latest stable release. You can do it in the tools plugins menu or whatever. I don’t remember exactly at the moment but it’s in the F1 help.