程序推荐图形学hlsl教程_第1页
程序推荐图形学hlsl教程_第2页
程序推荐图形学hlsl教程_第3页
程序推荐图形学hlsl教程_第4页
程序推荐图形学hlsl教程_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

HLSL初级HLSL顶点用顶点器实现渐变动像素多纹理效果的像素HLSLEffect(效果框架Effect本针对HLSL(HighLevelShadingLanguage)初学者,从应用的角度对HLSL、顶点器、助读者尽可能快地理解HLSL编程的概念,掌握HLSL编程的方法。本文档为作者所有,非商业用途可免费使用,请注明出处

1.1Direct3DGraphicsD3DD3D预先固定的,所以这种管道技术被称为固定功能管道(fixedfunctionpipeline); B共同决定,即:A点色彩值*0.7B点色彩值*0.3以上两个问题都可以由可编程管道 blepipeline)来解决PixelProcessing阶段(11)Processing的部分叫做VertexShader(顶Processing的部分叫做VertexShader(顶Direct8.x中,器是通过低级汇编语言来编写的,这样的程序更像是汇编式的指令集合,由(HighLevelShadingLanguage,高级渲染语言)应运而生了。我们可以直接把HLSL器代码作为一长串字符串编写进我们的应用程序源文件中,但是,更加下面是一个完整的HLSL器程序代码,我们把它保存在BasicHLSL.txt中。该器完成顶点的世////Globalvectorcolor;//{vectorposition:{vectorposition:POSITION;vectorcolor:COLOR;//VS_OUTPUTSetColor(VS_INPUT{VS_OUTPUToutput=output.position=mul(input.position,WVPMatrix);output.color=color;return}代码中了两个全局变量vectorcolor;变量color是一个向量类型,它用于设定顶点颜色;局变量在应用程序中赋值而在器程序中使用,这是应用程序和器通信的关键所在。具体赋值过structVS_INPUT{vectorposition:{vectorposition:POSITION;vectorcolor:COLOR;vectorposition:vectorposition:其中,POSITIONCOLOR、NORMAL等很多表示本节所说的输入输出其实是指器代码和编译器、GPU之间的通信,和应用程序是无关的,所以法线、颜色等,这是器代码和编译器、GPU之间通信的关键。1.3.3函OUTPUTSetColor(INPUTinput){VS_OUTPUToutput=output.position=mul(input.position,WVPMatrix);output.color=color;return} 果赋值到output.position;output.color=color;在同一个器代码文件中,可以有多个用户自定义函数,因此在应用程序中需要指定一个做为函数使用1.3.4VS_OUTPUTVS_OUTPUT上述过程中,全局变量在应用程序中赋值而在器程序中使用,这是应用程序和器通信的关键所在;标志符告诉编译器各个输入输出变量的用途(顶点位置、法线、颜色等,这是器代码和编译器、GPU之间通信的关键。个人认为这是器中最为精义的地方:)加载(称为编译更为妥当)器代码把器设定到渲染管道中IDirect3DVertexShader9*BasicShader=0;//顶点器指D3DXHANDLEWVPMatrixHandle =0;D3DXHANDLE = 编译 pileShaderFromFile函数从应用程序外部的文本文件BasicHLSL.txt中编译一个ID3DXBuffer* =ID3DXBuffer* = //器代码文件"SetColor",//函数名D3DXSHADER_DEBUG,//Debug模式编译&BasicConstTable);//常量表创建g_pd3dDevice->CreateVertexShader((DWORD*)shaderBuffer->GetBufferPointer(),&BasicShader);对器中的变量进行赋1.3.4节说到器的全局变量在应用程序中赋值而在器程序中使用,这是应用程序和器通接口对其进行,参照1.4.1中编译器函数pileShaderFromFile的最后一个参数,该参通过变量名称得到指向器变量的句柄vectorcolor;D3DXHANDLE =D3DXHANDLE =ColorHandle=BasicConstTable->GetConstantByName(0,"color"); BasicConstTable-SetXXX(XXXvalueXXXMatrixSetMatrix把器设定到渲染管道这里我们使用SetVertexShader方法把顶点器设定到渲染管道中g_pd3dDevice-g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(153,153,153),1.0f,0);g_pd3dDevice-g_pd3dDevice->GetTransform(D3DTS_WORLD,&matWorld);g_pd3dDevice->GetTransform(D3DTS_VIEW,&matView);D3DXMATRIXmatWVP=matWorld*matView*BasicConstTable->SetMatrix(g_pd3dDevice,WVPMatrixHandle,D3DXVECTOR4color(1.0f,1.0f,0.0f,BasicConstTable->SetVector(g_pd3dDevice,ColorHandle,g_pd3dDevice-g_pd3dDevice-g_pd3dDevice->Present(NULL,NULL,NULL,编译运行程序,运行效果如图1.2所示,这里顶点颜色设置为黄色,如果读者在渲染过程中不断变换对器变量color的赋值,你将会得到一个色彩不断变幻的D3D茶壶。D3DXVECTOR4color(1.0f1.0f0.0f1.0f)读者可以尝试改变颜色值BasicConstTable->SetVector(g_pd3dDevice,ColorHandle,&color);图1.2器效顶点可以被Direct3D运行时(Direct3Druntime)以软件模拟,如果硬件不支持顶点器的话。图2.1说明了管线中顶点器替换的部件。由于顶点器是我们(在HLSL中)写的一个自定义程序,因此我们在图形效果方面获得了极大前的介绍使读者对器的编写和使用都有了一定的了解,下面把重心从介绍如何使用器转DirectX8.0引入了数据流的概念,可以这样理解数据流(22:n个数据流组成。使用更具表达性的并且更强有力的顶点(vertexdeclaration。这只是为了方便,因为FVF会在内部被转换为一个顶点。一个顶点描述为一个D3DVERTEXELEMENT9结构的数组。D3DVERTEXELEMENT9颜色,那么其相应的顶点将会被一个含3个元素的D3DVERTEXELEMENT9结构数组描述。{BYTEBYTEBYTEBYTEBYTEBYTE}Stream——指定关联到顶点分量的Offset——偏移,按字节,相对于顶点结构成员的顶点分量的开始。例如,如果顶点结构是struct{……pos0,因为它是第一个分量;normal12sizeof(pos12。换句话说,normal分量以Vertex的第12个字节为开始。D3DDECLTYPE_FLOAT4——4D浮点向量每一分量都是归一化到区间[0,1]了的。Method——指定网格化方法。我们认为这个参数是高级的,因此我们使用默认值,标识为D3DDECLMETHOD_DEFAULT纹理坐标等,有效的用途标识符(usageidentifier)是D3DDECLUSAGE枚举类型的:typedefenum{ = //D3DDECLUSAGE_BLENDWEIGHTS=1, D3DDECLUSAGE_BLENDINDICES=2, //Blendingindices. =3, //Normalvector. = //Vertexpoint=//Texture=//Tangent=//Binormal=//Tessellation =9, =10,//Color. =11,//Fogblendvalue. =12,//Depthvalue. = //Sampler}基于每个顶点控制其大小。一个D3DDECLUSAGE_POSITION成员的顶点意味着这个顶点已经被变换,它通知图形卡这个顶点送到顶点处理阶段(变形和光照。UsageIndex——用于标识多个相同用途的顶点分量。这个用途索引是位于区间[0,15]间的一个整数。例如,假设我们有三个用途为D3DDECLUSAGE_NORMAL 量,第二个数据流包含位置和纹理坐标2个分量,顶点可以指定如下:{POSITION,0NORMAL,0TEXCOORD,0POSITION,1NORMAL,1},D3DDECL_END宏用于初始化D3DVERTEXELEMENT9数组的最后一个顶点元 函数用于创建顶点声明, 为指向上一小节定义 *g_Decl=NULL;g_pd3dDevice- g_pd3dDevice-用顶点器实现渐变动渐变动画Morphing渐变是20世纪90年代出现的一种性的计算机图形技术,该技术使得动画序列平滑且变到另外一个。请看图2.3:我们在程序中使用两个网格模型——1的坐标为A(Ax,Ay,AzB(Bx,By,Bz所对应的顶点1C(Cx,Cy,Cz,我们使用如下方法:S=t/C=A*(1-S)+B*格模型的数据。渲染过程中,我们在器里根据两个数据流中的顶点数据以及时间值确定最终的顶点顶点指定如下{POSITION,0NORMAL,0TEXCOORD,0POSITION,1NORMAL,1},渐变动画中的顶点下面给出顶点器源码,代码于vs.txt中,该顶点器根据源网格模型数据流和目标网格matrixWVPMatrix;vector//2.3.1小节提到的S=t/T中的时间标尺Svector{vectorposition:POSITION;vectornormal :NORMAL;float2uvCoords:TEXCOORD;vectorposition1:POSITION1;vectornormal1 {vectorposition:POSITION;vectordiffuse :COLOR;float2uvCoords:TEXCOORD;VS_OUTPUTMain(VS_INPUT{VS_OUTPUToutput=型数据流中位置信息input.position1以及时间标尺Scalar的值//对应2.3.1小节中的C=A*(1-S)+B*vectornormal=input.normal*Scalar.x+output.diffusedot((-LightDirectionnormal);output.uvCoords=return}2.3.1小节提到的S=t/T中的时间标尺S值;创建、设置顶点;渲染Mesh模型;…/*********************变量//两个指向 的指针,分别用于源网格模型和目标网格模型 *g_Decl= =D3DXHANDLEWVPMatrixHandle =0;D3DXHANDLE =D3DXHANDLE =…/***************程序初始化{//1ststreamisforsourcemesh-position,normal, D3DDECLUSAGE_POSITION,0 0 D3DDECLUSAGE_TEXCOORD,0//2ndstreamisfortargetmesh-position, D3DDECLUSAGE_POSITION,1 ID3DXBuffer*shader =NULL;ID3DXBuffer* ="Main",//entrypointfunctionname{::MessageBox(0,(char*)errorBuffer->GetBufferPointer(),0,0);}g_pd3dDevice->CreateVertexShader((DWORD*)shader- g_pd3dDevice- ScalarHandle=ConstTable->GetConstantByName(0,"Scalar");LightDirHandle=ConstTable->GetConstantByName(0,"LightDirection");ConstTable-…/*******************渲染g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(153,153,153),1.0f,0);g_pd3dDevice-//为器全局变量WVPMatrix赋g_pd3dDevice->GetTransform(D3DTS_WORLD,&matWorld);g_pd3dDevice->GetTransform(D3DTS_VIEW,&matView);D3DXMATRIXmatWVP;matWVP=matWorld*matView*ConstTable->SetMatrix(g_pd3dDevice,WVPMatrixHandle,floatDolphinTimeFactor=(float)(timeGetTime()%501)/250.0f;floatScalar=(DolphinTimeFactor<=1.0f)?DolphinTimeFactor:(2.0f-ConstTable->SetVector(g_pd3dDevice,ScalarHandle,&D3DXVECTOR4(1.0f-Scalar,Scalar,0.0f,IDirect3DVertexBuffer9*pVB=NULL;g_pd3dDevice->SetStreamSource(1,pVB,0,D3DXGetFVFVertexSize(g_TargetMesh-g_pd3dDevice->SetStreamSource(0,pVB,0,D3DXGetFVFVertexSize(g_TargetMesh-g_pd3dDevice-…程序中我们使用SetStreamSource方法把源网格模型和目标网格模型中的顶点缓存分别绑定到两个设备数据流,但是Direct3D对数据流中的数据的真正只有在调用诸如DrawPrimitive、DrawIndexedPrimitive之类的绘制方法时才发生,因此在绘制Mesh网格模型时我们不能再使用传统的DrawSubmit方法,而是使用了DrawIndexedPrimitive,下面就如何调用DrawIndexedPrimitive绘制Mesh模型进行说明,该部分内容和HLSL器关系不大,在这里列出仅仅是为了大家理解程序的完整性,使用DrawIndexedPrimitive绘制Mesh模型的步骤如 WORDAttribId;//子集编号DWORDDWORDVertexCount; 下面是绘制Mesh模型的程序代码:在Load_Meshes()函数的最后,我们使用OptimizeInce方法对源网格模型和目标网格模型进行优…g_SourceMesh->OptimizeInce(D3DXMESHOPT_ATTRSORT,NULL,NULL,NULL,…g_TargetMesh->OptimizeInce(D3DXMESHOPT_ATTRSORT,NULL,NULL,NULL,……IDirect3DVertexBuffer9*pVB=NULL;IDirect3DIndexBuffer9*pIB =NULL;DWORDNumAttributes;D3DXATTRIBUNGE*pAttributes=NULL;pMesh->GetAttributeTable(pAttributes,&NumAttributes);g_pd3dDevice->SetStreamSource(0,pVB,0,D3DXGetFVFVertexSize(pMesh->GetFVF()));for(DWORD{{//GetmaterialDWORDMatNum=//Setg_pd3dDevice->SetTexture(0,//Drawthemeshg_pd3dDevice- pAttributes[i].FaceStart*3,}} delete[]…编译运行程序,效果如图2.4所示,你将看到屏幕上白色的海豚上下翻腾,同时感受到顶点器像素Direct3D不会以软件模拟像素器的功能。)它实际上替换了固定功能管线的多纹理化阶段(themultitexturingstage),并赋予我们直接单独的像素和每个像素的纹理坐标的能力。这种对像素pixellighting)、景深(depthoffield)、云状物模拟(cloudsimulation)、焰火模拟(firesimulation)、混杂阴影化技巧(sophisticatedshadowingtechnique)。理2中分别采样,得到的颜色值依据一定规则进行组合得到纹理3,这就是多纹理化。多纹理效果的像素下面是像素器的代码,该代码于ps.txt中,该像素器根据输入的两套纹理坐标对对应的纹理贴图进行采样,根据一定比例Scalar混合后输出像素颜色。//颜色混合的比例值s,其//Scalar.x=vectorScalar;texturesamplerSamp0{Texture=<Tex0>;MipFilter=LINEAR;MinFilter=LINEAR;MagFilter=samplerSamp1={Texture=<Tex1>;MipFilter=LINEAR;MinFilter=LINEAR;MagFilter=structPS_INPUT{float2uvCoords0:TEXCOORD0;float2uvCoords1:{float4Color:PS_OUTPUTPS_Main(PS_INPUT{PS_OUTPUToutput=output.Color=tex2D(Samp0,input.uvCoords0)*Scalar.x+tex2D(Samp1,input.uvCoords1)*Scalar.y;returnoutput;} HLSL采样器和和vector、matrix一样,采样器sample和纹理texture也是HLSL语言的一种类型,HLSL器使texturesamplerg_samp{Texture=MipFilterLINEAR;MinFilterLINEAR;MagFiltervectorColor=tex2D(g_samp,…structCUSTOMVERTEX{floatx,y,z;floattu0,tv0;floattu1,tv1;…/*********************变量LPDIRECT3DPIXELSHADER9 = =D3DXHANDLEScalarHandle =0;D3DXHANDLE =D3DXHANDLE =D3DXCONSTANT_DESCLPDIRECT3DVERTEXBUFFER9 =…/********************初始化应用程序CUSTOMVERTEXquad {{-3.0f,-3.0f,10.0f,0.0f,1.0f,0.0f,{- 3.0f,10.0f,0.0f,0.0f,0.0f, 3.0f,-3.0f,10.0f,1.0f,1.0f,1.0f, 3.0f,10.0f,1.0f,0.0f,1.0f,void*ptrNULL;g_pd3dDevice-quadVB->Lock(0,0,(void**)&ptr,0);D3DXCreateTextureFromFile(g_pd3dDevice,"luoqi.jpg",&quadTexture1);D3DCAPS9{MessageBox(0,"NotSupportPixelShader-FAILED",0,0);}ID3DXBuffer* =ID3DXBuffer* =HRESULThr= "PS_Main",//entrypointfunctionname//outputanyerrormessages{}{MessageBox(0," pileShaderFromFile()-FAILED",0,0);returnfalse;}hr=g_pd3dDevice->CreatePixelShader((DWORD*)codeBuffer->GetBufferPointer(),{MessageBox(0,"CreatePixelShader-FAILED",0,0);returnfalse;}ScalarHandle=pixelConstTable->GetConstantByName(0,"Scalar");Samp0Handle=pixelConstTable->GetConstantByName(0,"Samp0");UINTpixelConstTable->GetConstantDesc(Samp0Handle,&Samp0Desc,&count);pixelConstTable->GetConstantDesc(Samp1Handle,&Samp1Desc,&count);pixelConstTable-…/********************渲染 D3DCOLOR_XRGB(153,153,153),1.0f,0);g_pd3dDevice-D3DXVECTOR4scalar(0.5f,0.5f,0.0f,pixelConstTable->SetVector(g_pd3dDevice,ScalarHandle,器器g_pd3dDevice-g_pd3dDevice->SetStreamSource(0,quadVB,0,g_pd3dDevice- g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,g_pd3dDevice-g_pd3dDevice->Present(NULL,NULL,NULL,…Samp1和设定器其他变量稍有不同:Tex0Handle=pixelConstTable->GetConstantByName(0,"Samp0");Tex1Handle=pixelConstTable->GetConstantByName(0,"UINTpixelConstTable->GetConstantDesc(Samp0Handle,&Samp0Desc,&count);pixelConstTable->GetConstantDesc(Samp1Handle,&Samp1Desc,&count);最后通过SetTexture配合所得到的描述信息设置纹理:g_pd3dDevice- 断变换对器变量Scalar的赋值,你将会得到一个混合度不断变换的多纹理效果。D3DXVECTOR4scalar(0.5f0.5f0.0f1.0f读者可以尝试改变混合采用的比例值pixelConstTable->SetVector(g_pd3dDevice,ScalarHandle,&scalar);纹理一纹理二混合后纹理三3.2HLSLEffect(效果框架作为法,Effect简化了使用器的操作;作为一个框架,Effect把顶点器和像素器有机technique{pass{}}technique{pass{}pass{}}technique{pass{}}比较两者之间的异同,体会Effect框架给我们带来了哪些方面的改善。器一个Effect效果框架。 顶点matrix{vectorposition:POSITION;float2uvCoords0:TEXCOORD0;float2uvCoords1:{vectorposition:POSITION;float2uvCoords0:TEXCOORD0;float2uvCoords1:VS_OUTPUTVS_Main(VS_INPUT{VS_OUTPUToutput=output.uvCoords1=return} 像素vectortexturesamplerSamp0={Texture=<Tex0>;MipFilter=LINEAR;MinFilter=LINEAR;MagFilter=samplerSamp1={Texture=<Tex1>;MipFilter=LINEAR;MinFilter=LINEAR;MagFilter=struct{float2uvCoords0:TEXCOORD0;float2uvCoords1:struct{float4Color:PS_OUTPUTPS_Main(PS_INPUT{PS_OUTPUToutput=output.Color=tex2D(Samp0,input.uvCoords0)*Scalar.x+tex2D(Samp1,input.uvCoords1)*Scalar.y;returnoutput;} technique{pass{vertexShader=compilevs_1_1VS_Main();pixelShader=compileps_1_1PS_Main();}}pass{ vertexShader=compilevs_1_1VS_Main();pixelShader=compileps_1_1PS_Main();}pass{…}…structCUSTOMVERTEX{floatx,y,z;floattu0,tv0;floattu1,…/*********************变量//Effect效果 =D3DXHANDLEWVPMatrixHandle D3DXHANDLEScalarHandle =0;D3DXHANDLE =D3DXHANDLE =D3DXHANDLE =LPDIRECT3DVERTEXBUFFER9 =…/********************初始化应用程序CUSTOMVERTEXquad {{-3.0f,-3.0f,10.0f,0.0f,1.0f,0.0f,{- 3.0f,10.0f,0.0f,0.0f,0.0f, 3.0f,-3.0f,10.0f,1.0f,1.0f,1.0f, 3.0f,10.0f,1.0f,0.0f,1.0f,void*ptrNULL;g_pd3dDevice-D3DXCreateTextureFromFile(g_pd3dDevice,"Bleach.jpg",&quadTexture1);D3DCAPS9{MessageBox(0,"NotSupportPix

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论