Page 1 of 1

Problem with Lightings

Posted: Mon Jul 10, 2006 5:59 am
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.

Posted: Mon Jul 10, 2006 12:23 pm
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

Posted: Mon Jul 10, 2006 12:40 pm
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.

Posted: Mon Jul 10, 2006 3:49 pm
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.

Posted: Mon Jul 10, 2006 3:55 pm
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. :)

Posted: Mon Jul 10, 2006 5:06 pm
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

Posted: Tue Jul 11, 2006 3:39 am
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?

Posted: Tue Jul 11, 2006 5:50 am
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

maybe need improvement

Posted: Tue Sep 05, 2006 2:24 pm
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.

Posted: Fri Jul 13, 2007 12:31 pm
by ansu832001
How can we make this Material Setting Valid ?? i want my Node to retain its color despite light having different color??