Problem with Lightings

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Problem with Lightings

Post by thomascheah »

Hi,

Sorry for cross posting. I was encountering problems in Irrlicht.NET, and I couldn't get any help there. So I thought that maybe these problems occur in the C++ version.

I am quite new to Irrlicht Engine, and I had been playing around with it for 3 days. I found that there is some annoying bugs regarding the lighting in the engine, such as

1. It seems that the point light settings is a bit weird. I created a cube at (0, 0, 0), and I place a point light at (100, 0, 0) with radius of 50 points. The cube was lit up too much until it is like white for all its six sides. I tried to move the light farther, it seems that the light intensity only looks more realistic as the light are at (5000, 0, 0).

2. I noticed that the ambient color and diffuse color on the object material do not work. No matter what I set, it does not have any effect. Thus, it seems like I have no way to change the color of a geometry. The emissive color works, but that's not something that I want, i.e. emissive color does not react to lights.

Am I the only one that encounter this? I would appreciate if anyone can share their insights on these to me. Thanks in advance.
needforhint
Posts: 322
Joined: Tue Aug 30, 2005 10:34 am
Location: slovakia

Post by needforhint »

hmm... try this tool http://irrlicht.sourceforge.net/phpBB2/ ... =air+scene

you can place lights and change their radius as well as color .

I am curios myself how it wilk work at you
what is this thing...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

It might be good to show some source here, because I think that you aren't doing some things correctly. Sounds as if you have no lighting and texturing at all or something like that.
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

The following is the scene init code that I had created to test out the diffuse material. It is in C#, but it should be readable by a C++ programmer.

Code: Select all

// Create a default camera.
ICameraSceneNode camera = sceneManager.AddCameraSceneNode(null, new Vector3D(0, 0, -100), new Vector3D(0, 0, 0), -1);

// Create a test box.
ISceneNode box = sceneManager.AddTestSceneNode(50, null, -1, new Vector3D());

// Set the test box material.
Material material = new Material();
material.Lighting = true;
material.DiffuseColor = new Color(255, 255, 0, 0);
box.SetMaterial(0, material);

// Add a light source.
ISceneNode light = sceneManager.AddLightSceneNode(null, new Vector3D(100, 0, -100), new Colorf(255, 255, 255), 2.0f, -1);
As you can see, I set the box diffuse color to red. But when I render it, it is still white color, no matter what color I set to. Maybe someone can test out the simple code above in the C++ version and see what's the result. Probably it is a bug in the .NET version.
Last edited by thomascheah on Mon Jul 10, 2006 4:06 pm, edited 1 time in total.
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

More updates...

1. When I tried to create a .X file with diffuse color preset to some color, i.e. red, it is rendered as white in Irrlicht.

2. I tried modified the .X file used by some of the C++ examples that come with the engine, I remove its texture and change its diffuse color to red, when I run C++ example, the object appears as white too. This means that this 'bug' (if confirmed) affects the C++ version as well.

This feature is important to me as I am creating a CAD-like program using this engine. And for initial stage, most of the objects are untextured but merely color coded, i.e. different objects have different colors.

The only workaround I found out now is via IMeshManipulator::setVertexColors(), but I am not sure it is a good idea as to me, mesh manipulator is like modifying the internal mesh data and it might cause performance penalty. I know this can be done easily in DirectX by setting the rendering state.

Any advise would be appreciated. :)
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

This is not a lighting problem. Meshes are rendered using their vertex color, the texture color, or some combination of them both. The material color doesn't appear to be used with any of the default renderers.

You either need to color the vertices, or, if you need to use material color, you might need to create your own IMaterialRenderer. If you are trying to write your own CAD style app, you'll probably need to write a few of these.

Code: Select all

#include <d3d9.h>

//! Solid material renderer
class CD3D9MaterialRenderer_X : public irr::video::IMaterialRenderer
{
public:
	CD3D9MaterialRenderer_X(IDirect3DDevice9* d3ddev, irr::video::IVideoDriver* driver)
		: pID3DDevice(d3ddev), Driver(driver)
	{
	}

	virtual void OnSetMaterial(irr::video::SMaterial& material, const irr::video::SMaterial& lastMaterial,
		bool resetAllRenderstates, irr::video::IMaterialRendererServices* services) 
	{
		if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
		{
			pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
			pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
			pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP,  D3DTOP_DISABLE);

			pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
		}

		pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
		pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

		services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
	}

	virtual void OnUnsetMaterial()
	{
		pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
	}
private:
	IDirect3DDevice9* pID3DDevice;
	irr::video::IVideoDriver* Driver;
};

// and you use it like this...
s32 materialId = driver->addMaterialRenderer(
	new CD3D9MaterialRenderer_X(driver->getExposedVideoData().D3D9.D3DDev9, driver) );

ISceneNode* cube = smgr->addTestSceneNode();
cube->setMaterialFlag(video::EMF_LIGHTING, true);
cube->setMaterialType(video::E_MATERIAL_TYPE(materialId));
cube->getMaterial(0).DiffuseColor = video::SColor(255, 255, 0, 0);
Travis
Last edited by vitek on Tue Jul 11, 2006 5:21 am, edited 1 time in total.
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

Thanks for the great help. I truly appreciate it.

But I thought material color is always used for fixed pipeline rendering? And vertex color is only used if vertex shader is used. Well, I could be wrong. That's based on my understanding on how DirectX works.

On the other hand, what does the diffuse color in Material for if it does not do any good? I know that Emissive color works, and so does specular color and shininess. Isn't that kinda misleading if the diffuse color being part of the Material properties and does not behave similarly to what its "peers" properties?
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I don't know a whole bunch about DirectX or OpenGL, but this is what the D3D documentation says...
D3DRS_COLORVERTEX
TRUE to enable per-vertex color or FALSE to disable it. The default value is TRUE. Enabling per-vertex color allows the system to include the color defined for individual vertices in its lighting calculations.

For more information, see the following render states.

D3DRS_DIFFUSEMATERIALSOURCE
D3DRS_SPECULARMATERIALSOURCE
D3DRS_AMBIENTMATERIALSOURCE
D3DRS_EMISSIVEMATERIALSOURCE

D3DRS_DIFFUSEMATERIALSOURCE
Diffuse color source for lighting calculations. Valid values are members of the D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_COLOR1. The value for this render state is used only if the D3DRS_COLORVERTEX render state is set to TRUE.

D3DRS_SPECULARMATERIALSOURCE
Specular color source for lighting calculations. Valid values are members of the D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_COLOR2.

D3DRS_AMBIENTMATERIALSOURCE
Ambient color source for lighting calculations. Valid values are members of the D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_MATERIAL.

D3DRS_EMISSIVEMATERIALSOURCE
Emissive color source for lighting calculations. Valid values are members of the D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_MATERIAL.
This seems to indicate that the default is for DirectX to use the diffuse and specular vertex color, and the ambient and emissive material color. In order to get the material colors to work, you have to enable them with the above mentioned render states.

If you look at either of the D3D drivers, you'll see that the D3DRS_SPECULARMATERIALSOURCE is set to 3D3MCS_MATERIAL, so only the diffuse color should be coming from the vertex color. Everything else comes from the material.

I have no idea what happens with OpenGL though. I do know that the results of the following test code appear different depending on which driver I use [D3D/OGL]... The ambient color doesn't seem to be coming through on DirectX.

Code: Select all

   // enable a little ambient light
   driver->setAmbientLight(video::SColorf(.3f, .3f, .3f));

  ISceneNode* light = smgr->addLightSceneNode();

  ISceneNodeAnimator* fly = smgr->createFlyCircleAnimator(core::vector3df(0.f, 0.f, 0.f), 30.f);
    light->addAnimator(fly);
  fly->drop();

  ISceneNode* dwarf = smgr->addAnimatedMeshSceneNode(smgr->getMesh("media/dwarf.x"));
  dwarf->getMaterial(0).DiffuseColor = video::SColor(255, 255, 0, 0);
  dwarf->getMaterial(0).AmbientColor = video::SColor(255, 0, 255, 0);
  dwarf->getMaterial(0).EmissiveColor = video::SColor(255, 0, 0, 255);
With OpenGL the lit side is purple and the dark side is blue. With DirectX, the dark side is blue and the lit side is lit white. I consider that to be a bug.

Travis
solehome
Posts: 4
Joined: Wed Aug 23, 2006 3:12 pm

maybe need improvement

Post by solehome »

If you use OpenGL driver, the diffuse color in material will take effect.
But if you use D3D9 driver, the diffuse in material will not.

The reason is that the D3D9 driver always use FVF of (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1) which include a diffuse color declaration for the vertex stream. This causes material setting invalid. It maybe also explains some peoples' problem of "all white", etc. I don't know whether it is a bug. But it is at least a limitation.

If you want to write a mesh loader or custom mesh scenenode, you should pay additional attention to this problem.
ansu832001
Posts: 95
Joined: Thu Mar 01, 2007 6:39 am

Post by ansu832001 »

How can we make this Material Setting Valid ?? i want my Node to retain its color despite light having different color??
Post Reply