Transparent textures interfering with each other in three.js - three.js

I have created a simple human figure. The eyelashes use a texture with transparency.
However as soon as I turn on transparency for the face texture there is created transparency where it shouldn't be.
You can look through the face texture in the part that lies below the eye lashes.
See the effect by toggling face transparency with this line:
mesh.material.materials[3].transparent = false
mesh.material.materials[3].transparent = true
I wish to have transparency turned on for the face texture, so how can I solve this problem?
Demo:
http://dev.udart.dk/transparencyProblemStackOverflow/
(wait for model to load)
Code:
https://github.com/vibber/transparencyProblemStackOverflow/blob/gh-pages/index.html

Transparent geometry gets manually depth-sorted, for more information see this canonical answer by Toji: Transparent textures behaviour in WebGL.
If you want this scenario to work properly, you'll have to split up your model, and render the eyelashes as a separate (sub)mesh. This way three.js can render the rest of the face using the normal z-buffer approach, then apply the eyelashes separately (from the depth-sorted transaprent objects queue).

Related

Three.js transparency artefact on not transparent object

Transparency artefact problem
Hello,
I have an issue with three.js. I import a "big" glb model on my scene which is not transparent, but if the model is covered by itself on the camera view, the foreground become transparent. (as you can see on the picture, the background montain is on foreground)
I tried some solutions like :
depthTest to false on glb material
sortOrder to false
Use logarithmicDepthBuffer
Change material transparent to false
Change alphaTest from 0 to 1 by 0.1 steps
But nothing works. If someone have the solution :)
Thank you !
Rendering of transparent objects cannot be done quite properly. You first need to render any non-transparent objects, and then render transparent surfaces from back to front, so that any new ones blend on top of what was behind it. There are a number of cases where this cannot be done, especially when rendering transparent objects that may overlap themselves.
Fixing this would involve cutting the problematic objects (even single triangles) into smaller pieces so that the ordering can be preserved, and that is often nearly impossible. Since you are working with Three.js, see if you could alter your design so that this isn't a problem, or that the artifacts of incorrect rendering order aren't too much noticeable.
Thanks to donmccurdy which have find my solution on the three.js forum.
Finally my glb file was Transparent :( So there is two solutions.
Solution 1:
Find how the model is transparent and fix it.
Solution 2:
Changing it back to opaque, and restoring the default depthWrite value.
mesh = content.getObjectByName('mesh_0');
mesh.material.transparent = false;
mesh.material.depthWrite = true;

Is it possible to attain something like indexed transparency using three.js?

I am struggling with the common transparency sorting issue. I know there are ways around it (like manually sorting the objects or order-independent transparency) but all that can become quite fiddly. I'd be ok if there was a way to have objects that are partly opaque and partly 100% transparent and have them intersect correctly.
In theory this should be possible. Opaque pixels would be rendered to color buffer and z buffer in the standard way and transparent pixels are just left out.
What I'm looking for is something like indexed transparency as it was used with gif files, for instance that all pixels of an object that have the color #FF00FF are not rendered.
I just don't know if and how this would be possible using three.js. Also, I want to be able to use it with custom shaders.
EDIT: Thanks for your comments so far and sorry for the confusion. This is more of a conceptional thing than a specific problem with my code. It's just that I am often faced with the issue that parts of transparent objects cut out parts of other transparent objects which should be in front of them. Also, transparent objects do not intersect correctly, it's always that one covers another. I understand why this happens and that it is a problem which is inherent to the way transparency is treated. But often I only need parts of an object completely transparent, no partial-shine-through-alpha transparency. Which could be possible if there was a way to leave out certain pixels of objects and render the rest like a normal opaque object.
Let's assume I want to have a metal chain and each segment is a PlaneGeometry thing with a texture that shows the shape of an O (and the rest transparent). Now the chain should be shown with correct interlinkage so to say.
Any help welcome!
Cheers!
If you are rendering a three.js scene, and your texture maps contain no partially-transparent pixels -- that is, each pixel is either 100% opaque or 100% transparent, then you can achieve a proper rendering by setting
material.alphaTest = 0.5;
//material.transparent = true; // likely not needed
The same holds true if you are using a binary alpha-map.
If you are writing a custom shader, then you can achieve the same effect by using a pattern like the following in your fragment shader:
if ( texelColor.a < 0.5 ) discard;
three.js r.84

Cloning textures without causing duplicate card memory in THREE.js

I am using sprite sheets to create animated textures with THREE.js. Each sprite instance utilizes texture offsets to control which of the images to present that frame. Multiple animated sprites may be on the screen at once.
Currently I am using Texture.clone() to duplicate the sprite sheet texture. However, unless I set Texture.needsUpdate to true, the texture will not display on the sprites. Setting needsUpdate to true allows me to display multiple independent animated sprites at once, but unfortunately this causes the texture memory to be duplicate on the card (/ integrated chip). Using Chrome WebGL Inspector I can clearly see that the sprite texture has been duplicate the same number of times as animated sprites that have been rendered.
Is there any way to clone / reuse the texture with different offsets for each instance without duplicating the memory? Is this a bug or am I doing something wrong.
THREE.js r67
Update:
One way that we have gotten around this (not a great way I admit) is to duplicate the GL texture ID assigned to the original texture and set the cloned texture as being initialized.
clonedTexture.__webglTexture = origTexture.__webglTexture;
clonedTexture.__webglInit = true;
This requires that the texture has already been sent to the card, which we force with render.setTexture(origTexture...).
This is something that's in the works. Keep an eye for whenever THREE.Image lands.

OpenGL transparency and depth issues with three.js

I'm using three.js for a small game which utilizes textures with transparency. Things were going great until I noticed some errors due to depth testing:
Good from one angle
Bad from another
Some research has brought me to these posts, but I am still trying to figure out how to apply their suggestions in a three.js environment:
Rendering glitch with GL_DEPTH_TEST and transparent textures
Blending transparent textures with depth
As far as I know, {transparent: true} in a THREE.Material already separates transparent materials from opaque ones for proper rendering. However, I cannot get away with disabling depth writes because I don't have control over the rendering order of the transparent geometry (as far as I know). Am I missing something obvious that will help me out of this mess?

LibGDX - Sprites to texture using FBO

I am working on a simple painting app using LibGDX, and I am having trouble getting it to "paint" properly with the setup I am using. The way I am trying to do this is to draw with sprites, and add these individual sprites into a background texture, using LibGDX's FBO commands, when it is appropriate.
The problem I am having is something relating to blending, in that when the sprites are added to this texture that I am building, any transparent pixels of the sprite that are on top of pixels that have been drawn to previous will be brightened up substantially, which obviously doesn't look very good. The following is what the result looks like, using a circle with a green>red gradient as the "brush". The top row is part of the background texture now, while the bottom one is still in its purely sprite drawn form.
http://i238.photobucket.com/albums/ff307/Muriako/hmm.png
Basically, the transparent areas of each sprite are brightening anything below them, and I need to make them completely transparent. I have messed around with many different blending mode combinations and couldn't find one that was any better. GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA for example did not have this problem, but instead the transparent pixels of each sprite seem to be lowered in alpha and even take on some of the color from the layer below, which seemed even more annoying.
I will be happy to post any code snippets on request, but my code has become a bit of mess since I started trying to fix these problems, so I would rather only put up the necessary bits as necessary.
What order are you drawing the sprites in? Alpha blending only works with respect to pixels already in the target, so you have to draw all alpha-containing things (and everything "behind" them) in Z order to get the right result. I'm using .glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

Resources