-
-
Notifications
You must be signed in to change notification settings - Fork 35.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alpha Edge Quality of Canvas-based Textures #1864
Comments
I think this may be caused by black RGB part of RGBA for pixels with alpha < 1. You can try setting these semi and fully transparent pixels to white. Or you may try to experiment with alpha premultiplication for texture / different material blending options: http://mrdoob.github.com/three.js/examples/webgl_materials_blending_custom.html |
Maybe is the same as #1625? |
Hmm. Definitely seems related to that issue, mrdoob. I'm not sure I can use your solution of adding kind of buffer pixels, though, since in some cases I'm using drawImage to add a png directly (as with the speech bubble). alteredq, I checked out the blending example and did some experiments. premultiplyAlpha seems to have no effect and I get really crazy effects when I use THREE.CustomBlending. I can see through the alpha to the web page body behind the canvas: http://tweetopia.net/r10/test/blendTest.png I'm probably doing something wrong. Here is my code: var panelTexture = new THREE.Texture( $(tweetCanvas)[0] );
panelTexture.premultiplyAlpha = false;
panelTexture.needsUpdate = true;
var panelMaterial = new THREE.MeshBasicMaterial( { map: panelTexture } );
panelMaterial.transparent = true;
panelMaterial.doubleSided = true;
panelMaterial.blending = THREE.CustomBlending;
panelMaterial.blendSrc = THREE.SrcAlphaFactor;
panelMaterial.blendDst = THREE.SrcColorFactor;
panelMaterial.blendEquation = THREE.AddEquation;
var panelMesh = new THREE.Mesh( panelGeometry, panelMaterial); It seems like one of those blending options may help if I can get it right, but the problem seems deeper. You can see the original bubble image here: http://tweetopia.net/r10/textures/bubble.png If I use that directly as a texture with loadImage, there are no artifacts. And here is the bubble image drawn to the canvas and then saved from there as a png with toDataURL: http://tweetopia.net/r10/test/bubbleTest.png There's no weird alpha channel or anything as far as I can tell. So it seems like it must be something about the way the texture is created from the canvas? |
http://twitpic.com/9h00hs/full Try doing this:
|
By default the pixels of a canvas are 0,0,0,0 and, in your case, you need them to be 255,255,255,0. Either you do it by hand modifying the imagedata.data, or you do it with the approach I posted above. |
Ah, you are absolutely right about the default value and your approach to get white alpha totally makes sense, but unfortunately it doesn't seem to work for me. Even with "destination-in", which crops as expected, I still get black values in the alpha: http://tweetopia.net/r10/test/bubbleTestWhite.png I found a handy way to check with ImageMagick:
I also double checked with:
And got:
Then:
It looks like no matter what you do, the canvas ends up with black alpha. I even tried filling with various opacities of white, but as soon as I hit zero alpha, everything went black. It's like for the canvas, if alpha is zero, so are RGB. As a solve for this particular case, I've made a shader that sets anything with alpha < 1.0 to white and that seems to work, but it would be problematic for something that was another color. I think for that stuff I'll just build everything with materials and geometry instead of using the canvas, I just didn't want to have to mess with text that way. As always, you're incredibly awesome for taking so much time to help people with these issues. |
Ah! Shame... Did you tried changing the pixels with imagedata.data? It's basically doing what you're doing in the shader. |
Hmmm, so it seems like canvas always premultiplies alpha. Did you try setting Also did you already try to use And I still think that there may be some blending combination that may work - try to make a copy of the blending example I posted, replacing one of the foreground images with yours canvas generated one and see how it looks against various backgrounds with different options. |
Same results with
I did some more experimenting with webgl_materials_blending_custom.html by dropping in my own image, and it actually looks like both One/SrcColor DstAlpha/SrcColor lose the black border, which is great, but for some reason I'm having a hard time porting the effect to my scene. When I use:
I get: http://tweetopia.net/r10/test/blendTest.png (Those stripes are on the body, not in the render). I'm probably missing something, but I don't know what. |
Oh! I think I was confused by the labels in the example and had It works now as expected as far as the edges are concerned, but the text colors get blown out with both Looks like my best bet is the shader solution that makes alpha white. Thanks again for all of the help! |
I managed to get quite ok looking results by turning on alpha premultiplication and just using custom blending, leaving everything else on default ( texture.premultiplyAlpha = true;
bubbleMaterial.blending = THREE.CustomBlending; http://alteredqualia.com/tmp/tests/blending/webgl_canvas_alpha_test.html This btw differs from default |
I had similar issues and this is key to working with a canvas texture I think:
I think it would make for a good default for CanvasTexture, since it is always pre-multiplied colors. PS: Using |
Oh! Interesting... |
I'll try to make a fiddle so we can see the difference in a live example. |
Would be great since it is difficult to isolate from my project and I'm no threejs expert. My guess is that edges will look much better by default (with premultiplyAlpha=true), and should look the same if |
I've created a little test case but I'm not sure the used sprite texture is good to demonstrate the issue: https://jsfiddle.net/f2Lommf5/11045/ As far as I can see, setting @maartenbreddels Any tips to improve the demo? |
Yes, I created a new version here: As you can see, the red circle (101 overlapped and blended) shows a dark edge (this is why i chased this). This is caused, because the colors will be 'un-multiplied', and later on in the opengl pipeline multiplied again (SrcAlphaFactor). For low alphas this will cause the artifacts (loss of precision I guess). So the defaults now ( |
Thanks for the chances! The dark edges are now nicely to see^^ @mrdoob Still, changing the default values of normal blending (in this case the |
I'm seeing this in a few places, but when I create an image on a canvas and use it as a texture, I get black artifacts at the edges of the alpha. This doesn't happen when I use normal images as textures.
I've made the sky white in this example so you can really see the dark edges around the speech bubble:
http://tweetopia.net/r10/test/edgeTest.png
Is there something I can do to avoid this? I don't see these edges with I create and download a png of the canvas.
Thanks!
The text was updated successfully, but these errors were encountered: