光源
光照計算模型說明圖形系統以什么樣的方法計算燈光照射在物體上的顏色值,它是一種計算方法,而不是具體的燈光。光源則定義了三維場景中具體的燈光,包括位置、方向、強度等信息。相同的光源可以根據物體表面材質的不同,通過不同的光照模型顯示。比如,在臥室中的一盞臺燈,照射在布質床單上時,應使用漫反射模型;而照射在玻璃表面的桌子上時,則應使用鏡面反射模型計算光照效果。
光源類型
在Direct3D中支持三種光源類型:方向光(directional light)、點光源(point
light)和聚光燈(spot light)。它們在Direct3D中以枚舉類型D3DLIGHTTYPE表示,枚舉類型D3DLIGHTTYPE定義如下:
typedef enum _D3DLIGHTTYPE {
D3DLIGHT_POINT = 1,
D3DLIGHT_SPOT = 2,
D3DLIGHT_DIRECTIONAL = 3,
D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
} D3DLIGHTTYPE;
Constants
- D3DLIGHT_POINT
- Light is a point source. The light has a position
in space and radiates light in all directions.
- D3DLIGHT_SPOT
- Light is a spotlight source. This light is like a
point light, except that the illumination is limited to a cone. This light
type has a direction and several other parameters that determine the shape
of the cone it produces. For information about these parameters, see the
D3DLIGHT9 structure.
- D3DLIGHT_DIRECTIONAL
- Light is a directional light source. This is
equivalent to using a point light source at an infinite distance.
- D3DLIGHT_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in
size. Without this value, some compilers would allow this enumeration to
compile to a size other than 32 bits. This value is not used.
Remarks
Directional lights are slightly faster than point light
sources, but point lights look a little better. Spotlights offer interesting
visual effects but are computationally time-consuming.
1、點光源
點光源有顏色和位置,但沒有方向,它向所有方向發射的光都一樣。
電燈泡是點光源的一個例子,這種光的強度隨著距離物體的遠近而衰減,在程序中需要提供點光源的位置、顏色和衰減系數等參數。在進行光照計算時,根據點光源在世界空間中的位置和物體頂點坐標計算出燈光的方向和燈光傳播的距離(用于計算燈光的衰減),然后再同頂點法向量一起,根據燈光和物體表面材質屬性計算物體表面每個頂點的顏色值。
2、方向光
方向光有顏色和方向,沒有位置。它們發出的是平行光,這意味著由方向光生成的燈光以同一個方向照向場景。可以把方向光想象成無窮遠處的一個光源,如太陽光發出的光。方向光不會衰竭,當Direct3D用這種光源計算頂點顏色時,只考慮指定的方向和顏色。因為不需要考慮照亮范圍和位置的影響,所以這種光的計算量最少。有策略的應用方向光能夠提高程序的執行速度。
3、聚光燈
聚光燈有顏色、位置和方向,類似于現實世界中的探照燈。聚光燈發出的光線由一個明亮的內錐體(inner
cone)和大一點的外錐體(outer cone)組成。光線強度從內椎體到外椎體逐漸衰減,通過聚光燈的falloff、theta和phi這三個屬性共同來控制其衰減規律,其中theta為內錐角,phi為外錐角。
一個頂點受到的聚光燈光照總量以該頂點在內椎體或外椎體中的位置為基礎。Direct3D計算聚光燈方向向量L與從光源到頂點的向量D的點積,這個點積的值等于兩個向量夾角alpha的余弦。Direct3D將該值與角度theta和phi的余弦作比較。如果向量的點積小于或等于外椎體的余弦,該頂點超出了外椎體,不受光照;若這個點積大于內椎體角的余弦,則該頂點在內椎體內,受到的光照總量較多,仍需考慮在距離上的衰減。如果頂點在兩個區域之間,用下面的公式計算衰減后的光照系數。
If = ((cos(alpha) - cos(phi/2)) /
(cos(theta/2) - cos(phi/2)))p
其中,If為衰減后的光強系數,alpha表示向量L和D間的夾角,theta表示內錐角,phi表示外錐角,p表示衰減系數falloff。
該計算公式得到的If值在0.0~1.0之間,用來縮放光線強度以實現衰減。當然還要考慮從具體每個頂點到光源的距離衰減(attenuation)。在Direct3D中,聚光燈是所有光源類型中最耗時的光源,因此在系統性能不高的情況下應該謹慎采用聚光燈。
光源屬性
三維場景的一個光源通過其各種屬性來描述,光源屬性包括光的發光位置、方向、顏色和衰減范圍等,這些屬性可控制光線對物體的照明程度,各種類型光源的屬性由結構D3DLIGHT9定義。
Defines a set of lighting properties.
typedef struct D3DLIGHT9 {
D3DLIGHTTYPE Type;
D3DCOLORVALUE Diffuse;
D3DCOLORVALUE Specular;
D3DCOLORVALUE Ambient;
D3DVECTOR Position;
D3DVECTOR Direction;
float Range;
float Falloff;
float Attenuation0;
float Attenuation1;
float Attenuation2;
float Theta;
float Phi;
} D3DLIGHT9, *LPD3DLIGHT;
Members
- Type
- Type of the light source. This value is one of the
members of the D3DLIGHTTYPE enumerated type.
- Diffuse
- Diffuse color emitted by the light. This member is
a D3DCOLORVALUE structure.
- Specular
- Specular color emitted by the light. This member
is a D3DCOLORVALUE structure.
- Ambient
- Ambient color emitted by the light. This member is
a D3DCOLORVALUE structure.
- Position
- Position of the light in world space, specified by
a D3DVECTOR structure. This member has no meaning for directional lights and
is ignored in that case.
- Direction
- Direction that the light is pointing in world
space, specified by a D3DVECTOR structure. This member has meaning
only for directional and spotlights. This vector need not be normalized, but
it should have a nonzero length.
- Range
- Distance beyond which the light has no effect. The
maximum allowable value for this member is the square root of FLT_MAX. This
member does not affect directional lights.
- Falloff
Decrease in illumination between a spotlight's
inner cone (the angle specified by Theta) and the outer edge of the outer
cone (the angle specified by Phi).
- The effect of falloff on the lighting is subtle.
Furthermore, a small performance penalty is incurred by shaping the falloff
curve. For these reasons, most developers set this value to 1.0.
- Attenuation0
- Value specifying how the light intensity changes
over distance. Attenuation values are ignored for directional lights. This
member represents an attenuation constant. For information about
attenuation, see Light Properties (Direct3D 9). Valid values for this member
range from 0.0 to infinity. For non-directional lights, all three
attenuation values should not be set to 0.0 at the same time.
- Attenuation1
- Value specifying how the light intensity changes
over distance. Attenuation values are ignored for directional lights. This
member represents an attenuation constant. For information about
attenuation, see Light Properties (Direct3D 9). Valid values for this
member range from 0.0 to infinity. For non-directional lights, all three
attenuation values should not be set to 0.0 at the same time.
- Attenuation2
- Value specifying how the light intensity changes
over distance. Attenuation values are ignored for directional lights. This
member represents an attenuation constant. For information about
attenuation, see Light Properties (Direct3D 9). Valid values for this
member range from 0.0 to infinity. For non-directional lights, all three
attenuation values should not be set to 0.0 at the same time.
- Theta
- Angle, in radians, of a spotlight's inner cone -
that is, the fully illuminated spotlight cone. This value must be in the
range from 0 through the value specified by Phi.
- Phi
- Angle, in radians, defining the outer edge of the
spotlight's outer cone. Points outside this cone are not lit by the
spotlight. This value must be between 0 and pi.
Ambient、Diffuse、Specular分別表示光以不同的光照計算模型計算時的光源顏色,例如Diffuse就表示光源的漫反射顏色。因為一個光源會照亮場景中的多個物體,而這些物體可能會使用不同的光照計算模型進行光照計算,所以這就需要為燈光分別設置用于不同光照計算模型的燈光顏色。
光源發出光的三種顏色,與當前材質的相應部分相作用,生成最終用于渲染的顏色。光源漫反射顏色與當前材質的漫反射屬性作用,光源鏡面反射顏色與當前材質的鏡面反射屬性作用等。
這三個顏色成員都是D3DCOLORVALUE結構體類型的變量,其中R、G、B這三個分量的取值區間為0.0f~1.0f。最常見的漫反射顏色是白色(R:1.0
G:1.0 B:1.0),但可根據需要實現的效果創建所需的顏色。例如,為一個壁爐采用紅光。
Describes color values.
typedef struct D3DCOLORVALUE {
float r;
float g;
float b;
float a;
} D3DCOLORVALUE, *LPD3DCOLORVALUE;
Members
- r
- Floating-point value specifying the red component
of a color. This value generally is in the range from 0.0 through 1.0, with
0.0 being black.
- g
- Floating-point value specifying the green
component of a color. This value generally is in the range from 0.0 through
1.0, with 0.0 being black.
- b
- Floating-point value specifying the blue component
of a color. This value generally is in the range from 0.0 through 1.0, with
0.0 being black.
- a
- Floating-point value specifying the alpha
component of a color. This value generally is in the range from 0.0 through
1.0, with 0.0 being black.
Remarks
You can set the members of this structure to values
outside the range of 0 through 1 to implement some unusual effects. Values
greater than 1 produce strong lights that tend to wash out a scene. Negative
values produce dark lights that actually remove light from a scene.
距離衰減系數Attenuation0、Attenuation1、Attenuation2控制一個光源的光強如何向著最遠距離減弱,最遠距離是由屬性Range指定的照射范圍。這三個成員都是浮點型、取值范圍是從0.0到無窮大。Attenuation0、Attenuation1、Attenuation2分別表示光的常量、線性、二次距離衰減系數。衰減公式為:
Atten = 1 / (Attenuation0 + Attenuation1 * d +
Attenuation2 * d2)
其中d為物體頂點和光源之間的距離。物體距離光源越遠,它的亮度越小。距離衰減系數僅對點光源和聚光燈有效。一些應用程序可將Attenuation1設為1.0,其他的設為0.0,從而使光強按1/d的比例改變。在光源處光強最大,在光源的照射范圍邊界處減少到1/Range。也可以分別設置3個衰減系數為不同的數值,得到更復雜的衰減效果,這些值可以任意設置,但是不能為負數。
結構類型D3DLIGHT9包含三個僅有聚光燈使用的成員:內外錐體衰減系數falloff、內椎體角度theta、外椎體角度phi,共同控制著一個聚光燈的內外椎體各有多大,以及在它們中間的光線如何減弱。