Suic
Suic

Reputation: 443

TriangleMesh with a partially transparent material gives an unexpected result

Recently, i tried to make transparency work in JavaFX 3D as some of the animations i want to play on meshes use transforms that change the alpha of the mesh each keyframe.

However to my surprise, my TriangleMesh that uses a material which has transparent areas doesn't look as expected.

Current result(depth buffer enabled): https://i.imgur.com/EIIWY1p.gif

Result with depth buffer disabled for my TriangleMeshView: https://i.imgur.com/1C95tKy.gif (this looks much closer to the result i was expecting)

However i don't really want to disable depth buffering because it causes other issues.

In case it matters, this is the diffuse map i used for my TriangleMesh: https://i.sstatic.net/AwT0L.png (1 pixel per triangle as my triangles have a color per face, 128 pixels per column).

I compute UV's for the TriangleMesh like this:

float u = (triangleIndex % width + 0.5f) / width;
float v = (triangleIndex / width + 0.5f) / (float) atlas.getHeight();

and then use these for each vertex of the triangle.

What's the proper way to render a TriangleMesh that uses a transparent material(in my case only part of the image is transparent, as some triangles are opaque)?

After a bit of research, i've found this which potentially explains my issue: https://stackoverflow.com/a/31942840/14999427 however i am not sure whether this is what i should do or whether there's a better option.

Minimal reproducible example(this includes the same exact mesh i showed in my gifs): https://pastebin.com/ndkbZCcn (used pastebin because it was 42k characters and the limit in stackoverflow is 30k) make sure to copy the raw data as the preview in pastebin stripped a few lines.

Update: a "fix" i found orders the triangles every time the camera moves the following way:

  1. Take the camera's position multiplied by some scalar(5 worked for me)
  2. Order all opaque triangles first by their centroids distance to the camera and then after that order all transparent triangles the same way.

I am not sure why multiplying the camera's position is necessary but it does work, best solution i've found so far.

Upvotes: 0

Views: 151

Answers (1)

Suic
Suic

Reputation: 443

I have not yet found a 'proper fix' for this problem, however this is what worked for me pretty well:

  1. Create an ArrayList that'll store the sorted indices
  2. Take the Camera's position multiplied by some scalar (between 5-10 worked for me), call that P
  3. Order all opaque triangles first by their centroids distance to P and add them to the list
  4. Order all triangles with transparency by their centroids distance to P and add them to the list

Use the sorted triangle indices when creating the TriangleMesh

Upvotes: 1

Related Questions