Spot light rotation and positioning

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
poddaa
Posts: 1
Joined: Sat Dec 06, 2025 8:49 am
Location: Poland

Spot light rotation and positioning

Post by poddaa »

I've been trying to do something like flashlight for 3 days now, but was unable to correctly change position and direction of spot light.
SLight.Direction changes with rotation and position but visually nothing happens.
I'm using OpenGL renderer and i have mesh with tangents and normal maps for per-pixel lighting, but i don't think it really matters in this case.

Already tried:
Setting light node position and rotation, did literally nothing.
Giving light node a parent and playing between transoforming parent and light node, started doing something, but i couldn't get control on moving it as i wanted to.
Setting ligh nodes parent as camera, setting light.position = rotation kinda worked but origin of light was (i think) at 0, 0, 0.
Adding rotation animator to light node or parent node, nothing even moved.
And many more of playing with vectors, setting position, rotation, switching around with parents, updating abolute position, forcing doLightRecalc and many things i don't even remember.

Also using debug flags to show it do nothing, but i don't know if im using them right, i've just set light->setDebugDataVisible(EDS_FULL).
I was thinking of writing my own light shader now but i thought i'll ask forum first.

Thank you in advance.
CuteAlien
Admin
Posts: 9927
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Spot light rotation and positioning

Post by CuteAlien »

You have to set the light data for your node, so assuming spotlight is an ILightSceneNode it's something like:

Code: Select all

spotlight->getLightData().Type = irr::video::ELT_POINT;
spotlight->getLightData().OuterCone = 90.f;
spotlight->getLightData().Falloff = 1.f;
Also make sure your target material hasn't turned off lighting. Also GouraudShading shouldn't be turned off (or it becomes ugly). And because this is vertex based stuff your target needs to have enough polygons.

You can take a look at https://github.com/mzeilfelder/irr-play ... _scene.cpp which is slightly modified version of something I wrote based on a bugreport from Elevations here (viewtopic.php?p=308069). Just copy it over some Irrlicht example and it should compile I think (at least with svn trunk).
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
Noiecity
Posts: 317
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Spot light rotation and positioning

Post by Noiecity »

Make sure you have normalized the 3D models you import...

Code: Select all

"...we need to normalize the normals to make the lighting on it correct..."
https://irrlicht.sourceforge.io/docu/example008.html

Code: Select all

anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
I did some tests, in many ways and I can't create a spotlight or directional light if I use normalmaps, I don't know if it's a conceptual error from what I see but it seems that it considers it "pointlight".
When you disable normalmaps it works correctly... I don't know if I'm loading the normalmaps correctly, I barely notice their effect sometimes

I don't think it takes ambient light either (although you can configure a large radius pointlight to simulate it).

I also noticed that if your normalmap is very strong, the light practically loses its effect.

Code: Select all

driver->makeNormalMapTexture(normal, 1.0f);
(the test:)
https://drive.google.com/file/d/19m1w3c ... sp=sharing

Code: Select all

// example_spot_normalmap.cpp
#include <irrlicht.h>
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
using namespace irr;

int main()
{
    // create device
    IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
        core::dimension2d<u32>(512,512), 16, false, false, false, 0);
    if(!device) return 1;

    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    gui::IGUIEnvironment* guienv = device->getGUIEnvironment();
	driver->setTextureCreationFlag(video::ETCF_OPTIMIZED_FOR_QUALITY, true);
    const char* meshFile = "../../media/brickstone2_lp.obj";     
    scene::IAnimatedMesh* mesh = smgr->getMesh(meshFile);
    if (!mesh) {
        guienv->addStaticText(L"Could not load mesh. Change the name in the code.",
            core::rect<s32>(10,10,600,40), true);
    } else {
        scene::IMesh* tangMesh = smgr->getMeshManipulator()->createMeshWithTangents(mesh->getMesh(0));
        scene::IMeshSceneNode* node = smgr->addMeshSceneNode(tangMesh);
        

        node->setPosition(core::vector3df(0,0,0)); // at the origin
        node->setScale(core::vector3df(1,1,1));
        node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);

        node->setMaterialType(video::EMT_NORMAL_MAP_SOLID);
        video::ITexture* diffuse = driver->getTexture("../../media/albedo_brick2.jpg");
        video::ITexture* normal  = driver->getTexture("../../media/rustic_stone_wall_nor_gl_4k.jpg");  
		driver->makeNormalMapTexture(normal, 1.0f);
        node->setMaterialTexture(0, diffuse);
        node->setMaterialTexture(1, normal);
        node->setScale(core::vector3df(15.0f, 15.0f, 15.0f));
        node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
		node->getMaterial(0).DiffuseColor = video::SColor(255, 255, 255, 255); 
        
		tangMesh->drop(); 
    }

	smgr->loadScene("../../media/ambientlight.irr");

    scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.01f);
	camera->setFOV(90.0f*core::DEGTORAD);
	camera->setPosition(core::vector3df(0.0f, 5.0f, 0.0f));
    while(device->run())
    {
        if (device->isWindowActive())
        {
            driver->beginScene(true, true, video::SColor(255,100,101,140));
            smgr->drawAll();
            guienv->drawAll();
            driver->endScene();
        }
    }

    device->drop();
    return 0;
}
(changing the rotation in the main loop or the direction it points to didn't work for me, but it did work if I declared it before the main loop, hmmm... I didn't try this without the normalmaps)
Image

edit: okay, I think the problem is the normalmap that I added, so my problem may not be replicable in other cases

I noticed that unlike a image viewer, show the textures "desaturated" and as if they had a lot of brightness and little contrast... so I edited the texture with gimp: I reduced the resolution with a cubic filter to 1024x1024 -> I duplicated the layer, I assigned multiply mode to the layer, right click and merge down to merge, I raised the saturation, increased the contrast and the brightness(since multiplying reduces it), this is the result without normalmaps and the spotlight:
Image
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, for free. CC0 man.

Image
**
Post Reply