Lighting problem

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.
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Lighting problem

Post by DavidHT »

Dear all. I've been using Irrlicht for quite a while, but now I am baffled by a thing I cannot explain. I think it should be simple, hence I put it in the Beginners help.

I'm working on generating a 'landscape' on a rectangular area, think of a table.
Here is a picture of my problem case:
Image

All vertices are on the same 'height', and the scene is dynamically lit from above by one LightSceneNode placed in the center over the table.
Each triangle has the same 1x1 pixel texture: green.
All normals are up and normalized.
I switched on debug data as you can see for the wireframe and the normals.
I switched off Gouraud shading (as you can see, causing the sharp edges).

To my surprise, the triangles are lit in a different way, as if the normals are off. But for the 8 vertices they all have length 1.0, pointing upwards.

When I turn the LightSceneNode brightness to the max: SColorf(1.0f, 1.0f, 1.0f), all triangles get the same green color. The same with full ambient light.

Could any of you think of an easy explanation?

Thanks in advance for any suggestion.

David.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Lighting problem

Post by CuteAlien »

What happens when you increase the radius? Maybe it just is as large to hit those in the center. Thought not sure why one wouldbe a little less bright then.
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
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

Thanks for the quick reply!

The radius is large enough I think (5 * (height above the table + length + width of the table)). So according to Pythagoras, it should hit everything within 1/5th of its range.
So that can't be the issue.

Just now I've experimented moving the light a bit further away. This reduces the effect, but it's still there.

Indeed, the weird thing is that one of the triangles is less bright, and not for a logical reason like being further away from the light source.
I've played with Attenuation as well, but this doesn't make a difference.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Lighting problem

Post by mongoose7 »

Try changing the attenuation. I'm guessing your scene is quite large.
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Lighting problem

Post by Mel »

Your problem are the normals not being correctly aligned. It is not an obvious problem, but happens when you pick all the normals of an object and try to put them looking towards the same direction. Actually, everything should be of a single color. But the atenuation makes for the rest of the tonalities. I'd generate a series of vertices on a quad pattern and would "sew" triangles on them (it is not a hard task you just have to do it well for it to look correct). The hillplane mesh may generate for you such a mesh, for instance, just provide it a single color heightmap, it is only a mesh after you create it and then you may manipulate it (I don't mean the GeoMipMap terrain, i mean the hillplane mesh primitive) You can just move the vertices and all. Word of advice though, it is just logic to believe the normals of a terrain point all "up" but it is not correct, they must be perpendicular to the triangle they belong to and thus, some extra manipulation is needed, so far, i think the mesh manipulator (from the scene manager) is capable of regenerating the normals, so give it a try. Luck! :)
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

@Mongoose: Thanks for the suggestion. I tried, but it makes no difference.

@Mel: All the vertices are on the same plain, so no 'hills'. All have Y==0. All normals have X==Z==0, and Y==1.
Here is a list of the vertices and indices of the mesh (taken from the debugger, Visual Studio 2015):
Vertices:

Code: Select all

 
-       [0] irr::video::S3DVertex
+       Pos {X=121.919998 Y=0.000000000 Z=-0.000000000 }    irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=6.09600019 Y=0.000000000 }   irr::core::vector2d<float>
-       [1] irr::video::S3DVertex
+       Pos {X=121.919998 Y=0.000000000 Z=-60.9599991 } irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=6.09600019 Y=3.04800010 }    irr::core::vector2d<float>
-       [2] irr::video::S3DVertex
+       Pos {X=0.000000000 Y=0.000000000 Z=-60.9599991 }    irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=0.000000000 Y=3.04800010 }   irr::core::vector2d<float>
-       [3] irr::video::S3DVertex
+       Pos {X=0.000000000 Y=0.000000000 Z=-0.000000000 }   irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=0.000000000 Y=0.000000000 }  irr::core::vector2d<float>
-       [4]     irr::video::S3DVertex
+       Pos {X=34.3258286 Y=0.000000000 Z=-26.0343609 } irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=1.71629155 Y=1.30171800 }    irr::core::vector2d<float>
-       [5] irr::video::S3DVertex
+       Pos {X=57.3258286 Y=0.000000000 Z=-26.0343609 } irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=2.86629152 Y=1.30171800 }    irr::core::vector2d<float>
-       [6] irr::video::S3DVertex
+       Pos {X=34.3258286 Y=0.000000000 Z=-30.0573101 } irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=1.71629155 Y=1.50286555 }    irr::core::vector2d<float>
-       [7] irr::video::S3DVertex
+       Pos {X=57.3258286 Y=0.000000000 Z=-30.0573101 } irr::core::vector3d<float>
+       Normal  {X=0.000000000 Y=1.00000000 Z=0.000000000 } irr::core::vector3d<float>
+       Color   {color=4294967295 } irr::video::SColor
+       TCoords {X=2.86629152 Y=1.50286555 }    irr::core::vector2d<float>
 
Indices:

Code: Select all

 
{0, 1, 2, 2, 3, 4, 5, 4, 3, 2, 4, 6, 5, 3, 0, 2, 6, 7, 7, 5, 0, 0, 2, 7, 4, 5, 7, 7, 6, 4}
 
Note: the texture used is a 1x1 pixel green bmp.


I will try to make a single program to reproduce this.

Thanks for the help so far. Still suggestions are very welcome :)

David.
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

Hi All.

I've adjusted one of the Irrlicht samples to reproduce the problem.


Image


Here's the full code:

Code: Select all

 
#include <irrlicht.h>
 
using namespace irr;
 
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
 
 
/// Class to create a 1 pixel BMP in memory
class CSingleColorBitmap {
public:
CSingleColorBitmap(int r, int g, int b) {
  unsigned char bmpInit[58] = {0x42, 0x4d, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
                               0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
                               0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00,
                               0x4d, 0x48, 0xf0, 0x00 };
 
  (void) memcpy(bmp_, bmpInit, 58);
 
  bmp_[54] = (unsigned char)b;
  bmp_[55] = (unsigned char)g;
  bmp_[56] = (unsigned char)r;
}
void* Data() const {
  return (void*)bmp_;
}
int Size() const {
  return 58;
}
 
private:
unsigned char bmp_[58];
};
 
 
 
int main()
{
    auto driverType = video::E_DRIVER_TYPE::EDT_OPENGL;
    // create device
 
    auto device = createDevice(driverType,
            core::dimension2d<u32>(640, 480), 16, false);
        
    if (device == nullptr)
        return 1; // could not create driver.
 
 
    device->setWindowCaption(L"Lighting issues");
 
    auto driver = device->getVideoDriver();
    auto smgr = device->getSceneManager();
 
    smgr->addCameraSceneNode(nullptr, core::vector3df(60,100,-30), core::vector3df(60,0,-30));
 
  auto topLight = smgr->addLightSceneNode(nullptr, 
                          core::vector3df(60, 50, -30),  
                          video::SColorf(0.05f, 0.05f, 0.05f), 
                          1000);
 
  smgr->setAmbientLight(video::SColorf(0.0f, 0.0f, 0.0f));
 
  auto normal = irr::core::vector3df(0.0, 1.0, 0.0);
  auto color = irr::video::SColor(255, 255, 255, 255);
 
  // Create a mesh.
  auto mesh = new irr::scene::SMesh();
  auto buffer = new irr::scene::SMeshBuffer();
  mesh->addMeshBuffer(buffer);
  buffer->drop();
 
  // Add vertices
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(121.919998f, 0.0f, 0.0f),
                                                   normal, color,
                                                   irr::core::vector2df(6.09600019f, 0.0f)));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(121.919998f, 0.0f, -60.9599991f),
                                                   normal, color,
                                                   irr::core::vector2df(6.09600019f, 3.04800010f)));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(0.0f, 0.0f, -60.9599991f),
                                                   normal, color,
                                                   irr::core::vector2df(0.0f, 3.04800010f)));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(0.0f, 0.0f, 0.0f),
                                                   normal, color,
                                                   irr::core::vector2df(0.0f, 0.0f)));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(34.3258286f, 0.0f, -26.0343609f),
                                                   normal, color,
                                                   irr::core::vector2df(1.71629155f, 1.30171800f)));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(57.3258286f, 0.0f, -26.0343609f),
                                                   normal, color,
                                                   irr::core::vector2df(2.86629152f, 1.30171800f)));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(34.3258286f, 0.0f, -30.0573101f),
                                                   normal, color,
                                                   irr::core::vector2df(1.71629155f, 1.50286555f)));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(57.3258286f, 0.0f, -30.0573101f),
                                                   normal, color,
                                                   irr::core::vector2df(2.86629152f, 1.50286555f)));
 
  // Add triangles
 
  buffer->Indices.push_back(0);
  buffer->Indices.push_back(1);
  buffer->Indices.push_back(2);
 
  buffer->Indices.push_back(2);
  buffer->Indices.push_back(3);
  buffer->Indices.push_back(4);
 
  buffer->Indices.push_back(5);
  buffer->Indices.push_back(4);
  buffer->Indices.push_back(3);
 
  buffer->Indices.push_back(2);
  buffer->Indices.push_back(4);
  buffer->Indices.push_back(6);
 
  buffer->Indices.push_back(5);
  buffer->Indices.push_back(3);
  buffer->Indices.push_back(0);
 
  buffer->Indices.push_back(2);
  buffer->Indices.push_back(6);
  buffer->Indices.push_back(7);
 
  buffer->Indices.push_back(7);
  buffer->Indices.push_back(5);
  buffer->Indices.push_back(0);
 
  buffer->Indices.push_back(0);
  buffer->Indices.push_back(2);
  buffer->Indices.push_back(7);
 
  buffer->Indices.push_back(4);
  buffer->Indices.push_back(5);
  buffer->Indices.push_back(7);
 
  buffer->Indices.push_back(7);
  buffer->Indices.push_back(6);
  buffer->Indices.push_back(4);
 
  buffer->recalculateBoundingBox();
  mesh->recalculateBoundingBox();
 
  irr::scene::IMeshSceneNode* node(smgr->addMeshSceneNode(mesh));
 
  auto bitmap = CSingleColorBitmap(0, 255, 0);
 
  irr::io::IReadFile* textureFile(device->getFileSystem()->createMemoryReadFile(bitmap.Data(), bitmap.Size(), "bitmap"));
  irr::video::ITexture* texture(device->getVideoDriver()->getTexture(textureFile));
  textureFile->drop();
 
  node->setMaterialTexture(0, texture);
  node->setMaterialFlag(irr::video::EMF_GOURAUD_SHADING, false);
 
  node->setDebugDataVisible(irr::scene::EDS_MESH_WIRE_OVERLAY);
    /*
    Now draw everything and finish.
    */
    u32 frames=0;
    while(device->run())
    {
        driver->beginScene(true, true, video::SColor(0,100,100,100));
 
        smgr->drawAll();
 
        driver->endScene();
        if (++frames==100)
        {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += L"] FPS: ";
            str += (s32)driver->getFPS();
 
            device->setWindowCaption(str.c_str());
            frames=0;
        }
    }
 
    device->drop();
    
    return 0;
}
 
 

If anyone knows why the triangles are lighted so differently, or even how to solve it :) , I'd be so happy!

David.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Lighting problem

Post by CuteAlien »

Yeah, you don't even need textures. I've modified it a little to allow playing around with the light-position (and make it visible). Very confusing...
I suspect it has something to do with the light being rather dark and not reaching everything. If you make very bright or turn up radius a lot it becomes evenly. But the way it changes... I don't get it yet.

Code: Select all

 
#include <irrlicht.h>
 
using namespace irr;
 
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
 
class MyEventReceiver : public IEventReceiver
{
public:
    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_KEY_INPUT_EVENT && node)
        {
            if ( event.KeyInput.PressedDown )
            {
                switch ( event.KeyInput.Key )
                {
                    case KEY_UP:    node->setPosition(node->getPosition() + core::vector3df(0, 0, 10)); break;
                    case KEY_DOWN:  node->setPosition(node->getPosition() + core::vector3df(0, 0, -10)); break;
                    case KEY_LEFT:  node->setPosition(node->getPosition() + core::vector3df(-10, 0, 0)); break;
                    case KEY_RIGHT: node->setPosition(node->getPosition() + core::vector3df(10, 0, 0)); break;
                    default:
                        break;
                }
            }
        }
 
        return false;
    }
    irr::scene::ISceneNode * node = nullptr;
};
 
int main()
{
    auto driverType = video::E_DRIVER_TYPE::EDT_OPENGL;
    // create device
 
    auto device = createDevice(driverType,
            core::dimension2d<u32>(640, 480), 16, false);
       
    if (device == nullptr)
        return 1; // could not create driver.
    
    MyEventReceiver receiver;
    device->setEventReceiver(&receiver);
 
    auto driver = device->getVideoDriver();
    auto smgr = device->getSceneManager();
 
    core::vector3df camPos(60,200,-30);
    core::vector3df camTarget(60,0,-30);
 
    irr::scene::ICameraSceneNode * cam;
//  irr::scene::ICameraSceneNode * cam = smgr->addCameraSceneNodeFPS();
//  cam->setPosition(camPos);
//  cam->setTarget(camTarget);
    cam = smgr->addCameraSceneNode(nullptr, camPos, camTarget);
    cam->setUpVector(core::vector3df(0, 0, 1));
 
    auto topLight = smgr->addLightSceneNode(nullptr,
                          core::vector3df(100, 150, -30),  
                          video::SColorf(0.1f, 0.1f, 0.1f),
                          1500);
    receiver.node = topLight;   
  
    irr::scene::ISceneNode * bb = smgr->addBillboardSceneNode(topLight, core::dimension2d<f32>(5, 5));
    bb->setMaterialFlag(video::EMF_LIGHTING, false);
  
 
    smgr->setAmbientLight(video::SColorf(0.f, 0.0f, 0.0f));
 
    auto normal = irr::core::vector3df(0.0, 1.0, 0.0);
    auto color = irr::video::SColor(255, 255, 127, 128);
 
    // Create a mesh.
    auto mesh = new irr::scene::SMesh();
    auto buffer = new irr::scene::SMeshBuffer();
    mesh->addMeshBuffer(buffer);
    buffer->drop();
 
    // Add vertices
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(121.919998f, 0.0f, 0.0f),
                                                   normal, color,
                                                   irr::core::vector2df(6.09600019f, 0.0f)));
 
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(121.919998f, 0.0f, -60.9599991f),
                                                   normal, color,
                                                   irr::core::vector2df(6.09600019f, 3.04800010f)));
 
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(0.0f, 0.0f, -60.9599991f),
                                                   normal, color,
                                                   irr::core::vector2df(0.0f, 3.04800010f)));
 
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(0.0f, 0.0f, 0.0f),
                                                   normal, color,
                                                   irr::core::vector2df(0.0f, 0.0f)));
 
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(34.3258286f, 0.0f, -26.0343609f),
                                                   normal, color,
                                                   irr::core::vector2df(1.71629155f, 1.30171800f)));
 
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(57.3258286f, 0.0f, -26.0343609f),
                                                   normal, color,
                                                   irr::core::vector2df(2.86629152f, 1.30171800f)));
 
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(34.3258286f, 0.0f, -30.0573101f),
                                                   normal, color,
                                                   irr::core::vector2df(1.71629155f, 1.50286555f)));
 
    buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(57.3258286f, 0.0f, -30.0573101f),
                                                   normal, color,
                                                   irr::core::vector2df(2.86629152f, 1.50286555f)));
 
    // Add triangles
 
    buffer->Indices.push_back(0);
    buffer->Indices.push_back(1);
    buffer->Indices.push_back(2);
 
    buffer->Indices.push_back(2);
    buffer->Indices.push_back(3);
    buffer->Indices.push_back(4);
 
    buffer->Indices.push_back(5);
    buffer->Indices.push_back(4);
    buffer->Indices.push_back(3);
 
    buffer->Indices.push_back(2);
    buffer->Indices.push_back(4);
    buffer->Indices.push_back(6);
 
    buffer->Indices.push_back(5);
    buffer->Indices.push_back(3);
    buffer->Indices.push_back(0);
 
    buffer->Indices.push_back(2);
    buffer->Indices.push_back(6);
    buffer->Indices.push_back(7);
 
    buffer->Indices.push_back(7);
    buffer->Indices.push_back(5);
    buffer->Indices.push_back(0);
 
    buffer->Indices.push_back(0);
    buffer->Indices.push_back(2);
    buffer->Indices.push_back(7);
 
    buffer->Indices.push_back(4);
    buffer->Indices.push_back(5);
    buffer->Indices.push_back(7);
 
    buffer->Indices.push_back(7);
    buffer->Indices.push_back(6);
    buffer->Indices.push_back(4); 
 
    buffer->recalculateBoundingBox();
    mesh->recalculateBoundingBox();
 
    irr::scene::IMeshSceneNode* node = smgr->addMeshSceneNode(mesh);
    node->setMaterialFlag(irr::video::EMF_GOURAUD_SHADING, false);
    node->setDebugDataVisible(irr::scene::EDS_MESH_WIRE_OVERLAY|irr::scene::EDS_NORMALS );
    /*
    Now draw everything and finish.
    */
    while(device->run())
    {
        driver->beginScene(true, true, video::SColor(0,100,100,100));
 
        smgr->drawAll();
 
        driver->endScene();
    }
 
    device->drop();
   
    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
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

Thanks, it looks like we're getting somewhere.

I've simplified it further. Just two triangles.

Moving the light to the left and right of the scene seems to work as expected.
Moving it up or down the scene, it seems the wrong triangle gets most of the light.

Code: Select all

 
#include <irrlicht.h>
 
using namespace irr;
 
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
 
 
 
class MyEventReceiver : public IEventReceiver
{
public:
    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_KEY_INPUT_EVENT && node)
        {
            if ( event.KeyInput.PressedDown )
            {
                switch ( event.KeyInput.Key )
                {
                    case KEY_UP:    node->setPosition(node->getPosition() + core::vector3df(10, 0, 0)); break;
                    case KEY_DOWN:  node->setPosition(node->getPosition() + core::vector3df(-10, 0, 0)); break;
                    case KEY_LEFT:  node->setPosition(node->getPosition() + core::vector3df(0, 0, 10)); break;
                    case KEY_RIGHT: node->setPosition(node->getPosition() + core::vector3df(0, 0, -10)); break;
                    default:
                        break;
                }
            }
        }
 
        return false;
    }
    irr::scene::ISceneNode * node = nullptr;
};
 
 
int main()
{
    auto driverType = video::E_DRIVER_TYPE::EDT_OPENGL;
    // create device
 
    auto device = createDevice(driverType,
            core::dimension2d<u32>(640, 480), 16, false);
        
    if (device == nullptr)
        return 1; // could not create driver.
 
  MyEventReceiver receiver;
  device->setEventReceiver(&receiver);
 
    device->setWindowCaption(L"Lighting issues");
 
    auto driver = device->getVideoDriver();
    auto smgr = device->getSceneManager();
 
    smgr->addCameraSceneNode(nullptr, core::vector3df(40,100,40), core::vector3df(40,0,40));
 
  auto topLight = smgr->addLightSceneNode(nullptr, 
                          core::vector3df(40, 50, 40),  
                          video::SColorf(0.05f, 0.05f, 0.05f), 
                          1000);
 
 receiver.node = topLight;   
 
  auto bb = smgr->addBillboardSceneNode(topLight, core::dimension2d<f32>(5, 5));
  bb->setMaterialFlag(video::EMF_LIGHTING, false);
 
  smgr->setAmbientLight(video::SColorf(0.0f, 0.0f, 0.0f));
 
  auto normal = irr::core::vector3df(0.0, 1.0, 0.0);
  auto color = irr::video::SColor(255, 255, 255, 255);
  auto tcoord = irr::core::vector2df(0.0, 0.0);
  // Create a mesh.
  auto mesh = new irr::scene::SMesh();
  auto buffer = new irr::scene::SMeshBuffer();
  mesh->addMeshBuffer(buffer);
  buffer->drop();
 
  // Add vertices
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(30.f, 0.0f, 30.f),
                                                   normal, color, tcoord));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(50.f, 0.0f, 30.f),
                                                   normal, color, tcoord));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(30.f, 0.0f, 50.f),
                                                   normal, color, tcoord));
 
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(50.f, 0.0f, 50.f),
                                                   normal, color, tcoord));
 
  // Add triangles
  buffer->Indices.push_back(0);
  buffer->Indices.push_back(3);
  buffer->Indices.push_back(1);
 
  buffer->Indices.push_back(3);
  buffer->Indices.push_back(0);
  buffer->Indices.push_back(2);
 
  buffer->recalculateBoundingBox();
  mesh->recalculateBoundingBox();
 
  auto node(smgr->addMeshSceneNode(mesh));
 
  node->setMaterialFlag(irr::video::EMF_GOURAUD_SHADING, false);
 
  node->setDebugDataVisible(irr::scene::EDS_MESH_WIRE_OVERLAY);
    /*
    Now draw everything and finish.
    */
    u32 frames=0;
    while (device->run())
    {
        driver->beginScene(true, true, video::SColor(0,100,100,100));
 
        smgr->drawAll();
 
        driver->endScene();
        if (++frames==100)
        {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += L"] FPS: ";
            str += (s32)driver->getFPS();
 
            device->setWindowCaption(str.c_str());
            frames=0;
        }
    }
 
    device->drop();
    
    return 0;
}
 
David.
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

I've tried to investigate this further, but so far I'm not sure why the lighting is so uneven.
If anyone has an idea, I would be interested to hear about it.

As a workaround, I've moved the lights a bit further away so the effect is less obvious.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Lighting problem

Post by mongoose7 »

Lighting is calculated at the vertices, not over the face. Maybe this has misled you? Maybe you could post an image?
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

Here's a video capture of what happens when moving the light (indicated by the white billboard).
http://screencast.com/t/uSPRQpcQanYe

The strange thing is that when the light is at the top or the bottom, the wrong triangle is brighter.
When moved to the left or the right, the expected result is displayed.
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Lighting problem

Post by thanhle »

Hi Try this link
http://irrlicht.sourceforge.net/forum/v ... de#p292138

It might have the solution to the question you asked.

smgr->getMeshManipulator()->recalculateNormals()

Your assumption the normal in the y direction is not correct. The normal are results of cross product of two vectors.

Cheers
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Lighting problem

Post by mongoose7 »

What! The normals *are* correct.

But there is a lot that is mysterious. For example, your light is very dark (.05, .05, .05) and yet the triangles are very bright! I tried changing the attenuation and the light direction (I know, it's a point light!). Setting the attenuation to (1, 0, 0) seems to give the correct level of light, but doesn't remove the strange behaviour.

But removing the line:
node->setMaterialFlag(irr::video::EMF_GOURAUD_SHADING, false);
actually fixes the behaviour, though the triangles are no longer flat-shaded.

EDIT: I think I've got it! Flat shading uses only one vertex. Suppose (50, 0, 50) is chosen for the triangle (30, 0, 30) (50, 0, 30) (50, 0, 50) and (30, 0, 30) for the triangle (30, 0, 30) (30, 0, 50) (50, 0, 50). Then, if the light moves to large X-values, the first triangle gets lighter (OK - it has X-values 30, 50, 50) and the opposite if the light moves to low X-values. If the light moves to high Z-values, the first triangle gets lighter EVEN THOUGH is has the small Z-values (30, 30, 50).
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Lighting problem

Post by hendu »

Indeed, the provoking vertex thing.
Post Reply