Rendering transparent triangles with opengl...

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Rendering transparent triangles with opengl...

ManuelBrotz
This post was updated on .
Hello

I am new to opengl and have a problem.
I want to render some semi-transparent, overlapping triangles using opengl. The rendering works, but the triangles don't look right.

What do i have to do, to make them look the way i want?

I have attached an eclipse project with the source i used to render both images below.
Triangles.zip

Please note, that you will only see the difference between the two files when you use the attached eclipse project to generate them on your own machine!

The opengl rendering seems to get the alphablending wrong. I think, the alpha channel of a rendered triangle always replaces the alpha channel of the pixels below the triangle. This is not what i want!

Any help is appreciated!

Manuel Brotz

See below for example images!
Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

Xerxes Rånby
Hi

You are tackling a "hard" problem, the behaviour you see with opengl is
correct according to the opengl specification.

There is several papers available on how to do Order-Independent
Transparency using opengl.
http://on-demand.gputechconf.com/gtc/2014/presentations/S4385-order-independent-transparency-opengl.pdf

OpenGL only give you an API to make use your hardware, its up to you to
use it properly.

I would suggest you to study different ways to do Order-Independent
Transparency using a GPU.
http://en.wikipedia.org/wiki/Order-independent_transparency

You may get the effect you want if you first sort the triangles to be drawn from back to front, but that is not enough you actually need to sort each pixel fragment as shown in the linked paper above.

Cheers
Xerxes

Den 2015-05-22 12:47, ManuelBrotz [via jogamp] skrev:
> Hello
>
> I am new to opengl and have a problem.
> I want to render some semi-transparent, overlapping triangles using
> opengl. The rendering works, but the triangles don't look right.
>
> What do i have to do, to make them look the way i want?
>
> I have attached an eclipse project with the source i used to render
> both images below.
> Triangles.zip <http://forum.jogamp.org/file/n4034507/Triangles.zip>
>
> Please note, that you will only see the difference between the two
> files when you use the attached eclipse project to generate them on
> your own machine!
>
> The opengl rendering seems to get the alphablending wrong. I think,
> the alpha channel of a rendered triangle always replaces the alpha
> channel of the pixels below the triangle. This is not what i want!
>
> Any help is appreciated!
>
> Manuel Brotz
>
>
>
> That's what i get: (rendered using opengl)
>
>
> That's what i want: (rendered using BufferedImage and Graphics2D)
>
>
>
> ------------------------------------------------------------------------
> If you reply to this email, your message will be added to the
> discussion below:
> http://forum.jogamp.org/Rendering-transparent-triangles-with-opengl-tp4034507.html 
>
> To start a new topic under jogl, email
> ml-node+s762907n782158h61@n3.nabble.com
> To unsubscribe from jogamp, click here
> <http://forum.jogamp.org/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=762907&code=eGVyeGVzQGd1ZGlubmEuY29tfDc2MjkwN3wtNTE5NjUwMzEw>.
> NAML
> <http://forum.jogamp.org/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml
>

Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

Xerxes Rånby
The JogAmp JOGL demos contains Alexandra Bokinsky's Port of NVIDIA OpenGL Order Independent Transparency with Dual Depth Peeling  demo.
http://developer.download.nvidia.com/SDK/10.5/opengl/samples.html

https://jogamp.org/git/?p=jogl-demos.git;a=tree;f=src/demos/dualDepthPeeling

Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

ManuelBrotz
Thank you for your answer.

I am not sure, whether i need depth peeling (i have disabled depth-mask) and i think, i don't need order-independent transparency...
My triangles are 2D only and will never have a z-coordinate. Nor does it matter to me, that the transparency is order-dependent.

All i want to do, is to blend a number of transparent triangles over each other and get a similar effect like i get it with the BufferedBitmap and Graphics2D...

By the way, the colors seem to blend fine, it's the alpha-channel, which makes problems...

I will try to give some better examples later, when i have more time.

M. Brotz
Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

gouessej
Administrator
Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

Xerxes Rånby
This post was updated on .
In reply to this post by ManuelBrotz
ManuelBrotz wrote
...
My triangles are 2D only and will never have a z-coordinate. Nor does it matter to me, that the transparency is order-dependent.

All i want to do, is to blend a number of transparent triangles over each other and get a similar effect like i get it with the BufferedBitmap and Graphics2D...

By the way, the colors seem to blend fine, it's the alpha-channel, which makes problems...

I will try to give some better examples later, when i have more time.

M. Brotz
I think i have the solution for you:

Brandon Borkholder has made a really cool project called GLG2D that implements a working Graphics2D using JogAmp JOGL.

http://brandonborkholder.github.io/glg2d/

You may use glg2d as is or be inspired by it.

If you look inside Brandons implementation you find his AbstractColorHelper class that implements the color precomutation required for OpenGL to implement Alpha blending the same way as Java2D, have a look for the SRC_ATOP implementation in this file:

https://github.com/brandonborkholder/glg2d/blob/master/src/main/java/org/jogamp/glg2d/impl/AbstractColorHelper.java

Cheers
Xerxes
Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

ManuelBrotz
Hello Xerxes

GLG2D is very interesting! I need to be able to render into a backbuffer and access the pixeldata, though. So far, i have found nothing in GLG2D about that, unfortunately...
Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

ManuelBrotz
Here are some better example images, i hope:

Half of the background of the images is rendered in black using java or jogl respectively.
The other half of the background is transparent. I used GIMP to blend the rendered images over
a checkerboard background to highlight the transparent parts of the images.

As you can see, in jogl the checkerboard bleeds through the black half of the background. In java, everything is fine...
Something is going completley wrong with alpha blending using jogl and i have no idea how to fix this...

Java rendering (good)


Jogl rendering (bad)


Again, the source code to render the images:
Triangles2.zip
Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

Xerxes Rånby
This post was updated on .
I took a look at your code and have identified some logical errors made:

#1
You have requested alpha bits in the GLCapabilites
caps.setAlphaBits(8);
making it possible for the alpha part of each draw operation to be stored on the destination surface.
You also use the following blend function
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
causing the source triangles alpha part to control opaqueness when drawing the triangles.
This combination do not work for you because the alpha is used twice.

I have two suggested "solutions" to you:

A: Do not request a surface with AlphaBits, use:
caps.setAlphaBits(0);
This will make alpha blending behave as you expected, the alpha is then only used once to control the opaqueness of each triangle and no traces of the alpha is stored at the destination surface.
Like this:


B: If you want a surface with AlphaBits, use the following blend function:
"Premultiplied Alpha Blending"
gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA);

This make the triangles slightly brighter compared to your Java2D version but the effect is similar.
This blending mode work for both caps.setAlphaBits(0); and caps.setAlphaBits(8);

I really enjoyed the following page while writing this answer that describes the OpenGL Blending stage using GLSL equations:
http://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Transparency

#2
When storing the gl pixels to a BufferedImage you should use:
bufferUtil = new AWTGLReadBufferUtil(glp, true);
image = bufferUtil.readPixelsToBufferedImage(gl, false);

This will make the red and blue correct in the generated png file.

#3
Your Java2D example and your JOGL example do not use the random number generator identically therefore you got two different compositions of triangles despite using the same random number generator seed.

#4
Your JOGL example happened to render 100000 triangles while your Java2D example rendered 100.
You may want to drop the for loop around render 100 random triangles ;)

for (int i = 0; i < 1000; i++) {
            TrianglesJoglHelper.renderRandomTriangles(gl, rng, 100, Width, Height);


I had to fix 2,3&4 in order to be able to compare the jogl and your java2d output.
Reply | Threaded
Open this post in threaded view
|

Re: Rendering transparent triangles with opengl...

ManuelBrotz
Thank you so much for your help! I've never worked with opengl bevore and don't realy understand the code i use, i just copied it from other examples. :) Solution A is a very good start! Thanks!

#2: I actually need the raw pixeldata, i just used a buffered image for comparison.
#3: I just didn't care about the triangles looking different, though i understand, that it makes comparing the images unnecessary difficult.
#4: Since i am intending to speed up my application i added that for loop to measure, how much of a speedup i could expect. And since Java2D is really slow, i just reduced the loop to 1 for experimentation... :)

Again, thank you so much for your help and the references, you really got me started here!

Manuel Brotz