天行健 君子当自强而不息

光照与材质(2)

光源

光照计算模型说明图形系统以什么样的方法计算灯光照射在物体上的颜色值,它是一种计算方法,而不是具体的灯光。光源则定义了三维场景中具体的灯光,包括位置、方向、强度等信息。相同的光源可以根据物体表面材质的不同,通过不同的光照模型显示。比如,在卧室中的一盏台灯,照射在布质床单上时,应使用漫反射模型;而照射在玻璃表面的桌子上时,则应使用镜面反射模型计算光照效果。

 

光源类型

在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,共同控制着一个聚光灯的内外椎体各有多大,以及在它们中间的光线如何减弱。


posted on 2008-05-03 18:58 lovedday 阅读(1566) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论