Canvas 3d JS Library

WebGL made easy!
  • rss
  • What is C3DL?
  • Download
  • Tutorials
    • Tutorial #1: WebGL Browsers
    • Tutorial #2: A simple scene
    • Tutorial #3: Callback
    • Tutorial #4: Models
    • Tutorial #5: Light effects
    • Tutorial #6: Picking
    • Tutorial #7: Materials
    • Tutorial #8: Particle Systems
    • Tutorial #9: Camera Basics
    • Tutorial #10: Advanced FreeCamera
    • Tutorial #11: OrbitCamera
    • Tutorial #12: Advanced Camera Functions
  • Development News
  • Documentation
  • Community
  • Resources
  • Contact
  • About

Lights!

Andor Salga | 18 January, 2009 | 18:47
Check out my cool light demo!

This blog is about lights and the new light classes we’ll be adding to the library for the next release. I’ll get right to it: OpenGL implementations provide access to light states which can add realism to a scene. Like most other rendering API’s, OpenGL approximates the results of lights, since calculating the real effects would require too many calculations (at least for our purposes). Lighting is important for adding realism to a scene just as real light is important for depth perception. Two eyes give us depth perception, however, if you close one eye, everything is still 3D! One major reason for this is because of light.

For the Unenlightened

For anyone who has never played with lights in OpenGL, it can cause quite a bit of confusion. Keep the following points in mind as you work with the lights:

Lights cannot be seen. They do not have a physical representation like a floating light bulb or a point. Nor do they have a ‘beam’ which can be seen. Placing a model into the scene to indicate where light is coming from is of course possible, but the API won’t do it for you.

Lights cannot cast shadows. The technique of adding shadows to a scene is surprisingly a totally separate topic and can get computationally expensive. If shadows are desired, it is left up to the user to create them.

Lights need to light something. If there aren’t any objects in the scene, there won’t be anything for the light to light up. So make sure you have a model (which has normals) and make sure the model is close enough to the light to get lit. This is especially true if you decide to adjust the attenuation of a light.

Lights go through objects! If you place a light directly in front of object A, and object B is behind object A, B will still get lit. It may seem silly, but OpenGL will not automatically figure out that light should not affect B.

The only way a light is ‘seen’ is through its effects. If you haven’t already run the demo, now would be a good time. Even with these strange quirks, lights are definitely worth adding to your scene.

Separating the Spectrum

OpenGL architects decided to separate lights into three components so they are easier to define and work with. These components are ambient, diffuse and specular. Each component has an associated color, which allows us to create interesting effects not possible in real life. This includes using a single light to illuminate an object with a red diffuse component and green highlights.

I won’t cover everything there is to know about lights since someone already did that, but I will cover some basics so one can get a basic grasp of the concepts.

Ambient Light

Ambient light does not have a direction or position, but seems to come from everywhere. If only using ambient light, all objects in the scene would be lit evenly. Assigning an ambient component to a light can seem strange since lights typically tend to attenuate. The functionality is simply provided because OpenGL supports it. Generally, users should use scene.setAmbientLight(array) to place ambient light in the scene.

Upon first glance it may seem that some parts of the duck are lit brighter than others, such as its wing. This is merely the work of the artist who created the texture to create the illusion of a non-flat surface. Focus your attention on the duck’s bill or most of its body and you will see it is a solid color. Compare this with the screenshot with the diffuse lighting.

Diffuse Light

Diffuse light is what most people associate with what light is. Diffuse gives shape to the object, making it appear 3D. Diffuse lighting is dependent on the light’s position relative to the object. If you were looking at the object directly and the light was behind it, you would likely not see the effects.

Specular Light

Specular lighting is used to create shiny highlights. Highlights are typically seen on objects such as glass, metal or plastic and are usually white. Although in order to use specular highlights one must change an object’s material (this I’ll save for another blog). Unlike ambient and diffuse light, specular light takes not only the objects position into account, but also the viewer’s position. When running the demo, notice that the shiny highlights seem to always ‘point’ to you. This mimics the real world where shiny objects have highlights which seem to follow your eyes.

New Light Classes

Initially we provided simple wrapper functions around the OpenGL light state changing commands. However the interface was, among other things, awkward to work with. The new classes will (hopefully) be much more intuitive. With the new classes defined, the light manager is no longer needed. We have also added name members, providing the option to assign names and then later request the scene for a light by name. So, here are the new classes:

Light

This is an ‘abstract class’ which exists only to serve as a base for PositionalLight and DirectionalLight. It is not meant to be instantiated, therefore if anyone knows how to prevent instantiation, I would be glad to hear it. Otherwise I’m left with two options. Option 1, tell users not to instantiate it, or 2: remove it and duplicate the code for DirectionalLight and PositionalLight.

PositionalLight

Inherits from Light and adds a position accessors and attenuation factor accessros. This means the light actually has a position in space and can be attenuated. Depending on the position and attenuation, the light may or may not affect objects in your scene.

DirectionalLight

Inherits from Light. It does not have a position, only a direction. Directional light does not attenuate which is why it inherits from Light and not PositionalLight. It will light one s’ide’ of all the objects in your scene. Think of the light as being infinitely far away, having parallel rays.

SpotLight

Inherits from PositionalLight. Along with having a position, a spotlight also has members such as cutoff and direction. Cutoff is a value which refers to the angle where the spotlight’s cone ‘stops’. This value is specified from the middle of the cone of light to the ‘end’. Therefore if a spotlight with a total of 90 degrees is desired, spot.setCutoff(45) is called. As with OpenGL, the cutoff can range from 0 to 90 inclusive or have a value of 180, in which case it is essentially a positional light. The direction of the spotlight is simply where it is pointing and is specified with a vector.

Light CRUD

Creating a light

//Create a positional light with a red diffuse component. var light = new c3dl.PositionalLight(); light.setName('posLight'); light.setPosition([30,0,0]); light.setDiffuse([1,0,0,1]); // scene needs to have the light and by default lights are off. light.setOn(true); scn.addLight(light);

Reading and Updating a light

// change the diffuse color of a light on keypress. var light = scene.getLight('posLight'); // swap the diffuse components on keypress. if(light.getDiffuse()[0] == 1) { light.setDiffuse([0,0,1,1]); } else { light.setDiffuse([1,0,0,1]); }

Delete the light

// posLight will no longer contribute to the scene. scene.removeLight('posLight');

Trade offs

Since we will no longer be providing a direct wrapper, some flexibility is lost. For example, when using lights with OpenGL directly, you change light states with gl.light(…). You can start off with a point light and if you want, you can change a state variable and make it a spot light. Using our new classes, the only way this can be done is if the members are copied over from a positional light to a spot light. Since the library is intended for users generally not familiar with 3d concepts, this trade off is justified with separate lights

Lights Out

Lights can be used to increase the realism of a scene, but they can also adversely affect the realism if used incorrectly. For example, if a scene contained a skybox textured with buildings, we would not want lights illuminating the skybox. Otherwise it destroy the skybox illusion. Therefore before rendering a skybox, all lights should be turned off. In the C3DL, this is done by automatically. Before rendering the SkyModel, all lights are turned off. The same idea applies to particle systems. Particle textures are prelit and should not need additional lighting.

Next Steps

Adding materials to objects must be done in order to define which colors are absorbed and reflected.

All the lighting calculations must be done ourselves for the 2.0 context. So I’ll somehow have to squeeze this into my todo list.

ES Issues

It took a while to get specular lighting to work. I set the material state to FRONT, but there was no change. Took a bit of investigation and I found out to use materials, they have to be assigned to both FONT_AND_BACK facing polygons. This seems to be an OpenGLES specific issue.

Categories
c3dl development
Comments rss
Comments rss

« New Front Page Artwork Texture Bug »

Leave a comment

You can use these tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Videos

Demos

  • Asteroids-3D
  • RTS Prototype
  • Particle Systems Demo
  • Cross-Browser Orbiter
  • Mocap Demo With Spheres
  • Google Maps-3D

C3DL Development News

A spec change that keeps coming back to haunt me

At some point, the way firefox handles keyboard events changed. I’m not sure exactly when it happened, all I know is that it broke how I was dealing with keyboard interaction on almost every demo I’ve written (for example,the mocap demo and MotionView). When I wrote the demos, the keydown event would be fired once, [...]

Release 2.2

The 2.2 Release of the Canvas 3D Library includes a number of new features, updates to old features and fixes for several bugs along with the requisite changes to meet the evolving WebGL spec. Some of the things included (in no particular order) are: Better picking code. The ability to swap textures as a scene [...]

Tutorials

  • Tutorial #1: WebGL Browsers
  • Tutorial #2: A simple scene
  • Tutorial #3: Callback
  • Tutorial #4: Models
  • Tutorial #5: Light effects
  • Tutorial #6: Picking
  • Tutorial #7: Materials
  • Tutorial #8: Particle Systems
  • Tutorial #9: Camera Basics
    • Tutorial9-YawPitchRoll
  • Tutorial #10: Advanced FreeCamera
  • Tutorial #11: OrbitCamera
  • Tutorial #12: Advanced Camera Functions

Documentation

Archives

Archives

C3DL Development News

Recent Comments

  • June 2011
  • March 2011
  • October 2010
  • July 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • A spec change that keeps coming back to haunt me
  • Release 2.2
  • 2.1 Release and things to come
  • Level Up! An Open Web Game Jam
  • Site moved!
  • SceneCreator0.3
  • WWW2010 in Raleigh
  • Motionview
  • On the train to Mountainview
  • C3DL 2.0-WebGL and beyond
  • That depends on what... - peter
  • This application is ... - Haisens
  • I think that example... - peter
  • The above links are ... - Atash
  • Hi there, just wante... - Patrick H. Lauke
  • Firefox 4 was releas... - Cathy Leung
  • In order to access l... - peter
  • I am not able to dis... - preksha
  • "JavaScript can’t di... - Joe Hocking
  • I should point out t... - peter



Canvas 3d JS Library

©2007- 2010 Canvas 3d JS Library

Disclaimer: This website is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 Canada License.
The Canvas 3d JS Library and Demos found on this website are licenced under the MIT License

Creative Commons License