Class Light
- java.lang.Object
-
- org.jzy3d.plot3d.rendering.lights.Light
-
public class Light extends Object
Adds light to a scene which allows shading theGeometry
's colors according to the angle between the light and theGeometry
, which is required to perceive the volume of an object. You do not instantiate a light but rather invokeChart.addLight(Coord3d)
orChart.addLightOnCamera()
which return a light instance. A chart can deal with up to 8 lights, which can be switched on or off with :Light light = chart.getScene().getLightSet().get(0); // light ID in [0;7] light.setEnabled(false);
The important thing to do is to allow a drawable to reflect light, which requires to compute its normals. This is achieved by
Geometry.setReflectLight(boolean)
, which is false by default to avoid processing normals for the majority of chart that do not require lighting.Then you can tune both the light colors and the drawable reflection colors. The below documentation are taken from the GL Red Book documentation and a great website for learning OpenGL (see references below).
Light effect on coloring
Light settings
- Ambient illumination is light that's been scattered so much by the environment that its direction is impossible to determine - it seems to come from all directions. Backlighting in a room has a large ambient component, since most of the light that reaches your eye has first bounced off many surfaces. A spotlight outdoors has a tiny ambient component; most of the light travels in the same direction, and since you're outdoors, very little of the light reaches your eye after bouncing off other objects. When ambient light strikes a surface, it's scattered equally in all directions.
- The diffuse component is the light that comes from one direction, so it's brighter if it comes squarely down on a surface than if it barely glances off the surface. Once it hits a surface, however, it's scattered equally in all directions, so it appears equally bright, no matter where the eye is located. Any light coming from a particular position or direction probably has a diffuse component.
- Finally, specular light comes from a particular direction, and it tends to bounce off the surface in a preferred direction. A well-collimated laser beam bouncing off a high-quality mirror produces almost 100 percent specular reflection. Shiny metal or plastic has a high specular component, and chalk or carpet has almost none. You can think of specularity as shininess.
Object material settings
The OpenGL lighting model makes the approximation that a material's color depends on the percentages of the incoming red, green, and blue light it reflects. For example, a perfectly red ball reflects all the incoming red light and absorbs all the green and blue light that strikes it. If you view such a ball in white light (composed of equal amounts of red, green, and blue light), all the red is reflected, and you see a red ball. If the ball is viewed in pure red light, it also appears to be red. If, however, the red ball is viewed in pure green light, it appears black (all the green is absorbed, and there's no incoming red, so no light is reflected).
Like lights, materials have different ambient, diffuse, and specular colors, which determine the ambient, diffuse, and specular reflectances of the material. A material's ambient reflectance is combined with the ambient component of each incoming light source, the diffuse reflectance with the light's diffuse component, and similarly for the specular reflectance and component. Ambient and diffuse reflectances define the color of the material and are typically similar if not identical. Specular reflectance is usually white or gray, so that specular highlights end up being the color of the light source's specular intensity. If you think of a white light shining on a shiny red plastic sphere, most of the sphere appears red, but the shiny highlight is white.
In addition to ambient, diffuse, and specular colors, materials have an emissive color, which simulates light originating from an object. In the OpenGL lighting model, the emissive color of a surface adds intensity to the object, but is unaffected by any light sources. Also, the emissive color does not introduce any additional light into the overall scene.
RGB Values for Lights and Materials
The color components specified for lights mean something different than for materials. For a light, the numbers correspond to a percentage of full intensity for each color. If the R, G, and B values for a light's color are all 1.0, the light is the brightest possible white. If the values are 0.5, the color is still white, but only at half intensity, so it appears gray. If R=G=1 and B=0 (full red and green with no blue), the light appears yellow.
For materials, the numbers correspond to the reflected proportions of those colors. So if R=1, G=0.5, and B=0 for a material, that material reflects all the incoming red light, half the incoming green, and none of the incoming blue light. In other words, if an OpenGL light has components (LR, LG, LB), and a material has corresponding components (MR, MG, MB), then, ignoring all other reflectivity effects, the light that arrives at the eye is given by (LR*MR, LG*MG, LB*MB).
Similarly, if you have two lights that send (R1, G1, B1) and (R2, G2, B2) to the eye, OpenGL adds the components, giving (R1+R2, G1+G2, B1+B2). If any of the sums are greater than 1 (corresponding to a color brighter than the equipment can display), the component is clamped to 1.
Light type
As previously mentioned, you can choose whether to have a light source that's treated as though it's located infinitely far away from the scene or one that's nearer to the scene. The first type is referred to as a directional light source; the effect of an infinite location is that the rays of light can be considered parallel by the time they reach an object. An example of a real-world directional light source is the sun. The second type is called a positional light source, since its exact position within the scene determines the effect it has on a scene and, specifically, the direction from which the light rays come. A desk lamp is an example of a positional light source. To switch type, simply invoke :light.setType(Type.DIRECTIONAL);
Light attenuation
For real-world lights, the intensity of light decreases as distance from the light increases. Since a directional light is infinitely far away, it doesn't make sense to attenuate its intensity over distance, so attenuation is disabled for a directional light. However, you might want to attenuate the light from a positional light. OpenGL attenuates a light source by multiplying the contribution of that source by an attenuation factor:
where- d = distance between the light's position and the vertex
- kc = GL_CONSTANT_ATTENUATION
- kl = GL_LINEAR_ATTENUATION
- kq = GL_QUADRATIC_ATTENUATION
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5);
Attenuation attenuation = new Attenuation(); attenuation.setConstant(1); attenuation.setLinear(1); attenuation.setQuadratic(1); Light light = new Light(); light.setAttenuation(attenuation);
Light Model
The OpenGL notion of a lighting model has three components:- The global ambient light intensity
- Whether the viewpoint position is local to the scene or whether it should be considered to be an infinite distance away
- Whether lighting calculations should be performed differently for both the front and back faces of objects
Global Ambient Light
Each light source can contribute ambient light to a scene. In addition, there can be other ambient light that's not from any particular source. To specify the RGBA intensity of such global ambient light, use the GL_LIGHT_MODEL_AMBIENT parameter as follows:float[] ambiant = { 0.2f, 0.2f, 0.2f, 1.0f }; painter.glLightModel(LightModel.LIGHT_MODEL_AMBIENT, ambiant);
Local or Infinite Viewpoint
The location of the viewpoint affects the calculations for highlights produced by specular reflectance. More specifically, the intensity of the highlight at a particular vertex depends on the normal at that vertex, the direction from the vertex to the light source, and the direction from the vertex to the viewpoint. Keep in mind that the viewpoint isn't actually being moved by calls to lighting commands (you need to change the projection transformation, as described in "Projection Transformations" in Chapter 3); instead, different assumptions are made for the lighting calculations as if the viewpoint were moved. With an infinite viewpoint, the direction between it and any vertex in the scene remains constant. A local viewpoint tends to yield more realistic results, but since the direction has to be calculated for each vertex, overall performance is decreased with a local viewpoint. By default, an infinite viewpoint is assumed. Here's how to change to a local viewpoint:painter.glLightModel(LightModel.LIGHT_MODEL_LOCAL_VIEWER, true);
false
as the argument.Two-sided Lighting
Lighting calculations are performed for all polygons, whether they're front-facing or back-facing. Since you usually set up lighting conditions with the front-facing polygons in mind, however, the back-facing ones typically aren't correctly illuminated. In Example 5-1 where the object is a sphere, only the front faces are ever seen, since they're the ones on the outside of the sphere. So, in this case, it doesn't matter what the back-facing polygons look like. If the sphere is going to be cut away so that its inside surface will be visible, however, you might want to have the inside surface be fully lit according to the lighting conditions you've defined; you might also want to supply a different material description for the back faces. When you turn on two-sided lighting withpainter.glLightModel(LightModel.LIGHT_MODEL_TWO_SIDE, true);
false
as the argument in the preceding call. (See "Defining Material Properties" for information about how to supply material properties for both faces.) You can also control which faces OpenGL considers to be front-facing with the command glFrontFace(). (See "Reversing and Culling Polygon Faces" in Chapter 2 for more information.)- Author:
- Martin Pernollet
- See Also:
- OpenGL Red book chapter about lighting which was copied to make this javadoc closest to the OpenGL documentation.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Light.Type
-
Field Summary
Fields Modifier and Type Field Description protected Color
ambiantColor
protected Attenuation
attenuation
static Color
DEFAULT_COLOR
protected Color
diffuseColor
protected static int
DIRECTIONAL_TYPE
protected boolean
enabled
protected float[]
glPositionAndType
protected static int
lightCount
protected int
lightId
protected Coord3d
position
protected static int
POSITIONAL_TYPE
protected Color
representationColor
protected boolean
representationDisplayed
protected float
representationRadius
protected Color
specularColor
protected Light.Type
type
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
apply(IPainter painter, Coord3d scale)
protected void
configureLight(IPainter painter, int lightId)
Color
getAmbiantColor()
Attenuation
getAttenuation()
Color
getDiffuseColor()
int
getId()
Coord3d
getPosition()
boolean
getRepresentationDisplayed()
float
getRepresentationRadius()
Color
getSpecularColor()
Light.Type
getType()
boolean
isEnabled()
static void
resetCounter()
void
setAmbiantColor(Color ambiantColor)
void
setAttenuation(Attenuation attenuation)
void
setDiffuseColor(Color diffuseColor)
void
setEnabled(boolean enabled)
void
setPosition(Coord3d position)
void
setRepresentationDisplayed(boolean status)
Indicates if a square is drawn to show the light position.void
setRepresentationRadius(float representationRadius)
void
setSpecularColor(Color specularColor)
void
setType(Light.Type type)
-
-
-
Field Detail
-
DEFAULT_COLOR
public static final Color DEFAULT_COLOR
-
POSITIONAL_TYPE
protected static final int POSITIONAL_TYPE
- See Also:
- Constant Field Values
-
DIRECTIONAL_TYPE
protected static final int DIRECTIONAL_TYPE
- See Also:
- Constant Field Values
-
type
protected Light.Type type
-
lightId
protected int lightId
-
enabled
protected boolean enabled
-
ambiantColor
protected Color ambiantColor
-
diffuseColor
protected Color diffuseColor
-
specularColor
protected Color specularColor
-
position
protected Coord3d position
-
glPositionAndType
protected float[] glPositionAndType
-
attenuation
protected Attenuation attenuation
-
representationDisplayed
protected boolean representationDisplayed
-
representationRadius
protected float representationRadius
-
representationColor
protected Color representationColor
-
lightCount
protected static int lightCount
-
-
Method Detail
-
resetCounter
public static void resetCounter()
-
configureLight
protected void configureLight(IPainter painter, int lightId)
-
setRepresentationDisplayed
public void setRepresentationDisplayed(boolean status)
Indicates if a square is drawn to show the light position.
-
getRepresentationDisplayed
public boolean getRepresentationDisplayed()
-
getRepresentationRadius
public float getRepresentationRadius()
-
setRepresentationRadius
public void setRepresentationRadius(float representationRadius)
-
getId
public int getId()
-
setPosition
public void setPosition(Coord3d position)
-
getPosition
public Coord3d getPosition()
-
isEnabled
public boolean isEnabled()
-
setEnabled
public void setEnabled(boolean enabled)
-
getAmbiantColor
public Color getAmbiantColor()
-
setAmbiantColor
public void setAmbiantColor(Color ambiantColor)
-
getDiffuseColor
public Color getDiffuseColor()
-
setDiffuseColor
public void setDiffuseColor(Color diffuseColor)
-
getSpecularColor
public Color getSpecularColor()
-
setSpecularColor
public void setSpecularColor(Color specularColor)
-
getType
public Light.Type getType()
-
setType
public void setType(Light.Type type)
-
getAttenuation
public Attenuation getAttenuation()
-
setAttenuation
public void setAttenuation(Attenuation attenuation)
-
-