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.
Lighting problem
Re: Lighting problem
I'd never heard of it but
Re: Lighting problem
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
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Lighting problem
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:
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.
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.
Re: Lighting problem
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.
Re: Lighting problem
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?
Or are there certain other settings that render it more evenly?
Re: Lighting problem
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.
Re: Lighting problem
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!
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!
Re: Lighting problem
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.