Light, Euler

Help with the Ecere 3D Graphics Engine: Camera, Mesh, Object, Material, OpenGL integration, etc.
Post Reply
sacrebleu
Posts: 27
Joined: Sun Jan 17, 2010 12:37 pm

Light, Euler

Post by sacrebleu »

Please describe in detail including

Code: Select all

sample code
all of the modes and uses of Light, and all the modes and uses of Euler
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Light, Euler

Post by jerome »

Ok so I will try to explain how to use lights with the Ecere 3D engine. Lights are set on a Display by calling the Display::SetLight method with a Light structure. Let's take a look at the API:

Code: Select all

void SetLight(int id, Light light);
 
public struct Light
{
   LightFlags flags;
   ColorRGB ambient;
   ColorRGB diffuse;
   ColorRGB specular;
   Vector3D direction;
   Quaternion orientation;
   Object lightObject;
   Object target;
   Degrees fallOff;
   Degrees hotSpot;
   float Kc;
   float Kl;
   float Kq;
   Degrees start;
   Degrees end;
   float multiplier;
};
public class LightFlags { public bool off:1, spot:1, omni:1, attenuation:1; }; 
A light can be disabled by setting flags.off to true, but that would require the developer to check flags.off for true and omit to call Display::SetLight.

There are 2 categories of lights. For the simpler one, where lightObject is 'null', only the orientation and the color members (multiplier, diffuse, ambient & specular) are taken into account. It defines a directional light source.

Orientation

Orientations in the 3D engine are usually specified as Quaternion. Read up that wikipedia article to learn about the advantages of quaternions over Euler angles. They include avoiding Gimbal locks (losing a degree of freedom of rotation), and allow for performing spherical linear interpolation. Euler angles are the familiar notion of orientation from 3 components: yaw (rotation around the y-axis), pitch (rotation around the x-axis) and roll (rotation around the z-axis). Ecere makes it to easy to convert from one to the other using eC's conversion properties:

Code: Select all

Quaternion q = Euler { 10, 40, 65 };
Euler e = Quaternion { 0.773, 0.243, 0.252, 0.528 }; 
The default unit for Euler angle components is degrees.

Colors

You can specify how the light source contributes to the lighting model in 3 ways: ambient, diffuse, and specular lighting. Each of these component will react with the material of the objects being drawn accordingly. The 'multiplier' member multiplies all of these 3 components so they can go beyond the 0.0-1.0 range of ColorRGB.

Then you have the more complex model, where lightObject points to an insance of the Object class, which will be marked as a light source in its ObjectFlags (Object::flags.light == true).
In this model the type of light is controlled by the Light::flags property. There are 2 basic types, omnidirectional or spotlight.

Omnidirectional

You can set flags.omni to true, although if flags.spot is not set this is the default.

Here there is two ways you can specify the light's direction, either through a vector, by setting the 'direction' member, or by filling in the 'orientation' member. The vector 'direction' will be used if all of its 3 components (x,y,z) are 0, otherwise it is assumed that 'orientation' will be used. Note that this is not the case at the moment for the 'simple' light (when lightObject is null). The lightObject is actually not very useful in this case, this particular option of setting the 'direction' through a vector is the only thing you cannot do without a lightObject. Ecere should be fixed to also have that option when lightObject is null.

Spotlight

By setting flags.spot = true, lightObject becomes more useful and you can make yourself a spot light. Now you can position your light somewhere using lightObject.transform.position. The light can also be attached to a parent object (e.g. which could have a Mesh) using the Object hierarchy and articulation model, and also benefit from Object animation tracks system. You must also specify a 'target' for the light to point towards, which also is an Object instance.
Note that the UpdateTransform() method must be called after making modifications to the 'transform' property.
Spot lights also have additional parameters to control the angles of the spot: a hotSpot (range - both sides of the center point, in degrees) and a fallOff (also both sides -- so twice the GL_SPOT_CUTOFF). The GL_SPOT_EXPONENT is computed with the formula:

Code: Select all

exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))))
where MAXLIGHT is currently defined to be 0.9.

Attenuation

Attenuation can be enabled for spot lights by setting flags.attenuation to true. It is then controlled by the 3 members Kc, Kl, and Kq, respectively standing for constant, linear and quadratic attenuation. The attenuation formula is f(d) = 1/(C + Ld + Qd^2 where d is the distance between the point being lit and the light source. Attenuation is loaded from 3DS models using the formula:

Code: Select all

light->Kl = 1/(lightEnd*MINLIGHT);
where MINLIGHT is defined to be 0.15.

A quick way to set up both the Light and its Object lightObject together:

Code: Select all

Object specularLight
{
   flags = { light = true; };
   light = 
   {
      multiplier = 1;
      diffuse = white;
      specular = white;
      lightObject = specularLight;
   };
};
It is possible to set multiple lights all at once using the object hierarchy model and Display::SetLights which takes in the scene's root object.

Caveats

Only 8 lights (id 0 through 7) can be used in OpenGL due to OpenGL's limitation of 8 lights.

Note that at one point calling Display::SetLight before or after the Display::SetCamera had different behavior, whether the light positioning is relative to the viewer's orientation and position or not. I do not remember if that was changed. I noticed that in the Test3DS and ColorSpheres it is set AFTER the camera, whereas in the other smaples it is set before. It would be worthwhile to test if both before and after give the same result, and whether lightObject vs/ no light object changes that behavior.

Another major confusion is which sign to give the light vector's z component or which orientation to use to be going behind the screen or coming out of the screen. That remains to be clarified.

Note that the support for all these nice Light properties are working well in OpenGL, but lacking in the Direct3D 8/9 drivers. Contributions to finalize its implementation are welcome.



Find attached 3 samples using light sources in Ecere.

OpenGL lighting: http://linux.die.net/man/3/gllight
Direct3D 9 lighting: http://msdn.microsoft.com/en-us/library ... S.85).aspx, http://msdn.microsoft.com/en-us/library ... S.85).aspx
Attachments
Animate3DS.ec
(2.23 KiB) Downloaded 1436 times
colorSpheres.ec
(5.5 KiB) Downloaded 1429 times
Test3D.ec
(1.96 KiB) Downloaded 1405 times
Post Reply