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.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Lighting problem

Post by mongoose7 »

I'd never heard of it but
One of the vertices in an output primitive is designated the "provoking vertex". This vertex has special meanings for the primitive. For example, when using flat-shading on output variables, only outputs from the provoking vertex are used; every fragment generated by that primitive gets it's input from the output of the provoking vertex.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Lighting problem

Post by CuteAlien »

I also didn't know. But explains this I guess.
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 all the suggestions so far.

I'm not sure about the 'provoking vertex' though, as the problem persists with Gouraud shading on.

I've gone back a bit to a previous example, and simplified it. Gouraud shading is on.

The code:

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, 640), 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(60,150,60), core::vector3df(60,0,60));
     
  auto topLight = smgr->addLightSceneNode(nullptr,
                          core::vector3df(60, 50, 60),  
                          video::SColorf(0.1f, 0.1f, 0.1f),
                          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);
     
  // 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(120.f, 0.0f, 120.0f),
                                                    normal, color,
                                                    irr::core::vector2df(6.f, 0.0f)));
     
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(120.f, 0.0f, 0.f),
                                                    normal, color,
                                                    irr::core::vector2df(6.f, 3.f)));
     
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(0.0f, 0.0f, 0.f),
                                                    normal, color,
                                                    irr::core::vector2df(0.0f, 3.f)));
     
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(0.0f, 0.0f, 120.0f),
                                                    normal, color,
                                                    irr::core::vector2df(0.0f, 0.0f)));
     
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(34.f, 0.0f, 104.f),
                                                    normal, color,
                                                    irr::core::vector2df(1.f, 1.f)));
     
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(57.f, 0.0f, 104.f),
                                                    normal, color,
                                                    irr::core::vector2df(2.f, 1.f)));
     
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(34.f, 0.0f, 90.f),
                                                    normal, color,
                                                    irr::core::vector2df(1.f, 1.f)));
     
  buffer->Vertices.push_back(irr::video::S3DVertex(irr::core::vector3df(57.f, 0.0f, 90.f),
                                                    normal, color,
                                                    irr::core::vector2df(2.f, 1.f)));
     
  // 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);
    /*
    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;
}
     
     
 

And then the result in a screen capture:

http://screencast.com/t/Is3cgZ3sbaN

As you can see, one area is very brightly lit, while the large right-top triangle does not seem to capture much light at all.

Thanks again for all your help so far. I appreciate it a lot.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Lighting problem

Post by mongoose7 »

You've probably missed the point that, even with gouraud shading on, the lighting is still only computed at the vertices. The video generally looks OK to me.
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

OK, so a solution would be to replace the larger triangles with smaller ones?
Or are there certain other settings that render it more evenly?
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Lighting problem

Post by mongoose7 »

If you want flat shading, then subdivision is your only course of action. Err, though the rendering will not really be flat as the different triangles representing the subdivision will each have a different colour. I think you need to evaluate why you want flat shading and what variations are acceptable. The model in the OP does not really show the reason for flat shading as each triangle would be shaded differently anyway. I note that shaders will not help as you will still have the provoking vertex problem. And the vertex shader does not have access to the other vertices of the primitive.
DavidHT
Posts: 10
Joined: Tue Apr 12, 2016 2:41 pm

Re: Lighting problem

Post by DavidHT »

I don't want flat shading. I switched off Gouraud shading (and thus implying flat shading?) to try to make the issue more apparent.
I want the whole thing to be naturally lit, without the dark areas along the edges of the larger triangles.
Originally, EMF_GOURAUD_SHADING was set to true.
As you can see here:
http://screencast.com/t/TOl38Hh6R

This strangely does not result in the area directly under the light to be the brightest, and it shows all sorts of dark areas along the edges.
What I'm looking for is just a lighting where the brightness depends on the distance from the lamp to the surface, and the angle with the surface. Per pixel I suppose?

The fact that the (flat) area is composed of a set of triangles as displayed, much like a jigsaw, is a given, and can't be changed. I can perhaps subdivide larger triangles.

By the way, thanks for looking at this!
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Lighting problem

Post by mongoose7 »

Well, if you want per-pixel lighting, you can set the material type to NORMAL_MAP or PARALLAX_MAP but you will have to texture it. Otherwise, subdivide the triangles.
Post Reply