irrlicht basic light 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.
Post Reply
jeromebdx
Posts: 8
Joined: Mon Mar 05, 2012 11:41 pm

irrlicht basic light problem

Post by jeromebdx »

Hello eveyone,

I have a problem with light and irrlicht, it's probably a basic problem with normals.
But i didn't solve the problem by myself. I wrote a short source code to illustrate my problem :

Code: Select all

 
// to compile : g++ norm.cpp -lIrrlicht -o norm
 
#include <irrlicht/irrlicht.h>
 
using namespace irr;
 
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
 
// build a basic surface oriented Y
void build_surface(core::array<S3DVertex> &vertices, const vector3df &pos, const vector3df &size)
{
  vector3df up[4] = { irr::core::vector3df(-.5, .5, .5),
    irr::core::vector3df(.5, .5,  .5),
    irr::core::vector3df(.5,  .5, -.5),
    irr::core::vector3df(-.5,  .5, -.5)};
  for(char i=0;i<4;i++)
  {
    vector3df p = up[i] * size + pos;
 
    vertices.push_back(S3DVertex(p,
          vector3df(0, 1, 0),
          SColor(255, 0, 255, 255),
          vector2df(0,0)));
 
  }
}
 
// build a mesh, enable light and normals debug
void build_mesh(ISceneManager* smgr, const vector3df &pos, const vector3df &size)
{
  core::array<S3DVertex> vertices;
  array<u16> indices;
  build_surface(vertices, pos, size);
  indices.push_back( 0 );
  indices.push_back( 1 );
  indices.push_back( 2 );
  indices.push_back( 2 );
  indices.push_back( 3 );
  indices.push_back( 0 );
 
  scene::SMeshBuffer *buf = new scene::SMeshBuffer();
  SMesh *mesh = new SMesh();
  buf->append(vertices.pointer(), vertices.size(), indices.pointer(), indices.size() );
  mesh->addMeshBuffer(buf);
  buf->Material.setFlag(video::EMF_LIGHTING, true);
  buf->drop();
  irr::scene::ISceneNode *node = smgr->addMeshSceneNode(mesh);
  node->setDebugDataVisible(irr::scene::EDS_NORMALS);
}
 
// manage to close this app with the escape key
class EventReceiver_close : public IEventReceiver
{
  private:
    IrrlichtDevice *Device;
  public:
    EventReceiver_close ( IrrlichtDevice *device ): Device ( device ) {}
 
    virtual bool OnEvent(const SEvent& event)
    {
      if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
      {
        if(event.KeyInput.Key == irr::KEY_ESCAPE)
        {
          Device->closeDevice();
          return true;
        }
      }
      return false;
    }
};
 
int main()
{
  IrrlichtDevice *device =
    createDevice( video::EDT_OPENGL, dimension2d<u32>(640, 480), 16,
        false, false, false, 0);
 
  if (!device)
    return 0;
 
  EventReceiver_close receiver(device);
  device->setEventReceiver(&receiver);
 
  device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
  device->getCursorControl()->setVisible(false);
 
  IVideoDriver* driver = device->getVideoDriver();
  ISceneManager* smgr = device->getSceneManager();
  IGUIEnvironment* guienv = device->getGUIEnvironment();
 
  smgr->setAmbientLight(irr::video::SColorf(0.2f, 0.2f, 0.f, 1.0f));
 
  ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS(0, 50, 0.2);
  camera->setPosition(vector3df(0, 20, 0));
  camera->setTarget(vector3df(0,0,0));
 
  // create two mesh with different size,
  // one just nearest other one
  build_mesh(smgr, vector3df(0, 0, 0), vector3df(10, 10, 10));
  build_mesh(smgr, vector3df(0, 0, 10), vector3df(30, 10, 10));
 
  // add a light just top of the surfaces
  smgr->addLightSceneNode( 0, irr::core::vector3df(0, 10, 10), irr::video::SColorf(1.0f, 1.0f, 1.0f), 3.0f, 1 );
  // add a small block in same position of the light to undestand what happen
  smgr->addCubeSceneNode(1, 0, -1, vector3df(0, 10, 10));
 
  while(device->run())
  {
    driver->beginScene(true, true, SColor(255,0,0,0));
 
    smgr->drawAll();
    guienv->drawAll();
 
    driver->endScene();
  }
 
  device->drop();
 
  return 0;
}
 
 
And this is a screenshot of the scene :

Image

So where I am wrong ?

Thanks in advance,

Jérôme
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: irrlicht basic light problem

Post by CuteAlien »

I think what you are seeing is simply what happens when you use gouroud shading. Gouroud shading works by calculating the light for each vertex - and then interpolates that value over the whole surface area. That has some problems in cases like this where your light is just in the center - so all 4 vertices of your large mesh have the same distance to the light - meaning they have all the same color.

If you would split the large one into 3 small ones it would probably look better. Otherwise you have to use more complicated light-calculations (using shaders).

edit: Hint - if you got a free evening some day then spend 1-2 hours on this recently released video from Carmack: http://www.youtube.com/watch?v=MG4QuTe8 ... ture=share
He goes over all the basics of exactly that kind of stuff.
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
jeromebdx
Posts: 8
Joined: Mon Mar 05, 2012 11:41 pm

Re: irrlicht basic light problem

Post by jeromebdx »

well, I understand the problem now,
thanks for you help !

I'll probably invistigate to compute light through shaders.
Post Reply