• Advertisement
Sign in to follow this  

Intraobject transparency

This topic is 3740 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, what would be the correct way to draw an object that has multiple transparent textures over each other. I am trying to make a low-poly fir tree out of five cones with five sides each, but when the program draws the object, the cones with the branch texture get drawn in wrong order, top-down, and the top cones have an ugly see-trough effect. Must I export the faces from Blender in correct order (bottom up) or is there some way to disable intra-object depth-testing. I don't want to disable the global depth test as I don't want the tree to stick atop everything. The tree is supposed to be viewed from a 45 degree angle above (Similar to any rts, transport/city sim). edit:Could I use glBlendFunc() with GL_(ONE_MINUS_)DST_ALPHA to solve this? Which parameters should I use when I make the call? [Edited by - Rakshasa on October 25, 2007 2:05:46 PM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Rakshasa
... is there some way to disable intra-object depth-testing. I don't want to disable the global depth test as I don't want the tree to stick atop everything.


So the short answer to this is yes. When drawing the tree, turn off depth writes, but keep the depth test on. Then draw the tree again with color writes off and depth writes on. That will avoid "intra-object depth-testing".

Unfortunately, this doesn't actually give you the effect you want. If you want correct alpha blending you need to have the faces sorted. Alpha testing might be an option here.

Share this post


Link to post
Share on other sites
If you are just want something look like transparent, you can change your blend function to GL_ONE and GL_ONE. Of course, this is not really the correct way of doing transparent effect. However, it can fool our eye in most cases as we are less likely picking up this fault.

Share this post


Link to post
Share on other sites
Looks as though you need to experiment with the opengl pipeline i.e.
to get familiar with blending techniques.

So...Here is experiment (1):

It's a neat little trick I use when prototyping;

or on a less formal level :

"It's a neat little hack that produces quick results :(without sorting at face level)"

so e.g. pseudocode:


// Precondition(s)[Unfortunately]:
// (0) All opaque(textured) models have been rendered
// (1) This whole model is skinned with alpha channelled texture(s)
// (2) there may be others depending on the nature of the model(s) that may have
// other texture condtions... e.g. model(s) skinned with opaque texture(s)...dum didi daa.
// (3) Bound the texture ala... glBindTexture( GL_TEXTURE_2D,...)
void Model::Render()
{

// do the stuff you are currently doing like
// e.g. like glPushMatrix();
// glEnable(GL_TEXTURE_2D);
// glEnable(GL_COLOR_MATERIAL);
// glEnable(GL_LIGHTING);
// glColor3f(0.6f, 0.6f, 0.6f);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glDepthMask(GL_FALSE);

glEnable(GL_CULL_FACE);

glCullFace(GL_FRONT);
// DO Your Draw stuff: like glDrawArrays(GL_TRIANGLES, 0, m_vertexCnt);
// or a more immediate mode: looping thru all glVertex3fv();.. glNormal3fv.. glTexCoord2f.. stuff etc

glCullFace(GL_BACK);
// DO Your Draw stuff: like glDrawArrays(GL_TRIANGLES, 0, m_vertexCnt);
// or a more immediate mode: looping thru all glVertex3fv();.. glNormal3fv.. glTexCoord2f.. stuff etc

glDisable(GL_CULL_FACE);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);

// do the stuff you are currently doing
// e.g. for completeness
//
//glDisable(GL_TEXTURE_2D);
//glDisable(GL_COLOR_MATERIAL);
//glDisable(GL_LIGHTING);
//glPopMatrix();
}




Now... that is one example.
If It works for you...then your next task will be to..post back here with an explanation why its works!
Seriously though... let us know what happens...I will be dissappointed if it doesn't help you.


[/source]

Share this post


Link to post
Share on other sites
Quote:
Original post by steven katic
...
"It's a neat little hack that produces quick results :(without sorting at face level)"
...
[/source]


Just to remind you steven, this hack works only if the whole scene contains only a single convex 3D model (e.g. a sphere or a ellipsoid). Otherwise, you still need to do sorting.

Share this post


Link to post
Share on other sites
Quote:

Just to remind you steven, this hack works only if the whole scene contains only a single convex 3D model (e.g. a sphere or a ellipsoid). Otherwise, you still need to do sorting.


hmmm...yes well.
I do appreciate the "correct" way would be to sort the faces,
especially if the "camera" has six degrees of movement
(or even perhaps less than six).
And by all means I wouldn't stop anyone from recommending learning/knowing/implementing one of the most robust solutions (sorting at face level stuff ) Rakshasa can use.

However, there are advantages to be had due to:
Quote:

The tree is supposed to be viewed from a 45 degree angle above (Similar to any rts, transport/city sim).


This to me , implies perhaps a maximum of 3 degrees of movement?
The little experiment(1) I presented can be a major part of the whole (older?)solution that I believe will make no difference as far as what the user sees, and whether
sorting at face level is implemeted or not. (The other part(s) involve something to do with (things Rakshasa has already alluded to):
(1) how the models are constructed
(2) the order in which the tree models are rendered

Taking advantage of the limitation on the degrees of movement may take a little more thought (and obviously has err... limitations!?).

Whereas sorting of faces takes a lot more work as well as thought...but once done is very transferable to other applications( in this sense being more "correct").

Personally I would experiment with both alternatives (hack and face sorting)
If I was pressed for time(yeah..deadlines) I would do the "hack".
If I was going to move on to more serious 6 degree's of movement in the future
I would do the stuff along the lines of face sorting stuff.

Maybe now there is a little more info here now that will help Rakshasa
make his choice? or...research the topic more?

Share this post


Link to post
Share on other sites
I think you missed the point, steven.

Your hack works only for a convex 3D scene, for example a single sphere. Otherwise, it will simply break down.

You are assuming the whole scene make of two layers only (back faces and front faces). That's why you can take back faces as further away and front faces nearer. However, when the 3D scene are not convex (e.g. a teapot or two balls), you have more than one layers of back faces (so as front faces). So, depending on the ordering of back faces (so as front faces), drawing order problem occurs as usual. And, it is very noticeable which will make "a difference as far as what the user sees".

Personally, I don't think this hack help. Why would anyone want a 3D scene which contains a single convex 3D model? What is the use of drawing a single sphere on screen or a drawing a single cube on screen?

By the way, it is purely a drawing order problem and therefore have nothing to do with view angle or "degrees of movement" ("degrees of movement"?).

Share this post


Link to post
Share on other sites
Quote:

Your hack works only for a convex 3D scene, for example a single sphere. Otherwise, it will simply break down.


not true. And I am not going to explain.

Sorry I keep missing the point. It must be my pig headedness.

Quote:

Personally, I don't think this hack help.


I assume you have tried it.

I am sorry, I stand by what I have posted.

Quote:

By the way, it is purely a drawing order problem and therefore have nothing to do with view angle or "degrees of movement" ("degrees of movement"?).


Oh...I thought your drawing order is dependant on your viewing position.
Or am I wrong?

Let's be a little positive....provide Rakshasa your solution.

Quote:

If you are just want something look like transparent, you can change your blend function to GL_ONE and GL_ONE. Of course, this is not really the correct way of doing transparent effect. However, it can fool our eye in most cases as we are less likely picking up this fault.


somehow this seems a little inadequate to me...

Share this post


Link to post
Share on other sites
Quote:
Original post by steven katic
Quote:

Your hack works only for a convex 3D scene, for example a single sphere. Otherwise, it will simply break down.

not true. And I am not going to explain.


If it does work in general, please explain. I would be delighted to find out it does.

In particular, can I draw a transparent "teapot over a plane" correctly with your hack?

Share this post


Link to post
Share on other sites
Quote:

If it does work in general, please explain. I would be delighted to find out it does.


This is not a general case we are talking about. The solution(s) are
specific to:

Quote:

The tree is supposed to be viewed from a 45 degree angle above (Similar to any rts, transport/city sim).


This is a critical point that should not be overlooked.

Quote:

In particular, can I draw a transparent "teapot over a plane" correctly with your hack?


my goodness... you persist in challenging me ....for nought.

and nought.... you will get.

Why won't you try it yourself? maybe you have?
(I am getting tired of repeating myself)

My advice is: Convince youself.

As an interlude, however, see it in action:

you can try out FileViewer 3.14.2

here




It implements the experiment(1) I provided (plus more).

You can even load a plane, load a teapot and put an alpha texture on it
if you want, and see for yourself... how experiment(1) works and also the
drawbacks of not sorting polygons as you move the camera freely around.

Tear it apart with criticism if you wish but not here, and don't post in this thread about it (email me RE: fileviewer if you need to or), use another thread.

This is Rakshasa thread topic.

Note: UI is similar to 3dsmax 3.x, which hopefully reduces the ui learning
curve for those that have used 3dsmax.


oh, ma_hty, If you still have a problem with my "hack" after trying the fileviewer, put me down as someone who doesn't know what he's taking about it... It is my obvious preference to giving you an explanation...

and maybe spend a little time addressing the questions in my last post:
They are critical.

Cheers

ps: RE: fileviewer: if you have vista, best to disable aero, and run as xp compatible app! warning: also it may time out (Stop/Crash)after 2 seconds of loading(e.g. HUGE models: gotta love microsoft's feature's?)

[Edited by - steven katic on October 27, 2007 9:39:33 PM]

Share this post


Link to post
Share on other sites
As you insist your hack work in general, I implemented your hack that draw a simple scene to demostrate how its break down.



#include <stdio.h>
#include <stdlib.h>

#include <GL/glut.h>

float angle = 0;

void display();
void keyboard( unsigned char key, int x, int y );

void draw_plane_group1();
void draw_plane_group2();

void main( int argc, char **argv )
{
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_ALPHA );
glutInitWindowSize( 512, 512 );

glutCreateWindow( "test08" );
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );

glutMainLoop();
}

void keyboard( unsigned char key, int x, int y )
{
switch( key )
{
case 'r':
angle+=5;
glutPostRedisplay();
break;
}
}

void display()
{
GLint viewport[4];
glGetIntegerv( GL_VIEWPORT, viewport );

glEnable( GL_DEPTH_TEST );

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45, double(viewport[2])/viewport[3], 0.1, 100 );

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0,0,9, 0,0,0, 0,1,0 );
glRotatef( angle, 1,0,0 );

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);

glPushMatrix();
glTranslatef( -1.5,0,0 );
draw_plane_group1();
glPopMatrix();
glPushMatrix();
glTranslatef( 1.5,0,0 );
draw_plane_group2();
glPopMatrix();

glCullFace(GL_BACK);

glPushMatrix();
glTranslatef( -1.5,0,0 );
draw_plane_group1();
glPopMatrix();
glPushMatrix();
glTranslatef( 1.5,0,0 );
draw_plane_group2();
glPopMatrix();

glDisable(GL_CULL_FACE);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);

glutSwapBuffers();
}

void draw_plane_group1()
{
glColor4f( 1,0,0, .5 );
glBegin( GL_QUADS );
glVertex3f( -1,-1, 1 );
glVertex3f( 1,-1, 1 );
glVertex3f( 1,1, 1 );
glVertex3f( -1,1, 1 );
glEnd();

glColor4f( 0,0,1, .5 );
glBegin( GL_QUADS );
glVertex3f( -1,-1, 0 );
glVertex3f( 1,-1, 0 );
glVertex3f( 1,1, 0 );
glVertex3f( -1,1, 0 );
glEnd();

glColor4f( 0,1,0, .5 );
glBegin( GL_QUADS );
glVertex3f( -1,-1, -1 );
glVertex3f( 1,-1, -1 );
glVertex3f( 1,1, -1 );
glVertex3f( -1,1, -1 );
glEnd();
}

void draw_plane_group2()
{
glColor4f( 0,1,0, .5 );
glBegin( GL_QUADS );
glVertex3f( -1,-1, -1 );
glVertex3f( 1,-1, -1 );
glVertex3f( 1,1, -1 );
glVertex3f( -1,1, -1 );
glEnd();

glColor4f( 0,0,1, .5 );
glBegin( GL_QUADS );
glVertex3f( -1,-1, 0 );
glVertex3f( 1,-1, 0 );
glVertex3f( 1,1, 0 );
glVertex3f( -1,1, 0 );
glEnd();

glColor4f( 1,0,0, .5 );
glBegin( GL_QUADS );
glVertex3f( -1,-1, 1 );
glVertex3f( 1,-1, 1 );
glVertex3f( 1,1, 1 );
glVertex3f( -1,1, 1 );
glEnd();
}




In the demo, you can press 'r' to rotate the scene. If your hack works, the plane group on the left should be the same as those on the right. And, it is not.

a captured image from demo

Share this post


Link to post
Share on other sites
Quote:
Original post by steven katic

This is not a general case we are talking about. The solution(s) are
specific to:

Quote:

The tree is supposed to be viewed from a 45 degree angle above (Similar to any rts, transport/city sim).


This is a critical point that should not be overlooked.



Even you have a fixed view direction for all 3D models, the faces of a 3D model would still have a drawing order. Without having them sorted, you have drawing order problem. And your help won't help unless the scene contains a convex 3D model only.

Share this post


Link to post
Share on other sites
Quote:
Original post by steven katic
now try it with a uv mapped/alpha mapped texture on the quad(s), not just color:
set color to glColor4f( 1,1,1,1 );


Mapping a texture is not necessary for this demostration.

If you really wanted it to be, you can simply consider there are three texture of constant color (1,0,0,.5), (0,1,0,.5) and (0,0,1,.5).

Share this post


Link to post
Share on other sites
I am not familiar with glut (anymore).

Quote:

Mapping a texture is not necessary for this demostration.

If you really wanted it to be, you can simply consider there are three texture of constant color (1,0,0,.5), (0,1,0,.5) and (0,0,1,.5).


Well I must say: I guess you tried it and it didn't work then.
The important thing is that you are convinced either way.

Cheers

Share this post


Link to post
Share on other sites
The "hack" that has been under discussion here is an old technique and has more commonly been referred to as the "cull-mode sorting trick" if anyone is interested in further info (even other threads on gamedev have touch on it).

Also of importance is my error:

Quote:


Quote:

Your hack works only for a convex 3D scene, for example a single sphere. Otherwise, it will simply break down.


not true. And I am not going to explain.


I am wrong. my sincere apologises for providing misinformation.
meshes do need to be convex.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement