游戏设计颜色和灯光.ppt
M,Lecture 5 Color&Lighting颜色和光照,Contents,Color RepresentationShadingLight ComponentsMaterialsVertex NormalsLight SourcesSample Applications,M,Color Representation,在Direct3D中,颜色是使用RGB(Red,Green,Blue)三部分来描述的。这三个分量通过加性混合(additive)决定了最终颜色(可以表示上百万种颜色)两种不同的存储RGB数据的结构:(1)D3DCOLOR:实际上一个DWORD(32位)类型。在D3DCOLOR类型中的这些位按照8-bit被分为4个部分,每一部分存储的是该色的亮度值。每种颜色占用内存的一个字节,各颜色亮度值的取值范围是0-255。这个值越接近0就越暗,越接近255就越亮。,M,Color Representation,D3DCOLOR赋值宏D3DCOLOR_ARGB:完成指定每个颜色分量并且把它放到D3DCOLOR中适当位置的任务。宏D3DCOLOR_XRGB,M,D3DCOLOR brightRed=D3DCOLOR_ARGB(255,255,0,0);D3DCOLOR someColor=D3DCOLOR_ARGB(255,144,87,201);,#define D3DCOLOR_XRGB(r,g,b)D3DCOLOR_ARGB(0 xff,r,g,b),Color Representation,(2)D3DCOLORVALUE:使用一个浮点数来表示每一部分的亮度值。其取值范围是0-1,0表示没有亮度,1表示最大亮度。,M,typedef struct _D3DCOLORVALUE float r;float g;float b;float a;D3DCOLORVALUE;,可以使用结构D3DXCOLOR替代D3DCOLORVALUE,前者不仅包含与后者相同的数据成员,还提供了一组有用的构造函数和重载运算符,为颜色运算提供了便利。(两种结构可以相互转换),Color Representation,顶点颜色 图元的颜色是由构成它的顶点的颜色决定的。因此,必须把一个颜色成员加入到我们的顶点数据结构中。注意:D3DCOLORVALUE类型不能用在这里,因为Direct3D希望用一个32位的值来描述顶点的颜色,M,Shading,着色处理发生在光栅化和指定图元上的顶点颜色怎样被计算成像素颜色之间。目前使用2种着色模式:平面着色(flat shading)Gouraud着色(Gouraud shading)。平面着色:图元像素的颜色是均匀的,且只指定图元第一个顶点的颜色。因此一旦三角形的第一个顶点被指定成红色,那么它的其他两个顶点也将会是红色而忽略其他顶点颜色。平面着色使物体呈现是斑驳的,因为没有从一个颜色到另一个颜色的平滑过渡。Gouraud着色:平滑着色,图元表面的颜色是由每个顶点通过线性插值来获得。,M,Light Components,为了提高场景的真实性,我们可以为其加入灯光。灯光也能帮助表现物体的立体感以及物体的体积。当使用灯光时,我们不再自己指定顶点的颜色;Direct3D中每个顶点都通过灯光引擎来计算顶点颜色,该计算是基于定义的灯光资源,材质以及灯光资源关心的表面方向。通过灯光模型计算顶点颜色会得到更真实的场景。,M,Light Components,在Direct3D 灯光模型中,灯光是通过灯光资源的三个成员之一来照射的,即有三种灯光。环境光(Ambient Light)这种类型的灯光将被其他所有表面反射且被用在照亮整个场景。例如,物体的各部分都被照亮,对于一个角度,甚至穿过不在光源直接照射的地方他们都能被照亮。漫反射(Diffuse Reflection)这种灯光按特殊方向传播。当它照射到一个表面,它将在所有方向上均匀的反射。因为漫射光在所有方向上都均匀的反射,被反射的光线将到达眼睛而与观察点无关,因此我们不必为观察者考虑。因而,漫射光仅仅需要考虑灯光方向和表面的姿态。这种灯光将成为你的资源中照射的普通灯光。,M,Light Components,镜面反射(Specular Reflection)这种灯光按照特殊方向传播。当它照射到一个表面时,它严格地按照一个方向反射,这将产生一个明亮的光泽,它能在某角度被看见。因为这种灯光在一个方向反射,所以观察点必须考虑灯光的方向和表面姿态,且必须按照镜面灯光等式来考虑。镜面灯光被用在物体上产生高光的地方,这种光泽只有在灯光照射在磨光的表面上才会产生。镜面光比其他灯光类型要求更多的计算;因此,Direct3D提供了一个开关选择。实际上,它默认是被关闭的;要使用镜面光你必须设置D3DRS_SPECULARENABLE渲染状态。,M,Device-SetRenderState(D3DRS_SPECULARENABLE,true);,Light Components,每一种灯光都是通过D3DCOLOR VALUE结构或者描述灯光颜色的D3DXCOLOR来描绘的。,M,D3DXCOLOR redAmbient(1.0f,0.0f,0.0f,1.0f);D3DXCOLOR blueDiffuse(0.0f,0.0f,1.0f,1.0f);D3DXCOLOR whiteSpecular(1.0f,1.0f,1.0f,1.0f);,在D3DXCOLOR类中的alpha值用在描述灯光颜色时是被忽略的。,Materials,在现实世界中我们看到的物体颜色将由物体反射回来的灯光颜色来决定。比如,一个红色的球是红色的,因为它吸收除红色光之外的所有灯光颜色。红色光是被球反射回来进入我们眼睛的,因此我们看到的球是红色的。Direct3D通过定义物体材质来模拟这些所有的现象。材质允许我们定义表面反射灯光的百分比。材质是通过D3DMATERIAL9结构描述的,M,typedef struct _D3DMATERIAL9 D3DCOLORVALUE Diffuse;/指定此表面反射的漫射光数量D3DCOLORVALUE Ambient;/指定此表面反射的环境光数量D3DCOLORVALUE Specular;/指定此表面反射的镜面光数量 D3DCOLORVALUE Emissive;/给表面添加颜色float Power;/指定锐利的镜面高光 D3DMATERIAL9;,例如,想得到一个红色的球。我们将定义球的材质来只反射红光吸收其他颜色的所有光:D3DMATERIAL9 red;:ZeroMemory(设置绿色和蓝色的值为0,这表明材质反射0%此颜色的光。我们设置红色为1,表示材质反射100%的红光。假如我们定义一个只发出蓝色光的光源,对球的光照将失败因为蓝色光将被全部吸收而没有红光被反射。当物体吸收了所有光以后,物体看起来就为黑色。同样的,当物体反射100%的红、绿和蓝光,物体就将呈现为白色。,Materials,顶点结构没有材质属性;一个通用的材质必须被设置。设置它我们使用IDirect3DDevice9:SetMaterial(CONST D3DMATERIAL9*pMaterial)方法。假设我们想渲染几个不同材质的物体,M,D3DMATERIAL9 blueMaterial,redMaterial;./set up material structuresDevice-SetMaterial(/red sphere,Vertex Normals,面法线(face normal)是描述多边形表面方向的一个向量顶点法线(Vertex normals)也是基于同样的概念,描述构成多边形的各个顶点的法线,M,Vertex Normals,顶点法线和面法线 Direct3D需要知道顶点法线以便它能够确定灯光照射到物体表面的角度,并且一旦计算了每个顶点的灯光,Direct3D需要知道每个顶点的表面方向。注意顶点法线不一定和面法线相同。,M,顶点法线,面法线,Vertex Normals,为了描述顶点的顶点法线,必须修改顶点结构:,M,struct Vertexfloat _x,_y,_z;float _nx,_ny,_nz;static const DWORD FVF;const DWORD Vertex:FVF=D3DFVF_XYZ|D3DFVF_NORMAL;,Notice that the color member are removed,Vertex Normals,顶点法线的计算:假设一个由p0,p1,p2构成的三角形,我们需要计算每个顶点的法线n0,n1,n2p1-p0=u,p2-p0=v,n=u v=n0=n1=n2=n 当用三角形近似表示曲面时,使用面法线作为顶点法线不能表现一个平滑的结果。一个更好的方法是找到顶点法线的平均法线。为了找到顶点v的顶点法线vn,我们找到网格模型中所有三角形的面法线记为顶点v。vn是通过计算他们的平均面法线得到的。,M,假设有3个三角形它们的面法线分别是n0,n1,n2,指定为顶点v。那么vn的平均法线就是:Vn=1/3(n0+n1+n2),Vertex Normals,顶点法线的规范化:,M,Device-SetRenderState(D3DRS_NORMALIZENORMALS,true);,Light Sources,Direct3D 支持三种类型的光源:点光源这种光源在世界坐标中有一个位置且向所有方向上都照射光线。方向光源这种光源没有位置但是向指定方向发出平行光线。聚光灯这种类型的光源和手电筒的光类似;它有位置并且发出的光在指定方向上按照圆锥形照射。这个圆锥形有两个角度,和。角度描述内圆锥,描述外圆锥。,M,Light Sources,Direct3D 光源表示:,M,typedef struct _D3DLIGHT9 D3DLIGHTTYPE Type;/定义灯光类型:D3DLIGHT_POINT,D3DLIGHT_SPOT,D3DLIGHT_DIRECTIONALD3DCOLORVALUE Diffuse;/此光源发出的漫射光颜色D3DCOLORVALUE Specular;/镜面光颜色D3DCOLORVALUE Ambient;/环境光颜色D3DVECTOR Position;/用一个向量来描述光源世界坐标位置D3DVECTOR Direction;/用一个向量来描述光源世界坐标照射方向float Range;/灯光能够传播的最大范围float Falloff;/只用于聚光灯,定义灯光从内圆锥到外圆锥间的强度衰减float Attenuation0;float Attenuation1;float Attenuation2;/上述三个变量为衰减变量,被用来定义灯光强度的传播距离衰减。float Theta;/只用于聚光灯;指定内圆锥的角度,单位是弧度float Phi;/只用于聚光灯;指定外圆锥的角度,单位是弧度 D3DLIGHT9;,它们只被用于点光源和聚光灯上。Attenuation0定义恒定衰减,Attenuation1定义线性衰减,Attenuation2定义二次衰减。衰减公式为:D是代表到光源的距离,A0,A1,A2与Attenuation0,1,2相匹配。,Light Sources,在把D3DLIGHT9初始化好以后,我们需要用Direct3D内在支持的灯光来注册灯光注册后,使用下面的代码来开或关灯光:,M,Device-SetLight(0,/element in the light list to set,range is 0-maxlights/address of the D3DLIGHT9 structure to set,Device-LightEnable(0,/the element in the light list to enable/disabletrue);/true=enable,false=disable,Sample Applications,Example,M,Summary,Colors are described by specifying an intensity of red,green,and blue.The additive mixing of these three colors at different intensities allows us to describe millions of colors.In Direct3D,we can use the D3DCOLOR,the D3DCOLORVALUE,or the D3DXCOLOR type to describe a color in code.With flat shading,the pixels of a primitive are uniformly colored by the color specified in the first vertex of the primitive.With Gouraud shading,the colors at each vertex are interpolated linearly across the face of the primitive.,M,Summary,Direct3D supports three light source models:directional lights,point lights,and spot lights.Light sources emit three types of light:ambient light,diffuse light,and specular light.The material of a surface defines how light interacts with the surface that it strikesVertex normals are used to define the orientation of a vertex.Theyare used so that Direct3D can determine the angle at which a ray oflight strikes the vertex.,M,Thanks?,