katopz / jsc3d

Automatically exported from code.google.com/p/jsc3d
0 stars 1 forks source link

No transparency #41

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I've been trying to export canvas renderings to png via data urls...
With no background colors / image there is still solid black.

What is the expected output? What do you see instead?

What version of the product are you using? On what operating system?

Please provide any additional information below.

I've used this rather hackish solution where my background color is pure green 
and .... 

    case 'standard':
    default:
        for(var src=0, dest=0; src<csize; src++, dest+=4) {
            var color = cbuf[src];
            data[dest    ] = (color & 0xff0000) >> 16;
            data[dest + 1] = (color & 0xff00) >> 8;
            data[dest + 2] = color & 0xff;
            if (color != 0x00FF00){
                data[dest + 3] = 0xff;
            } else {
                data[dest + 3] = 0x00;
            }
        }
        break;
    }

Original issue reported on code.google.com by a...@cheong.co on 3 Sep 2013 at 8:46

GoogleCodeExporter commented 9 years ago
That's it. Current implementation simply write 0xff to the alpha chanel so it 
won't produce real transparent background.

Your modification no doubt works to achieve the goal. But I suggest a slightly 
more elegant method. When raterizing, jsc3d also writes IDs (always >0) of each 
mesh to a buffer named 'selectionBuffer' which can be used to detect the 
coverage of primitives: for each pixel in viewer.selectionBuffer, if there's a 
primitive its value should be greater than 0; otherwise it is pure background. 
The selection buffer has the same dimensions with the color buffer and the 
z-buffer.

The implementation looks like the following:

    var sbuf = this.selectionBuffer;
    ...
    case 'standard':
    default:
        for(var src=0, dest=0; src<csize; src++, dest+=4) {
            var color = cbuf[src];
            var id = sbuf[src];
            data[dest    ] = (color & 0xff0000) >> 16;
            data[dest + 1] = (color & 0xff00) >> 8;
            data[dest + 2] = color & 0xff;
            data[dest + 3] = id > 0 ? 0xff : 0; // transparency for backgound area
        }
        break;
    }
    ...

And now you don't need to fill backgound with a specific color :-)

Original comment by Humu2...@gmail.com on 3 Sep 2013 at 6:53

GoogleCodeExporter commented 9 years ago
thank you!

Original comment by a...@cheong.co on 3 Sep 2013 at 7:22

GoogleCodeExporter commented 9 years ago
It's much better this way but I have a minor issue still, a nice to have really.

For some models such as trees and hair the textures often include alpha.

I think the way the blending is done right now there is no support for 
transparent in the starting buffers? Here is a picture to illustrate what I 
mean. I have set the background colors to #FFFFFF and use your code above.

http://imgur.com/AeFBQZc

Original comment by a...@cheong.co on 3 Sep 2013 at 11:38

GoogleCodeExporter commented 9 years ago
This is because mesh IDs are always written into the selection buffer even for 
transparent sub areas.

Transparent background is a planned feature but not supported at this moment. 
Current implementation just blend the colors of the foreground and the 
background directly in the renderer's color buffer. But to implement 
transparent backgound, we also have to perform blending between dom layers(the 
canvas and elements behind it) in a correct way. This is more complicated.

So the tricks we discussed above (determine alpha value of a pixel by checking 
the selection buffer) only work fine for opaque texture or transparent texture 
with alpha mask (0 or 255) rather than alpha gradient.

Original comment by Humu2...@gmail.com on 4 Sep 2013 at 3:20

GoogleCodeExporter commented 9 years ago
Is there no way to prefill the pixel buffers with "transparent" color somehow 
or does that need another array for per pixel alpha?

i.e. the empty arrays have full rgba

i.e. begin with transparent black
when you blend you average like you are doing now?
so 50% transparent red + 0% (transparent) black becomes 50% transparent red the 
r,g,b values of 0 would be discarded as their weighting would be 0?

Original comment by a...@cheong.co on 4 Sep 2013 at 4:47

GoogleCodeExporter commented 9 years ago
Your idea is correct. For each item in the color buffer, the highest 8 bits are 
reserved and not used now, where we can write in alpha values. When blending we 
just blend the foreground alpha (from textures and mateials) with the backgound 
alpha (from the color buffer), and write back the result to the color buffer. 
In this way the canvas with our rendering would automatically blend correctly 
on pages.

Would you like to try it out?

Original comment by Humu2...@gmail.com on 4 Sep 2013 at 6:31

GoogleCodeExporter commented 9 years ago
Transparent background is supported now. Please check out the latest jsc3d.js 
and jsc3d.webgl.js from the repository.

Original comment by Humu2...@gmail.com on 13 Feb 2014 at 11:01

GoogleCodeExporter commented 9 years ago
I really wish to set the background to transparent on the DataURL export but 
sadly do not understand the code you guys have pasted above. Is it just plain 
java script? A more detailed explanation would leave me one very happy camper! 
:)

Original comment by TonyVJe...@gmail.com on 23 Dec 2014 at 10:44

GoogleCodeExporter commented 9 years ago
I found a simple solution actualy... Change the DataURL type to png....
var dataURL = cv.toDataURL('image/png');

Original comment by TonyVJe...@gmail.com on 24 Dec 2014 at 12:38

GoogleCodeExporter commented 9 years ago
You get it. PNG is the only image format that contains alpha channel and is 
well-supported by most browsers.

Original comment by Humu2...@gmail.com on 24 Dec 2014 at 1:29