1. Hidden area Removal
During rendering, OpenGL needs to draw objects close to the viewpoint and remove the objects that are blocked from the distance. In 2D drawing, the purpose is generally achieved by controlling the draw sequence. 3D scenes are much more complex and may be partially blocked. Changing the angle of view also changes the occlusion. OpenGL uses depth buffer to eliminate hidden parts.
Depth buffer stores the depth value of each pixel (generally the distance between the fragment and the near cut surface ). At the initial time or glclear (gl_depth_buffer_bit), the depth buffer is initialized to the maximum value (generally the depth of the distant cut plane). During the fragment operation, the depth value of its depth value and the corresponding position in the buffer is determined, if the value is less than, continue the operation and replace the depth value. Otherwise, the operation is discarded directly. To activate this function, call glable (gl_depth_test ).
2. Care System
In the real world, the color of the surface of an object depends on the color of the light reflected by the object. The light source (or multiple light sources) shines on the surface of the object, and some are absorbed by the object, some objects are reflected. Some objects have smooth surfaces, and the incident light is reflected in a specific direction. Some objects are scattered in different directions. Most objects are based on the two. OpenGL simulates the illumination system by dividing the light into three RGB components: The color of the light source depends on the strength of the three components of rbg, the material on the surface of an object is defined as the percentage of the three rbg components reflected in each direction.
In OpenGL, light comes from several independent light sources. The light received by an object may come from a specific direction or position, or be evenly distributed in the environment. For example, if there is a lamp in the room, most of the Light received by the objects in the room comes from the lamp. However, some light may not be reflected in the direction after multiple reflections, however, the light is still from this lamp. If the light source is off, the light will disappear. In addition, the environment itself has some light, which cannot determine its source and direction.
Ambient, diffuse, specular, and emisive)
The light received by an object can be divided into the above four parts, which are calculated separately and then combined.
Ambient Light: uniformly dispersed in the environment and cannot be distinguished. When ambient light is in contact with the object surface, it is uniformly reflected in all directions;
Diffuse Light: from a certain direction, if direct, it will look brighter, and after contact with the object surface, it will emit uniformly in all directions; PS: we can see that this light is
The action is related to the incident angle, but not to the observed angle.
Reflected Light: Reflection from a certain direction to a certain direction, which plays a role in high light;
Radiation light: the light released by an object in this province affects the object itself. It does not interact with the light source or add light to the environment.
Material color (Material color)
The color of the material is actually the reflection ratio of the material to the light. It is also divided into three types: ambient, diffuse, and specular. Each type is determined by RGB. The ambient value is combined with the illumination ambient value, the same diffuse value is combined with the illumination diffuse value, and the specular value is combined with the illumination specular value. The ambient and diffuse of materials are generally the same. The reflection (diffuse) of these two components determines the color of the object, and the specular value is generally white or gray, that is, the color after reflection is the light color, which is used to produce the high-gloss effect. For example, a red ball in white light is mainly red and the bright area is white.
Color Calculation
The RGB color of light has the same meaning as the RGB value of general color. The RGB color value of the material represents the reflection ratio of light. The former can be expressed by (LR, LG, LB, the latter can be represented by (MR, Mg, MB), so the color of the object reflection is (LR * Mr, LG * Mg, LB * MB ). If there are two light sources that generate two colors for the object (R1, G1, B1) and (R2, G2, B2), the final color of the object is (R1 + R2, g1 + G2, B1 + B2). If a value is greater than 1.0, the value is limited to 1.0.
Normal
The surface normal defines the phase direction of the surface and the light source, which will affect the illumination effect. The normal is required to be normalized. You need to call the glable (gl_normalize) and glable (gl_rescale_normal) to enable automatic normalization of normal.
3. Create a light source
First, enable the gl_lighting system, and then enable the gl_lighti light source. Then define the properties of the light source, and use gllight * (glenum light, glenum pname, type PARAM) and gllight * V (glenum light, glenum
Pname, const type * PARAM) Two APIs to set the property value: light is the light source identity, that is, gl_light0, gl_light1..., pname is the property name, And Param is the property value.
For the attribute list and its default values, see the original book. It is worth noting that the default values of gl_diffuse and gl_specular are different for gl_light0 and other light sources.
Color
Set the color values for the gl_ambient, gl_diffuse, and gl_specular components of the light source, for example:
Glfloat light_ambient [] = {0.0, 0.0, 1.0, 1.0 };
Gllightfv (gl_light0, gl_ambient, light_ambient );
Location and direction
From the perspective of position, there are two kinds of light sources, one is directional light source, which is located in an infinite distance, and all the light directions are consistent and will not decay, such as "sunlight ". The other is positional light source, which is in the scene, and its specific position will affect the illumination effect.
The following is an API for setting the position of a light source:
Glfloat light_position [] = {1.0, 1.0, 1.0, 0.0 };
Gllightfv (gl_light0, gl_position, light_position );
If the fourth component of position is 0, the light source is directional, And the postion value is actually a vector; otherwise, the light source is postional, and the position is his position. Both the position and direction of the light source are affected by modelview matrix.
Attenuation
As the object is farther away from the light source, the light intensity degrades. For directional light sources, attenuation is meaningless. Therefore, attenuation is for positional light sources. Attenuation is multiplied by an attenuation factor by the intensity of the light source. The attenuation factor formula is as follows:
D = distance between vertex and Light Source
KC = gl_constant_attenuation
KL = gl_linear_attenuation
KQ = gl_quadratic_attenuation
The default values of KC are 1.0, and the default values of KL and KQ are 0. You can set them through API:
Gllightf (gl_light0, gl_constant_attenuation, 2.0 );
Gllightf (gl_light0, gl_linear_attenuation, 1.0 );
Gllightf (gl_light0, gl_quadratic_attenuation, 0.5 );
Concentration
You can add a concentrating effect to the positional light source, which is to specify the direction and range of the illumination of the light source (a vertebral body ):
Glfloat spot_direction [] = {-1.0,-1.0, 0.0 };
Gllightfv (gl_light0, gl_spot_direction, spot_direction );
The above specifies the direction of the light source, that is, the axis direction of the vertebral body;
Gllightf (gl_light0, gl_spot_cutoff, 45.0 );
The angle between the border of the vertebral body and the circumference is determined above. If the angle is 180, it is equivalent to NO concentration effect.
You can also add the attenuation effect from the center axis to the edge to use the gl_spot_exponent attribute.
Control the position and direction of the light source
OpenGL treats the position and direction of the light source as the same as the position of the vertex and the normal, and is converted to the eye coordinate system coordinate by modelview matrix, this section describes how to control the position of a light source to meet several common requirements:
1) fixed light source position: place the light source in a fixed position, which is not affected by other operations. After setting the viewpoint, specify the light source position immediately.
2) Independent Light Source Movement: Generally, it is not difficult to set the position of the light source in the display, as long as glpushmatrix and glpopmatrix are used.
3) Move the light source with the viewpoint: Specify the position of the light source before the viewpoint is specified. When the viewpoint is dynamically adjusted thereafter, the relative position of the light source remains unchanged. Note: The position specified before the viewpoint is specified does not change when the world coordinate system is switched to the eye coordinate system. Therefore, the relative viewpoint position does not change.
Set illumination mode
The API for setting the illumination mode is gllightmodel {if} (glenum pname, type PARAM) or void gllightmodel {if} V (glenum pname, const type * PARAM), and pname is the attribute name.
Global Environment light (Global ambient): The environment light irrelevant to the light source. Its name is gl_light_model_ambient.
Local or infinit viewport: when calculating the highlight effect, the height of the vertex depends on three directions: the relative direction, normal direction, viewpoint, and vertex direction of the light source and vertex. The relative direction of different vertices is different from that of the viewpoint. This inconsistency is ignored when an infinitely distant viewpoint is used, use a fixed value to improve efficiency. The setting here does not really change the viewpoint position, but only for illumination. OpenGL uses infinit by default.
For viewport, use gllightmodeli (gl_light_model_local_viewer, gl_true ).
Back illumination: by default, OpenGL only takes care of the front-face of a polygon. In some cases, it may be necessary to take care of the Back-face. For example, if a sphere is cut out, use the following API: gllightmodeli (gl_light_model_two_side,
Gl_true );
Delayed highlight processing: In the OpenGL assembly line, the light processing occurs after the texture processing, so that the highlight effect will be greatly weakened. To make the highlight effect more obvious, you need to delay the processing of the highlight. Enable the method: gllightmodeli (gl_light_model_color_control, gl_separate_specular_color ),
In this way, the ambient, diffuse, and emissve components are first synthesized to the vertex color. The color angle primary color and the secondary color generated by specular components are saved; after texture is complete, add the specular value secondary to the vertex color. Disable this function: gllightmodeli (gl_light_model_color_control,
Gl_single_color ).
4. Define material attributes
Define material attributes using API:
Void glmaterial {if} (glenum face, glenum pname, type PARAM );
Void glmaterial {if} V (glenum face, glenum pname, const type * PARAM );
Face indicates the front or back of an object. pname indicates the attribute name. Possible values include gl_ambient, gl_diffuse, gl_ambient_and_diffuse, gl_specular, gl_emission, and gl_shininess ).
Diffuse and ambient determine the final color of an object to a large extent;
The effect of sepcular has a great relationship with the position of the viewpoint. If the angle direction is the same as that of the reflection, the highlight effect is the most obvious;
Shiniess is used to control the area and brightness of the highlight. The value range is [0.0, 128.0]. The larger the value, the smaller the highlight area and the brighter the color;
Emission will make the object have a luminous effect, but it cannot act as a light source.
5. Illumination mathematical computing
The first line is the light color released by the object itself;
Row 2: The color of the global ambient light on the object;
Row 3: attenuation and concentration effect. As mentioned earlier, the concentration effect value is divided into several situations: 1) the radiation angle is 180, and there is no concentration effect at this time. The value is 1; 2) the vertex is outside the concentrating vertebral body, and the value is 0. 3) for max (V * D, 0), the gl_spot_exponent is obtained, and V is the unit vector from the position of the light source to the vertex, D is the central axis of the poly light source;
Row 4: ambient effect of light source I
Line 5: The effect of light source I scattered light. L is the unit vector from vertex to light source, and N is the vertex normal vector;
Row 6: The highlight effect produced by light source I. S is the normalization of the result (from vertex to light source unit vector + from vertex to viewpoint unit vector), and N is the vertex normal vector, from "vertex to viewpoint unit vector", if gl_light_model_local_viewer is not enabled, the value is (0, 0, 1 ).
If gl_light_secondary_color is enabled, you only need to extract the specular part as the secondary color, and the rest is the primary color.