Light Oversaturation
Light Oversaturation
I'm trying to get a point light to illuminate my scene correctly. However, the light is oversaturated on the lit side. So that the vertices are either super bright, or not lit at all.
There spheres each have 512 triangles so there should be a smooth gradient. And you should see some color difference between the top and side faces of the boxes.
I manually inspected the .obj normals and the look like they have a unit length (1.0).
If I lower the radius (10000.0f -> 400.0f), then it appears to improve the smoothness of the lighting. But why is the radius affecting the light intensity?
If I reduce the radius, then the light won't affect all the objects in my final scene. So I need a high Radius, but don't want it affecting the brightness of the scene.
If I switch to a directional light, then it appears I lose the shadows (which are the main reason I'm investigating Irrlicht as a rendering solution).
Source:
There spheres each have 512 triangles so there should be a smooth gradient. And you should see some color difference between the top and side faces of the boxes.
I manually inspected the .obj normals and the look like they have a unit length (1.0).
If I lower the radius (10000.0f -> 400.0f), then it appears to improve the smoothness of the lighting. But why is the radius affecting the light intensity?
If I reduce the radius, then the light won't affect all the objects in my final scene. So I need a high Radius, but don't want it affecting the brightness of the scene.
If I switch to a directional light, then it appears I lose the shadows (which are the main reason I'm investigating Irrlicht as a rendering solution).
Source:
are your normals normalized? if they have a length of anything other than 1.0 then you'll have lighting problems.
you can either recalculate them with the mesh manipulator, or if you want to keep their direction you can set the normalize normals SMaterial flag and let the hardware fix them.
If that's not the problem, perhaps you can post the contents of the MTL file here
you can either recalculate them with the mesh manipulator, or if you want to keep their direction you can set the normalize normals SMaterial flag and let the hardware fix them.
If that's not the problem, perhaps you can post the contents of the MTL file here
Yeap.bitplane wrote:are your normals normalized? if they have a length of anything other than 1.0 then you'll have lighting problems.
you can either recalculate them with the mesh manipulator, or if you want to keep their direction you can set the normalize normals SMaterial flag and let the hardware fix them.
If that's not the problem, perhaps you can post the contents of the MTL file here
Looking deeper at the issue, I found this chunk of code (same for D3D8 and OpenGL).I manually inspected the .obj normals and the look like they have a unit length (1.0).
Code: Select all
void CD3D9Driver::addDynamicLight(const SLight& dl)
{
if ((u32)LastSetLight == Caps.MaxActiveLights-1)
return;
CNullDriver::addDynamicLight(dl);
D3DLIGHT9 light;
if ( dl.Type == ELT_POINT )
{
light.Type = D3DLIGHT_POINT;
light.Position = *(D3DVECTOR*)((void*)(&dl.Position));
}
else
if ( dl.Type == ELT_DIRECTIONAL )
{
light.Type = D3DLIGHT_DIRECTIONAL;
light.Direction = *(D3DVECTOR*)((void*)(&dl.Position));
}
light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor));
light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor));
light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor));
light.Range = MaxLightDistance;
light.Attenuation0 = 0.0f;
light.Attenuation1 = 1.0f / dl.Radius;
light.Attenuation2 = 0.0f;
++LastSetLight;
pID3DDevice->SetLight(LastSetLight, &light);
pID3DDevice->LightEnable(LastSetLight, true);
}
For light attenuation values k0 k1 k2, the attenuation calculation is:
attenuation = 1.0 / (k0 + k1 * d + k2 * d^2)
So here's what happening.
blue - Constant attenuation.
purple - What's happening now. Instead of the light fading to black at the Radius, it's actually causing the light near the source become super brightened.
yellow - Closer to what I anticipated the system would work, fading from 1 near the source to 0 at the Radius.
Would it be possible to expose the attenuation values through the SLight structure? I don't know if the current setup is the intended lighting, but it would be nice to be able to override it so I can get the lighting I'm after.
That's cool. I look forward to the next release.
I would have expected default values of
Those are the system defaults (atleast for OpenGL) and most commonly used values.
Here's what my scene looks like after I changed the attenuation to those values and recompiled the Irrlicht.dll. The difference is pretty significant and how I expected the lighting to work.
I would have expected default values of
Code: Select all
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f;
light.Attenuation2 = 0.0f;
Here's what my scene looks like after I changed the attenuation to those values and recompiled the Irrlicht.dll. The difference is pretty significant and how I expected the lighting to work.
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
I'll check for default values in D3D then. My impression when I first saw those numbers (the default values are probably ever since...) was that these are better suited for interactive scenes where you can walk through. Since the light intensity does not change with the default values it's not realistic then!?
Oh great, I have the same problem, but I thought that is vertex shaders problem.
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=18856
I'll try your hint later
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=18856
I'll try your hint later
The DirectX SDK says "Typically, an application sets Attenuation0 to 0.0, Attenuation1 to a constant value, and Attenuation2 to 0.0."hybrid wrote:I'll check for default values in D3D then. My impression when I first saw those numbers (the default values are probably ever since...) was that these are better suited for interactive scenes where you can walk through. Since the light intensity does not change with the default values it's not realistic then!?
The DirectX SDK was smart by not giving a specific number as a default. If you tried putting in a specific default for Atten1 or Atten2, then the lighting for a scene will be completely different depending on what game units they use (meters, cm, mm, feet, inches, etc). The "constant value" they mention for Attenuation1 will always be application specific.
I think using the OpenGL defaults (1,0,0) is the smartest choice. It will work consistently for all cases regardless of world units/scale. And if someone wants the attenuation to work in a specific way then they can always override the default values.
hey... can you send me the dll? i am having this problem too.
I am not a typical programmer (i am artist) so i can't change the value myself.
by the way another question: is it suitable to call the primitives as no. of triangles? what it usually call? no. of primitives?
Before adding a light source...
After added the light source... ahh! Not looking good...
I am not a typical programmer (i am artist) so i can't change the value myself.
by the way another question: is it suitable to call the primitives as no. of triangles? what it usually call? no. of primitives?
Before adding a light source...
After added the light source... ahh! Not looking good...
Possible solution
I've met the same problem and made the following changes.
1. New member to SLight class
vector3df Attenuation;//defaults (0.f,0.f,0.f) in constructor
2. Adding appropriate attribute serialize/deserialize methods in CLightSceneNode class
3. Modification of light attenuation logic in drivers' classes (CD3D8Driver.cpp, CD3D9Driver.cpp, COpenGLDriver.cpp, CSoftwareDriver2.cpp) to the following:
By default the changes above doesn't affect existing Irrlich attenuation logic. If someone wants he may setup Attenuation member via ILightSceneNode::setLightData() to get standard OpenGL/Direct3D behavior.
1. New member to SLight class
vector3df Attenuation;//defaults (0.f,0.f,0.f) in constructor
2. Adding appropriate attribute serialize/deserialize methods in CLightSceneNode class
3. Modification of light attenuation logic in drivers' classes (CD3D8Driver.cpp, CD3D9Driver.cpp, COpenGLDriver.cpp, CSoftwareDriver2.cpp) to the following:
Code: Select all
if (light.Attenuation.getLength()==0)
{
//use native Irrlicht attenuation
}
else
{
//use standard OpenGL/Direct3D attenuation factor 1/(a0+a1*d+a2*d^2), where
//a0 = light.Attenuation.X
//a1 = light.Attenuation.Y
//a2 = light.Attenuation.Z
}
-
- Posts: 95
- Joined: Thu Mar 01, 2007 6:39 am
Hi All,
Iam facing problem with lighting,my nodes(which are of different color from Light)are getting effected,i.e whenever i enable light their actual color is getting effected by color of light.
If iam not wrong this can be done setting Attenuation to default values as said by "nullterm",if so i tried doing that but could not find as where we can set this Attenuation
i already have a thread here http://irrlichtnetcp.sourceforge.net/ph ... .php?t=790
since this lighting problem is generic i am posting here aswell.
Best Regards
Iam facing problem with lighting,my nodes(which are of different color from Light)are getting effected,i.e whenever i enable light their actual color is getting effected by color of light.
If iam not wrong this can be done setting Attenuation to default values as said by "nullterm",if so i tried doing that but could not find as where we can set this Attenuation
i already have a thread here http://irrlichtnetcp.sourceforge.net/ph ... .php?t=790
since this lighting problem is generic i am posting here aswell.
Best Regards
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
The attenuation is set in the drivers. Up to Irrlicht 1.3.1 this was fixed and you could only change it to some new fixed values by recompiling Irrlicht.
The next Irrlicht version will have an attenuation vector in the SLight data which allows for dynamic changes of the values. You can try it in the SVN version of Irrlicht, but probably not with Irrlicht.CP.
The next Irrlicht version will have an attenuation vector in the SLight data which allows for dynamic changes of the values. You can try it in the SVN version of Irrlicht, but probably not with Irrlicht.CP.