How can I force PART of a texture to full brightness?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

How can I force PART of a texture to full brightness?

Post by Devil Master »

I wrote this code:

Code: Select all

void CreateWorld(void)
{
 unsigned int i;
 unsigned char nextobject;
 
 camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.5f,-1,keyMap,4,false,0.f);
 camera->setFarValue(100000);
 camera->setNearValue(1);
 camera->setPosition(core::vector3df(16500,100,6000));
 smgr->setAmbientLight(SColorf(0.25f, 0.25f, 0.25f, 0));
 mainlight=smgr->addLightSceneNode(0, core::vector3df(50000,20000,-50000), video::SColorf(0.5f,0.5f,0.5f,0), 200000.0f);
 
 //Meshes
 mesh[0] = smgr->getMesh("media/map070_with_spec_white_diffuse_a.3ds");
 mesh[1] = smgr->getMesh("media/car001_a.3ds");
 
 // The objects are created and placed
 node[0] = smgr->addAnimatedMeshSceneNode( mesh[0] ); node[0]->setPosition(core::vector3df(0,0,0));
 node[1] = smgr->addAnimatedMeshSceneNode( mesh[1] ); node[1]->setPosition(core::vector3df(16300,0,6000)); node[1]->addShadowVolumeSceneNode();
 nextobject=2;
 smgr->setShadowColor(video::SColor(150,0,0,0));
 
 for (i=0; i<nextobject; i++)
 {
  node[i]->setScale(core::vector3df(1,1,1));
  node[i]->setMaterialFlag(EMF_LIGHTING, true);
  node[i]->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
  node[i]->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
  node[i]->setMaterialType(video::EMT_LIGHTMAP_LIGHTING  );
 }
}
It is supposed to create a scene with the model of a city and a flying car, and let the user fly around. This, it does correctly.
However, the flying car is not lit the way I want it to.

First, I'm going to show you the correct look of the model I want to achieve with Irrlicht. This is how the model appears in Deep Exploration (in case you don't know: it's a program used to view models and the properties of their materials, as well as to modify those properties and convert models from one format to another).
Note the two green exhaust ports, at full brightness.
Image
This is because, from Deep Exploration itself, I provided the model with a diffuse texture and a self-illumination texture.
Here is the diffuse texture:
Image

And here is the self-illumination texture.
Image

I know for a fact that Deep Exploration saves the object correctly, because the self-illumination texture is used when I open the object, either with Deep Exploration itself or 3D Studio Max. However, when I load the model in Irrlicht, the self-illumination texture is completely ignored. Here's how it appears in my program:
Image
The diffuse texture is correct. The specular color is correct. But the exhaust ports are NOT at full brightness! Why is the self-illumination texture ignored? I assumed I could force an object to use a self-illumination texture by setting its material type to EMT_LIGHTMAP_LIGHTING, but evidently it's not the case. I also assumed that "lightmap" means the self-illumination texture. Does it? If it does not, what do I need to change in my code?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How can I force PART of a texture to full brightness?

Post by CuteAlien »

I suspect Irrlicht ignores that part of 3ds (I'm not really familiar with that format).
I would have to experiment myself, but my first guess would be that have to change the emissive color settings in the material.
EMT_LIGHTMAP_LIGHTING is about using lightmaps on top of the texture (so you have 2 textures which are multiplied with each other). Difference to EMT_LIGHTMAP is that it supports also dynamic lighting. But that's not related to self-lighting - that should be about emissive colors.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

Re: How can I force PART of a texture to full brightness?

Post by Devil Master »

CuteAlien wrote:I would have to experiment myself, but my first guess would be that have to change the emissive color settings in the material.
I just discovered that doing so (specifically, changing the emissive color of the material to white) only gives the expected result if I convert the model to .x format. It does not affect the original .3ds model whatsoever.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How can I force PART of a texture to full brightness?

Post by CuteAlien »

That shouldn't depend on the model-format but on the material-type.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

Re: How can I force PART of a texture to full brightness?

Post by Devil Master »

Okay, I took a break from it, and now I tried to tackle the problem again. Here's what is really going on.

- When I save a model to the .3ds format, the emissive color of the material is not saved and defaults to black. Whether I save it from within 3D Studio Max, or I convert a pre-existing model to .3ds with Deep Exploration, it makes no difference. It always happens. The information about the self illumination texture is preserved within the model itself (so the illumination appears correct in both 3D Studio Max and Deep Exploration), but is ignored by Irrlicht.

- When I convert a model to the .x format with Deep Exploration, the emissive color of the material is saved correctly (so, if I make it white, every polygon covered with ANY part of that material's diffuse texture appears at full brightness). What I tried last week only APPEARED to be correct, because that flying car model only uses the part of that texture that I kept in the self illumination texture. The information about the self illumination texture, however, is NOT saved (the only texture name that appears inside the file is the diffuse texture).

EDIT: I googled the specs of the .x format, and they don't mention self illumination textures at all.

EDIT #2: if I convert the model to .lwo, it appears untextured in an Irrlicht program, despite appearing fine in Deep Exploration. Irrlicht even loads the textures (so it says in the command prompt window), they just don't appear on the object itself.

EDIT #3: I see here that Irrlicht has an internal mesh format with the extension .irrmesh. How can I convert a .3ds object to .irrmesh?

EDIT #4: Okay, I found IrrEdit. I converted the car model to .irrmesh, although I had to manually modify the emissive color by editing the obtained .irrmesh file with Notepad, because modifying it from inside IrrEdit had no effect and it was always saved as black. Now, what remains to do is tell IrrEdit to use a particular texture as a self-illumination texture for a particular material. How do I do that?

Solutions?
Last edited by Devil Master on Sat Oct 28, 2017 1:01 am, edited 3 times in total.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How can I force PART of a texture to full brightness?

Post by CuteAlien »

Solution is to make a test-model and debug it. If you send one to me I can maybe try to find some time, but I'm neither familiar with the format nor the loader (this was written way before my time). And always a little tricky for me to really debug that stuff when I don't have the tools to modify the models so I can experiment around.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

Re: How can I force PART of a texture to full brightness?

Post by Devil Master »

CuteAlien wrote:Solution is to make a test-model and debug it. If you send one to me I can maybe try to find some time, but I'm neither familiar with the format nor the loader (this was written way before my time). And always a little tricky for me to really debug that stuff when I don't have the tools to modify the models so I can experiment around.
Okay, I will send you the model I'm experimenting with. What about IrrEdit and self illumination textures?

EDIT: I sent you the model, to the email address you have in your website.

EDIT #2: I converted another, larger .3ds model to .irrmesh (a 2 MB city model, using the same textures as the car). The end result is over 23 MB big, and when I attempt to load it from within my program, the program just freezes, displaying only the command prompt window, until I terminate the process from the Task Manager.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How can I force PART of a texture to full brightness?

Post by CuteAlien »

Sorry, not too much time right now, but I did a quick check and your model looks like this in the Irrlicht meshviewer (example 09):

Image


So probably something about different light-settings. I can take a look at your code in a few days, but maybe just compare with the meshviewer example. It might be about lighting setting in material (just guessing).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

Re: How can I force PART of a texture to full brightness?

Post by Devil Master »

From what I see, it's more lit than it is in my program (due to a stronger light being present), but the green parts are still not at full brightness, and it couldn't be any different, since the model I sent you does not use self-illumination textures. Now I'm gonna send you an alternative version that does, so you can compare them.

EDIT: sent.
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: How can I force PART of a texture to full brightness?

Post by Mel »

What you're asking for is something that actually Irrlitch doesn't support natively, which is to add two textures together, Quake3 maps can achieve this effect because they use their own rendering path, by rendering the texture multiplied by the light maps and then, performing a second pass where it matters with the self-illumination texture. What you can do is this something similar, if you don't want to mess with shaders, which is to duplicate the parts where you want lit textures, use on them the self illumination texture only, and then, on the engine, use an additive blending material. But you will have to use a small positive polygon shift in order to avoid the z-fights that may occur (some flashing triangles that appear when two surfaces are too close one to the other), and disable the Z-writes, i think the engine supports them, as per material parameters.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How can I force PART of a texture to full brightness?

Post by CuteAlien »

Hm, not yet checked new model, but Irrlicht support multiplying 2 materials (all kind of different EMT_LIGHTMAP materials).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

Re: How can I force PART of a texture to full brightness?

Post by Devil Master »

Mel wrote:What you can do is this something similar, if you don't want to mess with shaders, which is to duplicate the parts where you want lit textures, use on them the self illumination texture only, and then, on the engine, use an additive blending material. But you will have to use a small positive polygon shift in order to avoid the z-fights that may occur (some flashing triangles that appear when two surfaces are too close one to the other), and disable the Z-writes, i think the engine supports them, as per material parameters.
In the end, I solved the problem in a slightly different way. Like you wrote, I used one instance of the object for the parts that must react to the lights that surround it, and another for the parts that must always be at full brightness. Unlike you wrote, I didn't disable the Z-write flag, but instead I modified the textures. First, I added an alpha channel to all of them. Then, I took the diffuse textures and removed all the parts that must be displayed at full brightness. From the self-illumination textures, instead, I removed all the parts that used to be black, leaving only the alpha channel. And finally, I changed the material type of all objects to EMT_TRANSPARENT_ALPHA_CHANNEL.

So, the object that must react to environmental lights will have transparent "holes" where the parts that must be at full brightness should be, while the object that must always be at full brightness will be almost completely invisible, EXCEPT for the parts that must be displayed at full brightness!

EDIT:
By adding more objects, I realized that changing the material type to EMT_TRANSPARENT_ALPHA_CHANNEL for all objects would cause problems with the depth buffer, so parts of some objects that needed to be drawn in front of others were drawn behind, and viceversa. I solved the problem by setting all objects that must react to light to EMT_SOLID, and the rest to EMT_TRANSPARENT_ALPHA_CHANNEL.

For reference (for me or whoever else might have this problem) I'll paste the modified function.

Code: Select all

void CreateWorld(void)
{
 unsigned int i;
 unsigned char nextobject;
 
 camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.5f,-1,keyMap,4,false,0.f);
 camera->setFarValue(100000);
 camera->setNearValue(1);
 camera->setPosition(core::vector3df(16500,100,6000));
 smgr->setAmbientLight(SColorf(0.25f, 0.25f, 0.25f, 0));
 mainlight=smgr->addLightSceneNode(0, core::vector3df(50000,20000,-50000), video::SColorf(0.5f,0.5f,0.5f,0), 200000.0f);
 
 // Meshes ("_d" stands for "diffusive" = they react to light and fog;  "_e" stands for "emissive" = always full brightness)
 mesh[0] = smgr->getMesh("media/map070_d.3ds");
 mesh[1] = smgr->getMesh("media/map070_e.3ds");
 mesh[2] = smgr->getMesh("media/car001_d.3ds");
 mesh[3] = smgr->getMesh("media/car001_e.3ds");
 
 // The objects are created and placed
 node[0] = smgr->addAnimatedMeshSceneNode( mesh[0] ); node[0]->setPosition(core::vector3df(0,0,0))
 node[1] = smgr->addAnimatedMeshSceneNode( mesh[1] ); node[1]->setPosition(core::vector3df(0,0,0))
 node[2] = smgr->addAnimatedMeshSceneNode( mesh[2] ); node[2]->setPosition(core::vector3df(16300,0,6000));
 node[3] = smgr->addAnimatedMeshSceneNode( mesh[3] ); node[3]->setPosition(core::vector3df(16300,0,6000));
 
 nextobject=4;
 
 for (i=0; i<nextobject; i++)
 {
  dlScaleObject(i,1,1,1);
  node[i]->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
  node[i]->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
  node[i]->setMaterialFlag(video::EMF_BILINEAR_FILTER, true);
 
  if (i%2==0) // diffusive objects
  {
   node[i]->setMaterialFlag(EMF_LIGHTING, true);
   node[i]->setMaterialFlag(video::EMF_FOG_ENABLE, true);
   node[i]->setMaterialType(video::EMT_SOLID );
  }
  else // emissive objects
  {
   node[i]->setMaterialFlag(EMF_LIGHTING, false);
   node[i]->setMaterialFlag(video::EMF_FOG_ENABLE, false);
   node[i]->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL );
  }
 }
 //Fog
 driver->setFog(video::SColor(0,16,16,16), video::EFT_FOG_EXP, 100, 10000, 0.0003f, true, false);
}
Post Reply