Chapter 5
During illumination, you do not need to specify the color value of the vertex. direct3d sends the vertex to the illumination computing engine based on the light source type, material, and orientation of the object surface relative to the light source, calculate the color value of each vertex. Calculating the color of a vertex based on a care model will make the rendering results more realistic.
Ambient Light: This type of light is reflected by other surfaces to the surface of the object and illuminates the entire scene.
Full Light: This type of light is transmitted along a specific direction. When it reaches a certain surface, it will be uniformly reflected along all directions. When using this model, you do not need to consider the position of the observer. In this way, in the diffuse light equation, only the direction of light propagation and the orientation of the surface need to be considered. The light emitted from a point light source is generally of this type.
The type of mirror light is transmitted in a specific direction. When such light reaches a surface, it will be reflected strictly in the other direction, so as to form a highlighted illumination that can only be observed within a certain angle, because in this model, the light is reflected along the same direction, so in the mirror illumination equation, we need to consider not only the light incident direction and the surface orientation of the element, but also the position of the observation point. The mirror light can be used to simulate the highlights of an object.
To enable mirroring, you must set the rendering status d3drs_specularenable to true.
Device-> setrenderstate (d3drs_specularenable, true)
Each type of light can be represented by the d3dcolorvalue or d3dxcolor structure. These types describe the color of light.
When the light color is described, the Alpha values in the d3dxcolor class are ignored.
Example: d3dxcolor redambient (1.0f, 0.0f, 0.0f, 1.0f );
The color of an object is determined by the color of the light reflected by the object. direct3d simulates the same phenomenon by defining the material of the object, material allows the reflection ratio of the defined object surface to various colors of light
Material structure d3dmaterial9
Typedef struct d3dmaterial9 {
D3dcolorvalue diffuse; // reflectivity of the material to the diffuse light
D3dcolorvalue ambient; // reflectivity of materials on ambient light
D3dcolorvalue specular; // reflectivity of the material to the mirror light
D3dcolorvalue emissive; // This component is used to enhance the brightness of an object and make it look as luminous.
Float power; // specify the sharpness of a mirror highlight. The greater the value, the greater the sharpness of the highlights.
} D3dmaterial9, * lpd3dmaterial9;
For example, a red sphere defines the attribute of the ball material as reflecting only the red light and absorbing all the other colors of light.
D3dmaterial9 red;
: Zeromemory (& Red, sizeof (red ));
Red. Diffuse = d3dxcolor (1.0f, 0.0f, 0.0f, 1.0f );
Red. Ambient = d3dxcolor (1.0f, 0.0f, 0.0f, 1.0f );
Red. specular = d3dxcolor (1.0f, 0.0f, 0.0f, 1.0f );
Red. emissive = d3dxcolor (0.0f, 0.0f, 0.0f, 1.0f );
Red. Power = 5.0f;
Here, we set the green and blue components to 0, indicating that the reflectivity of the light of these colors is 0%, and the red component is set to 1. it indicates that the reflectivity of the material to the red light is 100%. Note that we can control which color of the light is reflected under various types of light (ambient light, diffuse light, and mirror light.
The vertex structure does not contain material attributes, but we must set the current material.
Idirect3ddevice9: setmaterial (const d3dmaterial9 * pmaterial)
To draw objects of different materials:
D3dmaterial9 bulematerial, redmaterial;
Deivce-> setmaterial (& bulematerial)
Drawsphere ()
Deivce-> setmaterial (& redmaterial)
Drawsphere ()
The surface normal is the vector that describes the polygon orientation.
The vertex normal describes the normal of each vertex of a polygon.
Direct3d needs to know the normal direction of the vertex to determine the angle of incidence when the light arrives at the surface, and because the photometer is used for each vertex, therefore, direct3d needs to know the local orientation (normal direction) of the surface at each vertex. The vertex normal is not necessarily the same as the surface normal.
Describes a vertex normal.
Struct vertex {
Float x, y, z;
Float _ NX, _ NY, _ NZ;
Static const DWORD fvf;
};
Const DWORD vertex: fvf = d3dfvf_xyz | d3dfvf_normal;
For example, it is used to calculate the normal vector of the surface of a triangle composed of three vertices. The vertex is specified as a clockwise round.
Void computenormal (d3dxvector3 * P0, d3dxvector3 * P1, d3dxvector3 * P2, d3dxvector3 * out)
{
D3dxvector3 u = * P1-* P0;
D3dxvector3 v = * P2-* P0;
D3dxvec3cross (Out, & U, & V );
D3dxvec3normalize (Out, Out );
}
When a triangle element is used to represent a surface, it is impossible to use the surface method vector as the vertex method vector to form the surface.
A better way to obtain the vertex normal vector is to calculateAlgorithmVector Mean. Obtain the surface normal vectors of all triangles sharing vertex v. Then VN can be obtained from the mean value of the surface method vector. Assume that three triangle units share the vertex v, and their surface method vectors are N0, N1, and N2, the calculation method of VN is as follows: V = (N0 + N1 + N2)/3. During the transformation process, the vertex normal may no longer be normalized. Therefore, the best way is, all normal vectors are normalized by enabling the d3drs_normalizenormals draw state.
Device-> setrenderstate (d3drs_normalizenormals, true );
Direct3d supports three types of light sources
* Point light source, which has a fixed position in the world coordinate system and emits light in all directions
* Direction light. The light source has no location information, and the emitted light transmits along a specific direction in parallel.
* A spotlight. The light source has position information, and the light emitted from it is tapered and transmitted along a specific direction. The cone has two angles: Internal cone and external cone.
The light source is represented by the structure d3dlight9.
Typedef struct d3dlight9 {
D3dlighttype type; // light source type, d3dlight_point, d3dlight_spot, d3dlight_directional
D3dcolorvalue diffuse; // color of the diffuse light
D3dcolorvalue specular; // the color of the mirror.
D3dcolorvalue ambient; // color of ambient light
D3dvector position; // the vector of the light source in the world coordinate system. This parameter is meaningless for the direction light.
D3dvector direction; // a vector that describes the direction of light transmitted in the world coordinate system. This parameter is meaningless for the point light source.
Float range; // The maximum optical path that can be reached before the light is "Extinct". The maximum value of this value is flt_max, Which is meaningless for the direction light.
Float falloff; // This value is only used for the spotlight. This parameter defines the attenuation mode from the inner cone to the outer cone of the intensity. Generally, 1.0f is used.
Float attenuation0; // attenuation0, attenuation1, attenuation2 attenuation variable defines the attenuation mode of light intensity with distance, which is only valid for the spot light source and the spotlight, indicating the optical constant, linear, the attenuation formula for two distance attenuation coefficients is a = 1/(A0 + A1 * D + A2 * D), and D is the distance from the light source to the vertex. A0, A1, a2 corresponds to attenuation0, attenuation1, and attenuation2 respectively.
Float attenuation1;
Float attenuation2;
Float Theta; // used only for the spotlight. It specifies the cone angle of the Internal cone, unit: radian
Float Phi; // used only for the spotlight, specifying the cone angle of the external cone, unit: radian
} D3dlight9, * lpd3dlight9;
For example, create a direction light source with the propagation direction parallel to the X axis.
D3dxvector3 Dir (1.0f, 0.0f, 0.0f );
D3dxcolor c = d3d: white;
D3dlight9 dirlight = d3d: initdirectionallight (& Dir, & C );
After creation, you need to register the desired light source in the internal list of a light source maintained by direct3d.
Device-> setlight (0, & Light );
Once the light source is successfully registered, we can control its switch status.
Device-> lightenable (0, true );
To add illumination for a scenario, follow these steps:
* Enable illumination
* Create a material for each object and apply the material before drawing the corresponding object.
* Create one or more light sources, set and enable
* Enable all remaining lighting states, such as the mirror highlight.