Dynamic Adjusting of transparency for geometry [solved]

Problems building or running the engine, queries about how to use features etc.
Nano
Kobold
Posts: 37
Joined: Wed Jun 01, 2005 6:52 pm
Location: Illinois, USA

Dynamic Adjusting of transparency for geometry [solved]

Post by Nano »

Quick question for those more experienced in these matters than I -- I tried to search the forums, but had no luck in finding an answer to this:

I've got a mesh that I'd like to fade to transparent -- I can make it any transparency that I'd like successfully by altering the alpha value of the diffuse paramater in the material's pass like this:

Code: Select all

pass
{
         scene_blend alpha_blend
         depth_check off
         diffuse 1.0 1.0 1.0 0.3
         texture_unit
         {
                texture tex.jpg 
         }
}
but getting the same pass within the code and calling this:

Code: Select all

pass->setDiffuse(1.0,1.0,1.0,0.3);
doesn't seem to do anything at all. I've tried various combinations of other things, but haven't been able to get it to behave properly. Did I miss something in the documentation or is this more complicated than I'm giving it credit for?

Any help would be most appreciated.
Last edited by Nano on Fri Jun 03, 2005 6:22 pm, edited 1 time in total.
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark
Contact:

Post by DWORD »

You need to do the same in your code as in the script. Please post all the setup code for your material. Something like this might do the trick:

Code: Select all

pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
pass->setDepthCheckEnabled(false);
pass->setDiffuse(1.0, 1.0, 1.0, 0.3);
pass->createTextureUnitState("tex.jpg");
Nano
Kobold
Posts: 37
Joined: Wed Jun 01, 2005 6:52 pm
Location: Illinois, USA

Post by Nano »

Can I change properties of a material that I am initially loading in from a script or do I need to set up the material programmatically in order to have this type of control?
Krulspeld
Kobold
Posts: 35
Joined: Tue Apr 05, 2005 9:51 pm

Post by Krulspeld »

You can create a material in a script and change properties at runtime programmatically. Just ask the MaterialManager for the Material you created by name (See API ref for details).
Nano
Kobold
Posts: 37
Joined: Wed Jun 01, 2005 6:52 pm
Location: Illinois, USA

Post by Nano »

Thanks for the replies. :)

Krulspeld:
You can create a material in a script and change properties at runtime programmatically. Just ask the MaterialManager for the Material you created by name (See API ref for details).
This is precisely what I'm attempting (I've read what the manual and wiki have to say on the matter -- what I could find anyway.

I've got a material like so:

Code: Select all

material pool_stick
{
    technique
    {
        pass
        {
       	scene_blend alpha_blend
       	depth_check off
	diffuse 1.0 1.0 1.0 1.0
	texture_unit
                {
                        texture pool_stick.jpg 
                }
        }
    }
}
and then in the code I'm doing like so:

Code: Select all

Ogre::MaterialPtr material = cueNode->getMaterial();
Ogre::Technique* technique = material->getTechnique(0);
Ogre::Pass* pass = technique->getPass(0);

pass->setDiffuse(1.0, 1.0, 1.0, 0.3);
I've also tried adding all of the lines as DWORD has them, to no avail. Is there perhaps something else I'm missing?
Nano
Kobold
Posts: 37
Joined: Wed Jun 01, 2005 6:52 pm
Location: Illinois, USA

Post by Nano »

:lol:

OK:
Just ask the MaterialManager for the Material you created by name
Krulspeld that actually did the trick -- in my code I was getting the material of the SceneNode, figuring since Ogre::Mesh doesn't HAVE a "getMaterial" and since SceneNode's aren't themselves visible, that SceneNode's "getMaterial" MUST return the mesh's material... but I guess not. using MaterialManager::getSingleton().getByName("pool_stick") instead worked just fine.

Thanks again all.
eyevee99
Greenskin
Posts: 125
Joined: Tue Jul 22, 2003 11:28 am

Post by eyevee99 »

Does this effect everything using that material?

It doesn't seem like a very friendly way to fade an object.

How would this method handle a common situation like fading objects that obstruct the camera?

You want to do something like this (not real code):

Code: Select all

if(testForCameraObstruction())
{
  ObstructingObject->SetAlpha(ObstructingObject->GetAlpha() - timedelta)
}
You can't hard code a material to change the alpha of, as you don't know what you're fading until the obstruction test is met and you've determined which prop is in the way.
Cheers
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

I would suggest to have your ObstructingObject as a wrapper, keeping references to its entity, material... Then adding a setAlpha method would be quite linear. Indeed, I think it's the best way to do it...
Image
User avatar
BlasterN
Gnome
Posts: 378
Joined: Thu Mar 24, 2005 1:07 am
Location: Spain
Contact:

Post by BlasterN »

plz can you post the complete code. I think SceneNode::getMaterial() give a random material of the node.

Think of it. I have the Ogrehead that have 4 submeshes & 4 materials, attached to a scenenode & use getMaterial(). Wich material ogre give to me?

I really dont know I only want to know it.
Works:
MapToMesh | Bengine B9 @ www.sourceforge.net/projects/maptoogremesh/
3DWorldStudio exporter@ www.blastern.info
eyevee99
Greenskin
Posts: 125
Joined: Tue Jul 22, 2003 11:28 am

Post by eyevee99 »

So OgreHead is actually 4 meshes with 4 separate materials... That makes this method even harder as you have to apparently store 4 materials somewhere... Surely there is a programmatical way to retreive the meshes and then materials from an entity...

I'm assuming I've just miss understood the process described at the start of this thread.

:)

NOTE: I'm not actually near a computer with Ogre on it right now... I'm just reading through this for later....
Cheers
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

I can't post the complete code as I haven't done yet, and I don't plan to do it yet.

My suggestio for your proble with the ogre head, is to iterate through all the SubEntities that form the Entity (look in the API docs of Entity, you have the iteration methods there), then retrieving each SubEntity's material, and adjust it.
Image
eyevee99
Greenskin
Posts: 125
Joined: Tue Jul 22, 2003 11:28 am

Post by eyevee99 »

I'm finally back with an Ogre install...

Getting the material works as I expected. You don't need to know the name... You just get it from the entities.

I'm setting the transparency of something as a linear function of the distance. ie, it gradually changes opacity based on the distance

One problem though...

pass->createTextureUnitState("blah.png") eventually causes a segmentation fault after around 16 frames.

Code: Select all

void MyFrameListener::Fade()
{
  Real dist             = (mCamera->getDerivedPosition() - objectNode->getWorldPosition()).length();

  // if approaching atmosphere rentry process fading
  Real alpha          = clamp(0.0, sqr(1.0 - ((dist - 100.0) / (120.0 - 100.0))), 1.0);
  Entity *object     = static_cast<Entity *>(objectNode->getAttachedObject("atmosEntity"));
    
  for(int i = 0; i < object->getNumSubEntities(); ++i)
  {
    Pass *pass        = object->getSubEntity(i)->getMaterial()->getTechnique(0)->getPass(0);
    pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); 
    pass->setDepthCheckEnabled(true); 
    pass->setDepthWriteEnabled(false);
    pass->setDiffuse(pass->getDiffuse().r, pass->getDiffuse().g, pass->getDiffuse().b, alpha); 
    pass->createTextureUnitState("smoke.png");
  }
}
Cheers
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark
Contact:

Post by DWORD »

You shouldn't use Pass::createTextureUnitState() here as it creates a new TextureUnitState every time it's called. Actually, if you set up the material once (e.g. through a script), all you would have to do in Fade() would be setting the alpha component of the diffuse colour as you do now. I.e.:

Code: Select all

  for(int i = 0; i < object->getNumSubEntities(); ++i)
  {
    Pass *pass        = object->getSubEntity(i)->getMaterial()->getTechnique(0)->getPass(0);
    pass->setDiffuse(pass->getDiffuse().r, pass->getDiffuse().g, pass->getDiffuse().b, alpha);
  }
Of course this requires, that your script contains the other options initially. For performance it may be a good idea to enable/disable scene blending on demand, though.

Also note, that if you have more entities using this modified material, they'll change too. So this will probably only work as expected, if the object you're fading has a unique material. There are ways around this, e.g. dynamically creating a copy of the material when fading is needed for an object, and removing it again when it's not needed anymore.
eyevee99
Greenskin
Posts: 125
Joined: Tue Jul 22, 2003 11:28 am

Post by eyevee99 »

I figured it was something like that. Thanks for the heads up.

With dynamic creation do you mean create a new material, do set material on the entity again and then when it's no longer needed set the material back and destroy the dynamic version?
Cheers
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark
Contact:

Post by DWORD »

eyevee99 wrote:With dynamic creation do you mean create a new material, do set material on the entity again and then when it's no longer needed set the material back and destroy the dynamic version?
Yes, something like that; it could be automated.

An idea would be to write a wrapper class taking an Entity* in the constructor. When the wrapper object is created, it would create temporary copies of the SubEntities' materials, and assign those to the SubEntities. Then provide access to these new materials for things like modification of alpha value. On destruction of the wrapper object, the old materials are assigned again, and the temporary materials are destroyed. Maybe an implementation of this should be wikied, people quite often request per object alpha (or is that just me).
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

If this is going to be implemented, I would suggest to clone the material when it's going to be needed, not before (ie, in the constructor), just to save as much memory as possible.

Just a suggestion.
Image
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark
Contact:

Post by DWORD »

Ah yes, just thought you'd only create the wrapper when necessary, and destroy it again. But a clone/de-clone function might be better, I guess that depends on preference. :)

Another solution would be to add 'material sub-classing' capabilities to Ogre::Entity, but maybe that's too much integration into the core. Just a thought.

Code: Select all

Entity::uniquifyMaterials();
Entity::deuniquifyMaterials();
:P

(I'm tired.)
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

DWORD wrote:(I'm tired.)
:lol: Me too :lol:

I thought you were talking about the affected object to be the wrapper itself (like a character or so). If it's just a utility wrapper, then it's fine :) Tons of approaches can be taken (that's part of the magic about OO design :D)
Image
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark
Contact:

Post by DWORD »

Kencho wrote:Tons of approaches can be taken (that's part of the magic about OO design :D)
Yay! :D
eyevee99
Greenskin
Posts: 125
Joined: Tue Jul 22, 2003 11:28 am

Post by eyevee99 »

I don't know about other more general applications, but per object alpha is definately necessary for games development.

Do we have access to the model/mesh vertex colour? Perhaps that gives a per object means of changing opacity?

NB: I do have a material method working (though not through a wrapper class for per object alpha yet), it just seems like a lot of effort for a "simple", common and generally necessary ability. :o)
Cheers
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

Well, it's not a problem of it being easy when programming games, but if it's efficient when programming graphics.

I'll try to write a snippet that does per-object alpha through cloning and a wrapper class this week if possible.

And changing vertex alpha velues is definitely not the solution (amongst other things, because you have the same problem: The mesh data is shared, and changing any value means changing every entity that references that mesh). Just try this method, as is the most commonly said here, and seems to have been proved efficient ;)
Image
eyevee99
Greenskin
Posts: 125
Joined: Tue Jul 22, 2003 11:28 am

Post by eyevee99 »

I'll have the wrapper version working, that's not a problem. Was just trying to find a "simpler" method. if this is the way it has to be done in Ogre that's fine. Just discussing. :)

I wasn't even up to this in my ogre experimentation until I read this thread. It just piqued my interest as on another engine I'm familiar with it's as simple as pModel->color.alpha = blah. Where pModel is as close to an ogre mesh as the engine has, but it's instanced rather than directly shared. No doubt far less efficient on the engine side.

:o)
Cheers
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

I added right now two utility wrapper classes to do this. You can find them HERE
Image
Nano
Kobold
Posts: 37
Joined: Wed Jun 01, 2005 6:52 pm
Location: Illinois, USA

Post by Nano »

Kencho,
I added right now two utility wrapper classes to do this. You can find them HERE
Above and beyond the call of duty, Sir. While I don't need these (yet) since my fading geometry has a unique material, it was quite nice of you to just up and code this for others having the problem.

I'll probably end up back here using these utility wrappers as well, before my Ogre development days are done...
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

Well, I hope these to be useful for someone. At least one user will be enough for me. Not to mention that I'll use them some day (though I don't need them now too).

Hope you find them useful :)

PS: I'll be updating them as I improve them here, so that's not the final version.
Image
Post Reply