Inconsistant lighting in simple scene

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
deathbydeltabot
Posts: 6
Joined: Fri Oct 14, 2022 10:08 pm

Inconsistant lighting in simple scene

Post by deathbydeltabot »

Hi, I am having a problem where half of a square is being lit differently than the other half. I'm not sure where to start tracking this down. Moving around the scene there are positions where everything looks okay then others like in the screenshot below is not great. I am using revision 6438 from svn on Windows. Any ideas what I am doing wrong? Thanks
Here's the model: https://drive.google.com/file/d/1SjWGw2 ... sp=sharing
Image

Code: Select all

#include <irrlicht.h>

int main(int argc, char* argv[])
{
	irr::IrrlichtDevice* dev =  irr::createDevice(irr::video::EDT_OPENGL);

	irr::scene::IAnimatedMesh* mesh = dev->getSceneManager()->getMesh("Test.dae");
	irr::scene::IAnimatedMeshSceneNode* node = dev->getSceneManager()->addAnimatedMeshSceneNode(mesh);
	node->setDebugDataVisible(irr::scene::EDS_NORMALS);

	irr::scene::ICameraSceneNode* cam = dev->getSceneManager()->addCameraSceneNodeFPS(nullptr, 100, 0.01f);
	cam->setPosition(irr::core::vector3df(0, 1.75, 0));

	irr::scene::ILightSceneNode* light = dev->getSceneManager()->addLightSceneNode(cam, irr::core::vector3df(0,0,0), irr::video::SColorf(1,1,1), 10);

	while (dev->run())
	{
		dev->getVideoDriver()->beginScene();
		dev->getSceneManager()->drawAll();
		dev->getVideoDriver()->endScene();
	}

	return 0;
}
CuteAlien
Admin
Posts: 9679
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Inconsistant lighting in simple scene

Post by CuteAlien »

Hm, putting light directly into the camera is interesting - I'm not quite sure if that is a good idea. Really never tried.

But in theory you are not doing anything wrong. Vertex lighting simply isn't good and has lots of cases where you wonder if something is broken. Games using it use all kind of tricks to make it work. Like placing several lights. And adding a bit of ambient light to avoid the super dark places (and sometimes to give "mood" to a scene by coloring it somewhat). Also using more polygons will make vertex light use better - so 2 triangles for a flat area looks worse than more triangles (unlike pixel lighting where you want to reduce polygons as much as possible).

If you need better lighting there is no way around using pixel shaders Which calculate the light per pixel instead of calculating it per vertex and then average over the pixels. Irrlicht comes with some simple ones, like EMT_NORMAL_MAP_SOLID, but you need to convert your mesh to use EVT_TANGENTS vertex type. Unfortunately I've also not worked yet much with that one and trying to convert your example to use that gave strange results. Maybe the normalmap I created is not going straight up as I expect? Would have to invest a bit more time I fear, but currently already working on another bug and a bit short on time, so can't help more today (and next week probably even worse...). So, experiment!

Code: Select all

#include <irrlicht.h>

int main(int argc, char* argv[])
{
	irr::IrrlichtDevice* dev =  irr::createDevice(irr::video::EDT_OPENGL);

	irr::scene::IAnimatedMesh* mesh = dev->getSceneManager()->getMesh("Test.dae");
        // convert to mesh which can be used with build-in pixel shaders
	irr::scene::IMesh* meshT = dev->getSceneManager()->getMeshManipulator()->createMeshWithTangents(mesh->getMesh(0));
	irr::scene::IMeshSceneNode* node = dev->getSceneManager()->addMeshSceneNode(meshT);
	node->setDebugDataVisible(irr::scene::EDS_NORMALS);

	// Trying to create a dummy normalmap where all values just go up
	irr::video::IImage* imgNormals = dev->getVideoDriver()->createImage(irr::video::ECF_A8R8G8B8, irr::core::dimension2du(2,2));
	imgNormals->fill(irr::video::SColor(255,255,255,255));
	irr::video::ITexture* normalMap = dev->getVideoDriver()->addTexture("normalMap", imgNormals);
	imgNormals->drop();

	node->getMaterial(0).setTexture(1, normalMap);
	node->getMaterial(0).MaterialType = irr::video::EMT_NORMAL_MAP_SOLID;

	irr::scene::ICameraSceneNode* cam = dev->getSceneManager()->addCameraSceneNodeFPS(nullptr, 100, 0.01f);
	cam->setPosition(irr::core::vector3df(0, 1.75, 0));

	// moved it a up a bit in case camera and light exact same pos is the problem - but that wasn't it
	irr::scene::ILightSceneNode* light = dev->getSceneManager()->addLightSceneNode(cam, irr::core::vector3df(0,20,0), irr::video::SColorf(1,1,1), 150);

	while (dev->run())
	{
		dev->getVideoDriver()->beginScene();
		dev->getSceneManager()->drawAll();
		dev->getVideoDriver()->endScene();
	}

	return 0;
}
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
deathbydeltabot
Posts: 6
Joined: Fri Oct 14, 2022 10:08 pm

Re: Inconsistant lighting in simple scene

Post by deathbydeltabot »

Thanks for the input, I will poke around. I don't have D3D SDK installed so I can't try D3D9 right now but it's interesting that Burning's renderer does not show this issue.
deathbydeltabot
Posts: 6
Joined: Fri Oct 14, 2022 10:08 pm

Re: Inconsistant lighting in simple scene

Post by deathbydeltabot »

D3D9 gave the same result. I played with the code you provided and I am also seeing weirdness but it's also kind of similar to the issues I am getting with vertex shading. It's shading one side differently than the other....
CuteAlien
Admin
Posts: 9679
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Inconsistant lighting in simple scene

Post by CuteAlien »

My guess would be those pixl shaders also do some of the calculations per vertex. Bit hard for me to read quickly (they are written in asm and not in hlsl/glsl with which I'm a bit more familiar), but on first view it looks like the D3D pixel shader solution has 2 options, so it might work better.

Notice that for vertex shading it's probably correct to see some weirdness for this case. Because your quad is not identical from each corner. For that you would need to use 4 triangles which meet in the middle instead of just 2 triangles. But for a good pixel shader that shouldn't matter.

edit: Thought on further test - it shouldn't behave as it does with the pixel shader. It should have opposite diagonal corners behave the same.
edit2: Also shouldn't behave as it does with the vertex shader, OK guess I have to investigate a bit.
edit3: Seems to be 2 independent problems. Something about model (exporting same as obj in Blender it behaves different). And one with pixelshader (messed up always with my code - guess I do something worng)
edit4: Reason obj is different is because obj files have gouraud shading enabled. While this .dae file disables it by using "lambert" as technique. So - it will look better if it uses "phong" or "blinn" instead. Or enabled gouraud in the material directly.
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
CuteAlien
Admin
Posts: 9679
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Inconsistant lighting in simple scene

Post by CuteAlien »

Phew, OK - edit4 in previous post is basically the reason for all the mess. And I should have known as I remember now I struggled with a near identical problem once before.

In old times (before people wrote their own shaders) there had been 2 shading models - flat and gouraud. Now in theory that would not be that bad, because flat just means independent of camera I think (so just caring about sun position). But unfortunately back then people decided that "flat" is the "fast" solution and there is this super hack to make it even faster. So what they did was not use an average to all 3 vertices of a polygon (or more than 3 as back then people didn't just use triangles...), but simply 1 vertex! For triangles the first one. So that's the one deciding the brightness when you have gouraud disabled. Good enough approximation back then if the light was far away and the polygons were small enough. Makes no sense whatsoever these days usually.

But well, this is what seems to be used for "lambert" in Collada files. Because there is no way to say - calculate lambert, but at least use all vertices for old style non-shader code.

Now, the other problem - why do our pixel shaders also use only first vertex (as they obviously do)? Answer is I guess - because they were written back in Irrlicht 0.8 which was around the time computers were made out of wood and stones and powered by water mills. Or something like that. Anyway, the reason is likely again, back then PC's were slow and this was ... for speed!!!

Anyway to fix: Never disable gouraud shading. Or enable it if your format disabled it. And ... get someone to rewrite the Irrlicht shaders (which are written in some kind of asm no one alive still knows, so maybe time to kick out low level shaders?).
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
deathbydeltabot
Posts: 6
Joined: Fri Oct 14, 2022 10:08 pm

Re: Inconsistant lighting in simple scene

Post by deathbydeltabot »

Oh man that was it!!! Thank you so much, my level looks SO much better.

Where are these shaders stored? I know nothing about the old shader assembly but it sounds interesting. Would it make sense for Irrlicht to force gouraud whenever lighting is enabled or is there still a use case for the current behavior?

Thanks again for your help!
CuteAlien
Admin
Posts: 9679
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Inconsistant lighting in simple scene

Post by CuteAlien »

The assembler shaders are in files like COpenGLNormalMapRenderer.cpp and CD3D9NormalMapRender.cpp.
About forcing gouraud - I wondered the same earlier. Don't really know if that still has a use. I mean it kinda interprets the Collada setting correct, I'm just not sure if anyone still deliberately sets it like that.
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
deathbydeltabot
Posts: 6
Joined: Fri Oct 14, 2022 10:08 pm

Re: Inconsistant lighting in simple scene

Post by deathbydeltabot »

I am using Crocotile3D and the only option I have is "Lambert" and "Phong". I don't know how that makes it into the Collada file exactly. I'd never heard of Lambert before so I don't know how that differs Gouraud, I need to do more research. Maybe some kind of warning that Lambert doesn't work properly?
CuteAlien
Admin
Posts: 9679
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Inconsistant lighting in simple scene

Post by CuteAlien »

It kinda works as it should. It's just not something that makes that much sense anymore with modern cards. But maybe people might still want it for stylistic reasons.
Use phong - Irrlicht uses gouraud for it right now. No real phong yet (that's what I hoped the pixel shader would do - difference is that it should be calculated per fragment/pixel).
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
CuteAlien
Admin
Posts: 9679
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Inconsistant lighting in simple scene

Post by CuteAlien »

Can't figure out why the fragment shader in the normal map renderer does not get interpolated vertex values but only those from the prime vertex. From all the info I found so far it should already work. So if by any chance someone reading this has a clue why opengl or d3d9 assembly does not interpolate our light attenuation values, please inform me. Maybe we're just missing something simple?
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
deathbydeltabot
Posts: 6
Joined: Fri Oct 14, 2022 10:08 pm

Re: Inconsistant lighting in simple scene

Post by deathbydeltabot »

I finally had chance to dig into the GouraudShading flag. In OpenGL, it results in a toggle between glShadeModel(GL_SMOOTH) and glShadeModel(GL_FLAT). So it's not a shader program thing fortunately!
Post Reply