您的位置:首页 > 其它

精通DirectX.3D图形与动画程序设计(王德才 杨关胜 孙玉萍/编著,2007年5月出版)读书摘要(2008.8.4至今)

2015-08-04 10:21 267 查看

——谨以此篇日志,纪念本人进入游戏行业7周年

chap5光照和材质

使用光照效果能够有效地增强场景的真实感。

光照处理和顶点坐标变换一起构成了Direct3D图形显示的第一阶段:顶点坐标变换和光照流水线。

5.1光照计算模型

Direct3D光照计算模型包括4种:环境光、漫反射光、镜面反射光和自发光。它们的结合能灵活高效地解决三维图形程序中的光照问题。当然,程序员也完全可以编写自己的光照计算模型,来进行光照计算。

1.环境光

一个物体即使没有直接被光源照射,但只要有光线通过其他物体的折射、反射到达该物体,它也能被看见。

在基本光照模型中,可以在一个场景中设置一个基准光亮度,可以简单地模拟一种从不同物体表面所产生的反射光的统一照明,称为环境光(ambient light)或背景光。环境光没有位置或方向上的特征,只有一个颜色亮度值,而且不会衰减。

2.漫反射

太阳的直射、日光灯的照射都可以用漫反射光照模型来近似。不同于环境光,漫反射光的空间位置和方向对物体的照明有很大的影响。图形系统中物体表面顶点P的漫反射颜色值I_diffuse的计算公式为:I_diffuse=k·I_light·cosθ。

如果L和N为单位向量,由几何知识可知,cosθ等于L和N的点积,所以计算公式可变为I_diffuse=k·I_light·(L·N)。

在Direct3D图形系统中,物体表面顶点处的漫反射颜色值就是利用上式计算的。

3.镜面发射

当观察金属物品或玻璃制品的表面时,改变观察点的位置,可以发现玻璃杯表面的亮度值也在发生变化,这种现象往往发生在光滑物体表面,称之为镜面反射。

顶点P的镜面反射颜色值可由下式近似计算:I_specular=K_s·I_light·(cosφ)^n=K_s·I_light·(V·R)^n。

镜面反射的计算量比较大,因此在默认状态下,Direct3D不对物体进行镜面反射计算。

4.自发光

自发光是指对象自己发出的光。自发光其实就是通过对象的自发光材质实现的。

5.对光照计算模型的说明

在图形程序中对物体顶点进行光照计算时,具体采用哪种或哪几种光照计算模型,是由物体表面材质决定的。

环境光、自发光、漫反射光的计算结果作为顶点的漫反射颜色输出。镜面反射光的计算结果作为顶点的镜面反射颜色输出。

5.2光源

光照计算模型说明图形系统以什么样的方法计算灯光照射在物体上的颜色值,它是一种计算方法,而不是具体的灯光。光源则定义了三维场景中具体的灯光,包括位置、方向、强度等信息。

5.2.1光源类型

在Direct3D中支持3种光源类型:方向光(directional light)、点光源(point light)和聚光灯(spot light)。

——和Unity的光源类型是一致的

1.点光源

点光源有颜色和位置,但没有方向。它向所有方向发射的光都一样。

这种光的强度会随着距离物体的远近而衰减,在程序中需要提供点光源的位置、颜色和衰减系数等参数。

2.方向光

方向光有颜色和方向,没有位置。可以把方向光想象成无穷远点处的一个光源。方向光不会衰减,当Direct3D用这种光源计算顶点颜色时,只考虑指定的方向和颜色。这种光的计算量最少。

3.聚光灯

聚光灯有颜色、位置和方向,类似于现实世界中的探照灯。

在Direct3D中,聚光灯成为所有光源类型中最耗时间的光源。

5.2.2光源属性

三维场景的一个光源通过其各种属性来描述。

光源属性包括光的发光位置、方向、颜色和衰减范围等,这些属性可控制光线对物体的照明程度。

每种光源根据其类型只使用其中的几种属性,而不是使用全部属性。

因为一个光源会照亮场景中的多个物体,而这些物体可能会使用不同的光照计算模型进行光照计算,所以这就需要为灯光分别设置用于不同光照计算模型的灯光颜色。
5.2.3设置灯光

在Direct3D中的一个场景中,最多可设置8个光源。

5.2.4对光源的几点说明

Direct3D中的光源是对现实世界中各种光源的抽象。

5.3材质

对于光照计算,光源和材质两者缺一不可,物体表面材质属性决定了它能反射什么颜色的光线以及能反射多少。

物体顶点的颜色亮度总和为:

I_Total=I_Ambient+I_Diffuse+I_Specular+I_Emissive。

chap7使用文件模型

先利用三维建模软件(如3ds Max、Maya等)制作出复杂物体的模型,保存到相应的模型文件中,然后三维图形开发接口再将保存在文件中的模型加载到程序中进行显示。

7.1三维模型基础

Direct3D对使用3ds Max生成的三维模型提供了很好的支持。Maya是Alias|Wavefront公司在1998年才推出的三维制作软件。

通过Direct3D提供的外挂程序(XskinExp.dle、Xexport.mll)可以将它们转换成Direct3D能够识别的数据文件格式(后缀名为.X),这样在Direct3D中载入和渲染文件模型就很方便了。

7.2模型文件格式转换

Direct3D已经为.X文件提供了大量内置的支持,.X文件模型通常是由大量的三角形拼接成的网格模型。

三维建模软件中采用的坐标系通常是右手坐标系,而Direct3D中的坐标系是左手坐标系。Direct3D提供的3ds Max导出插件没有考虑到左手坐标系与右手坐标系的问题,因此给模型的制作和使用造成一些不便。

D3D导入插件根据使用的Maya版本命名,例如D3DMaya6ExportX.mll或者D3DMaya65ExportX.mll。

使用Maya插件不仅能导出生成.X文件,还可以使游戏开发者在Maya中实时地创建、编辑、预览高级渲染语言渲染器(HLSL shaders)。

7.3在Direct3D程序中载入模型

利用.X文件渲染三维模型,首先需要将.X文件中的各种数据分别加载到内存中,主要包括顶点数据、材质数据和纹理数据。

7.3.1网格模型接口ID3DXMESH

7.3.2载入.X文件并生成网格模型

一个三维网格模型通常是由几个子模型组合的,在制作模型时通常为每个子模型分别设置材质和纹理,所以这些子模型就可能使用不同的材质和纹理。

7.4渲染网格模型

7.5三维模型旋转

在现实世界中要完全定位一个物体需要6个参数:物体位置坐标的3个分量(x,y,z)和3个欧拉角(偏航角yaw,俯仰角pitch,横滚角roll)。

3个欧拉角的定义为:

偏航角:物体绕自身y轴(即上向量vUp)旋转的角度;

俯仰角:物体绕自身x轴(即右向量vRight)旋转的角度;

侧倾角:物体绕自身z轴(即前向量vLook)旋转的角度。

7.6使用文件模型的几点提示

1、在制作模型时,在不明显影响视觉效果的前提下,应尽量减少多边形的数量。

2、在制作三维模型注意使模型的尺寸和实物的尺寸保持一致。

3、渲染网格模型时,通常需要进行光照处理和纹理映射,需要对光照和纹理进行相关的设置。

4、在从网格模型数据中提取纹理文件名,为网格模型创建纹理对象时,提取的文件名可能是纹理文件的绝对路径。

5、模型的旋转是绕自身坐标轴的旋转,而不是绕世界坐标系的3个坐标轴旋转,而且在旋转模型时其自身坐标轴也在不断改变。

chap13网格模型高级技术

13.1 .X文件格式分析

.X文件格式最初是为传统的Direct3D保留模式而设计的,在DirectX 6.0问世后,针对立即模式对它作过一次扩展。

13.7骨骼动画网格模型

对于网格模型动画,一般有两种,一种是渐变动画,另一种是骨骼动画,这种动画包含在网格模型之中,通过网格模型不同部分之间的相对运行实现动画。

13.8蒙皮骨骼动画网格模型

chap16 Direct3D GPU编程概述

在Direct3D 9程序中,有两种途径来实现图形渲染,一种称为固定函数流水线,另一种称为可编程流水线。使用可编程流水线技术进行Direct3D程序设计也称为Direct3D GPU编程。

Direct3D 10只支持可编程流水线技术。

16.1可编程流水线

2001年初,nVidia发布了GeForce3, 这也是第一个提供底层控制的显卡。与较早版本的Direct3D 6和Direct3D 7相比,Direct3D 8最大的突破就是增加了可编程流水线。

在DirectX 9中可编程流水线分为可编程顶点渲染流水线和可编程像素渲染流水线,简称顶点渲染和像素渲染。

16.2顶点渲染

顶点渲染的作用是对三维图元的顶点进行坐标变换和光照计算,生成可用于渲染到投影空间的顶点坐标、颜色和纹理坐标。如果启用了顶点渲染,原有的标准固定函数流水线中的坐标变换和光照处理将自动被禁用。

16.3像素渲染

顶点渲染结束后,其结果将送至Direct3D光栅化处理单元进行光栅化处理,也称像素渲染。

如果像素渲染在一个效果(effect)中设计,设置状态将变得更加容易。

16.4渲染语言

几种主流的高级渲染器语言是:NVIDIA发行的Cg、微软新型的高级渲染器语言HLSL、OpenGL ARB所推动发展的glslang。

在Direct3D中可以通过两种语言来编写这些渲染代码,一种是HLSL,另一种是ASM。

chap18 HLSL顶点渲染

chap19 HLSL像素渲染

19.3渲染器的编译与调试

19.3.1渲染器的编译

高级渲染语言(HLSL)渲染器和汇编(ASM)渲染器可以通过DirectX SDK提供的4种工具的命令语句进行编译。

DirectX SDK编译工具

工具名称,作用

fxc.exe,编译HLSL渲染器

flink.exe,联接HLSL段落

vsa.exe,编译汇编顶点渲染器

psa.exe,编译汇编像素渲染器

chap20效果(effect)

效果就是综合管理顶点渲染器和像素渲染器的框架。通过使用效果,可以将顶点渲染和像素渲染统筹起来,而后在主程序中只需加载效果文件(.fx)并从中创建效果接口指针。这样就可以通过该效果接口指针方便地使用顶点渲染器和像素渲染器。

chap5光照与材质

对于光照计算,光源和材质两者缺一不可,物体表面材质属性决定了它能反射什么颜色的光线以及能反射多少。

chap20 效果(effect)

就是综合管理顶点渲染器和像素渲染器的框架。在主程序中只需要加载效果文件(.fx)并从中创建效果接口指针。
20.1效果、技术与通道

一般来说,效果(effect),技术(technique),通道(pass)都是连为一起使用的,一个效果至少要有一个技术,一个技术至少有一个通道,效果中技术数目是没有上限的,技术中的通道数目也没有上限。

11.4可编程管线

11.4.1可编程着色器

在渲染流水线上,存在着两个对开发者可见的可编程着色器。

顶点着色器(vertex shader)。对每个顶点调用一次,完成顶点变换(投影变换和视图模型变换)、法线变换与规格化、纹理坐标生成、纹理坐标变换、光照、颜色材质应用等操作,并最终确定渲染区域。在Cocos2d-x的世界中,精灵和层等都是矩形,它们的一次渲染会调用4次顶点着色器。

段着色器(fragment shader,又称片段着色器)。这个着色器会在每个像素被渲染的时候调用,也就是说,如果我们在屏幕上显示一张320*480的图片,那么像素着色器就会被调用153600次。所幸,在显卡中通常存在不止一个图形处理单元,渲染的过程是并行化的,其渲染效率会比用串行的CPU执行高得多。

这两个着色器不能单独使用,必须成对出现。

实际上需要自己编写着色器的场合并不太多。因此我们将着重介绍如何在Cocos2d-x游戏中导入自定义的着色器效果。

11.4.2 CCGLProgram

引擎提供了CCGLProgram类来处理着色器相关操作,对当前绘图程序进行了封装,其中使用频率最高的应该是获取着色器程序的接口:

const GLuint getProgram();

该接口返回了当前着色器程序的标识符。对象(纹理、着色器程序或其他非标准类型)都是使用整型标识符来表示的。

CCGLProgram提供了两个函数导入着色器程序,支持直接从内存的字符串流载入或是从文件中读取。

initWithVertexShaderByteArray

initWithVertexShaderFilename

11.4.3变量传递

仅仅加载肯定是不够的,我们还需要给着色器传递运行时必要的输入数据。在着色器中存在两种输入数据,分别被标识
为attribute和uniform。

attribute变量是应用程序直接传递给顶点着色器的变量,在段着色器中不能访问。必须为每个顶点指定对应的值。

uniform变量是全局性的,可以同时在顶点着色器和段着色器中访问。

在着色器程序中,不管是顶点着色器还是段着色器,这些变量都是只读的,不允许在渲染过程中改变。



chap16高级着色器语言入门

在DX8.x中,着色器是用低级着色器汇编语言编写的。

16.1编写HLSL着色器

我们在记事本中编写着色器并保存成一般的ASCII文本文件,然后用D3DXCompileShaderFromFile函数来编译它们。

下面是用HLSL编写的一个简单的顶点着色器,用记事本生成并保存成文本文件VertexShader.cxx。

顶点着色器用组合视图和投影矩阵转换顶点,并设置顶点漫射光为红色或蓝色。

全局变量

用来保存视图和投影的组合矩阵,在程序中初始化变量

matrix g_View_proj_matrix;

output.postion=mul(input.position, g_View_proj_matrix);
初始化颜色变量(蓝色)

const Vector BLUE={0.0f,0.0f,1.0f,1.0f};

红色

const Vector RED={1.0f,0.0f,1.0f,1.0f};
//ouput.diffuse=RED;

ouput.diffuse=BLUE;
结构

用来描述输入到着色器的顶点,只包含一个位置成员

struct sVertexInput

{

vector postion:POSITION;

};

用来描述从着色器输出的顶点,包含位置和颜色成员

struct sVertexOutput

{

vector postion:POSITION;

vector diffuse:COLOR;

};

主入口点,这个main函数接收一个Input顶点的拷贝作为参数,返回一个Output顶点的拷贝

sVertexOutput main(sVertexInput input)

{

sVertexOutput output=(sVertexOutput)0;

return output;

}

16.1.1全局变量

第一个变量是矩阵类型,它是一个在HLSL内创建的4*4的矩阵类型。这个变量保存视图与投影的组合矩阵,它描述两者的变换。注意,在着色器源代码的任何地方都没有初始化这个变量,因为它是我们在应用程序的源代码里设置的,而不是在着色器中。从应用程序向着色器程序通讯是常用的操作。

bool setup()

{

g_view_proj_handle=g_constant_table->GetConstantByName(NULL,”g_view_proj_matrix”);

g_constant_table->SetDefaults(g_device);

}

bool display(float time_delta)

{

D3DXMATIX view_proj_matrix=view_matrix*g_proj_matrix;

g_constant_table->SetMatrix(g_device,g_view_proj_handle,&view_proj_matrix);

}

第二个变量是built-in(内建)类型的4D向量,它是个RGBA的颜色向量。
16.1.2输入和输出结构

特殊的冒号是一种语义,用于是声明变量。这与vertex结构中的自由顶点格式(FVF)相似。

16.1.3函数的入口点

mul函数是一个built-in(内建)函数,实现向量与矩阵相乘,或矩阵与矩阵相乘。

16.2编译HLSL着色器

16.2.1常量表

每个着色器有一个常量表,用来保存它的变量。D3DX库通过ID3DXConstantTable接口,提供给应用程序访问着色器的常量表。通过这个接口我们能够在应用程序中设置着色器源代码中的变量。

16.2.1.1取得常量句柄

GetConstantByName

16.2.1.2设置常量

SetXXX

16.2.1.3设置常量默认值

这些默认值在声明时初始化。这个方法应该在应用程序建立期间被一次性调用。

16.2.2编译HLSL着色器

HRESULT hr = D3DXCompileShaderFromFile("VertexShader.cxx", NULL, NULL, "main","vs_2_0"/*"vs_1_1"*/, D3DXSHADER_DEBUG,

&shader_buffer, &error_buffer, &g_constant_table);

pSrcFile——要编译的包含着色器源代码的文本文件的文件名

pFunctionName——指定入口点函数名的字符串

pTarget——指定要编译成的HLSL着色器源文件的版本的字符串。有效的顶点着色器版本是:vs_1_1,vs_2_0,vs_2_sw。有效的像素着色器版本是2.0。

16.3变量类型

注意:除了下列各小节中描述的类型外,HLSL还有一些内建的对象类型(如:纹理对象),但这些对象类型主要用于效果框架。

16.3.1数值类型

HLSL支持下列数值类型:

bool、int、half、float、double

注意:一些平台不支持int,half,double类型,这时我们使用float类型模拟。

16.3.2向量类型

16.3.3矩阵类型

16.3.4数组

16.3.5结构

HLSL里的结构不能有成员函数。

16.3.6typedef关键字

16.3.7变量前缀

static

uniform

extern

shared

volatile

const

16.4关键字、语句和强制转换

16.5操作符

16.6用户定义函数

16.7内建函数

chap22 ASM顶点渲染
01_ASMTransform

检查当前设备支持的顶点渲染版本

pCaps->VertexShaderVersion|4294836992(0xfffe0300)
unsigned long dwVSV=D3DVS_VERSION(2,0);

assert(0xfffe0300>=dwVSV);

dwVSV = 4294836736

dwVSV = 0xfffe0200
unsigned long dwVSV1=D3DVS_VERSION(1,1);

assert(0xfffe0300>=dwVSV1);

dwVSV1 = 4294836481

dwVSV1 = 0xfffe0101
unsigned long dwVSV2=D3DVS_VERSION(3,0);

assert(0xfffe0300>=dwVSV2);

dwVSV2 = 4294836992

dwVSV2 = 0xfffe0300

1.查询顶点渲染器版本

2.创建顶点缓冲区和顶点声明对象

3.创建顶点渲染器对象

调用D3DXAssembleShaderFromFile(),从磁盘文件中读入文本格式的ASM渲染指令,并把它编译成二进制格式的ASM渲染指令。
ASM渲染指令格式类似于Intel汇编指令。

vs_2_0表示顶点渲染的版本号为2.0版本,该指令也是所有ASM顶点渲染指令程序中必需的第一条指令。

4.设置寄存器常量

函数SetVertexShaderConstantF()的作用是定义顶点渲染常量寄存器。

22.3 ASM顶点渲染简介

D3D顶点渲染主要有1.0、1.1、2.0、3.0几个版本,顶点渲染的后续版本是对前面版本指令的改进和扩充。

顶点渲染指令程序主要由以4部分组成:

顶点渲染版本声明

寄存器声明

渲染处理指令

顶点元素输出

1.查询像素渲染版本

pCaps->PixelShaderVersion=4294902528(0xffff0300)

unsigned long dwPSV=D3DPS_VERSION(2,0);

assert(0xffff0300>=dwPSV);

dwPSV = 4294902272

dwPSV = 0xffff0200

unsigned long dwPSV1=D3DPS_VERSION(1,4);

assert(0xffff0300>=dwPSV1);

dwPSV1 = 4294902020

dwPSV1 = 0xffff0104

23.2 ASM像素渲染简介

D3D像素渲染指令主要有1.1、1.2、1.3、1.4、2.0、3.0几个版本,像素渲染指令的后续版本是对前面版本的改进和扩充。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: