(浙江大學(xué) 計算機科學(xué)與技術(shù)學(xué)院, 杭州 310027)
摘 要:
提出了一種實現(xiàn)SlideShow中effect和transition的新方法,即基于GPU的實現(xiàn)方式。論述如何充分發(fā)揮GPU的功能,用Direct3D實現(xiàn)SlideShow中的effect和transition。利用Direct3D中的固定功能流水線能實現(xiàn)多種transition和一些簡單的effect,如掃描、漸隱漸現(xiàn)及圖像旋轉(zhuǎn)等。借助Direct3D中的可編程流水線功能則可實現(xiàn)多種effect,如浮雕、馬賽克等。論述了使用高級渲染語言實現(xiàn)多種特效的方法,并給出了編程示例。
關(guān)鍵詞:圖像處理器;Direct3D;SlideShow;固定功能流水線;可編程流水線;高級渲染語言;頂點渲染;像素渲染
中圖分類號:TP391 文獻標(biāo)志碼: A
文章編號:10013695(2008)12365603
Implement effect and transition in SlideShow based on GPU
CHE Rong, ZHANG Sanyuan
(College of Computer Science Technology, Zhejiang University, Hangzhou 310027, China)
Abstract:
This paper proposed a new method of implementing effects and transitions in SlideShow, which was based on GPU( graphics processing unit ). It discussed how to take advantage of GPU, implement effects and transitions in SlideShow using Direct3D. With the fixed function pipeline, could implement many transitions and some simple effects, such as wipe in/wipe out, fade in/fade out and rotate image. With the programmable function pipeline, we can implement much more effects, such as emboss and mosaic. Discussed using the highlevel shader language to implement effects. And also gave some examples about effects and transitions.
Key words:GPU(graphics processing unit); Direct3D; SlideShow; fixed function pipeline; programmable function pipeline; HLSL(highlevel shader language); vertex shader; pixel shader
現(xiàn)在不少的多媒體管理軟件均有SlideShow功能。SlideShow指的是一張接一張地連續(xù)播放圖片或視頻文件。在每一張圖片上有一些effect,如旋轉(zhuǎn)、浮雕和模糊等。在兩張圖片切換過程中可以做一些transition效果,如移動、百葉窗、漸隱漸現(xiàn)等。SlideShow還可以用做屏幕保護程序。本文主要討論Windows平臺上SlideShow中的effect和transition的實現(xiàn)方式,其他平臺原理是類似的。傳統(tǒng)的實現(xiàn)SlideShow中effect和transition的基本方式是位圖圖像處理[1],即對位圖進行各種圖像處理、圖層混合,然后用GDI函數(shù)顯示處理后的位圖數(shù)據(jù)。其過程可分為以下幾個步驟:a)讀取圖像文件(如BMP、JPG、GIF、TIFF文件等)。圖像文件經(jīng)解壓縮后,保存在系統(tǒng)內(nèi)存中,在內(nèi)存中圖像以DIB位圖(設(shè)備無關(guān)位圖)的形式存在。b)為了實現(xiàn)動態(tài)效果,需要每隔一段時間,更新顯示DIB。這一步根據(jù)原始DIB,經(jīng)位圖圖像處理后,得到經(jīng)處理后的DIB。如果是旋轉(zhuǎn)效果,就將DIB旋轉(zhuǎn),得到新的DIB。如果是浮雕效果,則需要對圖像進行浮雕化處理后,得到要顯示的新DIB。如果要實現(xiàn)漸隱漸現(xiàn)(fade out/fade in)的transition效果,則需要將前一張圖片的DIB和后一張圖片的DIB,根據(jù)透明度變化經(jīng)圖層混合后得到新的DIB。c)用GDI/GDI+函數(shù),如Bitblt或SetDIBitsToDevice函數(shù)顯示經(jīng)處理后的新DIB。
1基于GPU,使用Direct3D來實現(xiàn)effect和transition的原理
以上介紹的實現(xiàn)SlideShow中effect和transition的方式,是用CPU對DIB數(shù)據(jù)進行處理,然后用GDI函數(shù)顯示DIB數(shù)據(jù)。對于分辨率較高的圖形文件,這種處理方式會導(dǎo)致CPU使用率較高。近幾年來,GPU得到了高速的發(fā)展,GPU的高速發(fā)展受到相關(guān)應(yīng)用領(lǐng)域的強大驅(qū)動[2]。大數(shù)據(jù)量的圖形環(huán)境模型以及虛擬現(xiàn)實、計算機仿真、計算機游戲等實時需求向圖形處理提出了越來越高的要求。龐大的市場需求對GPU以及相關(guān)軟硬件的發(fā)展產(chǎn)生了強大的動力。現(xiàn)在,GPU不僅可以實現(xiàn)固定的功能,而且還具有了可編程能力。GPU的優(yōu)勢在于具有很強的并行處理能力,這一點正可以用來對圖像像素進行處理。如果能充分利用圖形處理器的功能,一定可以給人們帶來更好的性能。
DirectX是Microsoft公司開發(fā)的運行于Windows平臺的多媒體控制處理引擎, Direct3D是其API組件之一(現(xiàn)在Direct3D集成于DirectX graphics中),用來實現(xiàn)三維圖形功能。Direct3D使用HAL(hardware abstraction layer)與顯示硬件協(xié)同工作,與GDI不同的是,當(dāng)選擇了HAL設(shè)備時,Direct3D可以利用硬件特性[3]。基于圖形處理器支持的特性集,HAL設(shè)備提供了硬件加速,因而具有更高的效率。Windows平臺上視頻的播放等最終都是通過Direct3D實現(xiàn)的。主流的圖形處理器,如NVIDIA和ATI對Direct3D均有較好的支持。
應(yīng)用Direct3D中的紋理映射功能可以實現(xiàn)多種effect和transition效果。紋理也就是通常所說的貼圖,它通過在三維模型表面覆蓋上二維的圖片,使實體更具有真實感。它是增強計算機生成的三維圖像的真實感的有力工具,紋理映射長期以來一直是現(xiàn)代圖像繪制系統(tǒng)的一個重要組成部分。紋理映射中紋理坐標(biāo)的示意圖如圖1所示。
使用Direct3D中的紋理映射功能實現(xiàn)effect和transition的基本原理是創(chuàng)建具有四個頂點的矩形平面,作為本文的渲染圖元,然后將圖片作為紋理渲染到該平面上。
2使用Direct3D固定功能流水線實現(xiàn)effect和transition
Direct3D有兩種途徑來實現(xiàn)圖形渲染,即固定功能流水線和可編程流水線。Direct3D的每次渲染過程均包括頂點處理(vertex processing)和像素處理(pixel processing)兩個主要功能模塊的執(zhí)行[4]。如果在頂點處理和像素處理過程中執(zhí)行的是一套布在硬件上的固定程序,Direct3D程序員只能設(shè)置一些參數(shù)。就稱為固定功能流水線。可編程流水線是針對固定功能流水線而言的。Direct3D允許寫一段程序替代固定的頂點處理過程和像素處理過程。 其中,替換頂點處理的叫vertex shader,替換像素處理的叫pixel shader。Vertex shader 是一個在圖形卡的GPU上執(zhí)行的程序,它替換了固定功能流水線中的變換(transformation)和光照(lighting)處理 階段。Pixel shader是在對每個像素進行光柵化處理期間在圖形卡的GPU上執(zhí)行的程序。它實際上替換了固定功能流水線的多紋理化階段(multitexturing stage) , 并賦予程序員直接操縱單獨的像素和訪問每個像素的紋理坐標(biāo)的能力。
使用固定功能流水線能實現(xiàn)多種transition效果和一些簡單的effect。其基本方法是通過改變頂點的位置、顏色或紋理坐標(biāo),來影響渲染結(jié)果,實現(xiàn)效果。
21 實現(xiàn)步驟
a)創(chuàng)建具有四個頂點的頂點緩沖區(qū)。設(shè)置頂點格式中包括頂點位置信息xyz、顏色信息和頂點的紋理坐標(biāo)tu、 tv。
b)用圖像文件來創(chuàng)建紋理資源。Direct3D中提供了D3DXCreateTextureFromFile函數(shù)可以直接從圖像文件(如BMP文件或JPG文件等)創(chuàng)建紋理資源,也可以先用IDirect3DDevice9::CreateTexture創(chuàng)建紋理資源,然后lock資源后,將圖像數(shù)據(jù)寫入資源緩沖區(qū)。
c)用紋理資源渲染圖元。本文使用由兩個三角形組成的三角形帶作為圖元。這兩個三角形正好組成一個矩形平面。在渲染時改變頂點的信息就可以實現(xiàn)一些effect,如只需改變頂點的紋理坐標(biāo)就可以實現(xiàn)rotate效果。
d)要實現(xiàn)兩張圖片切換時的transition,可以將前一幅圖片作為第一個紋理層,后一幅圖片作為第二個紋理層。每次渲染時均對這兩個紋理層進行兩趟渲染。通過在兩趟渲染的過程中將兩個紋理貼到同一個圖元的表面,并且每隔一段時間就改變頂點的位置、顏色和紋理坐標(biāo),可完成前后兩幅圖片切換時的動態(tài)過程,即實現(xiàn)一些transition效果。如果GPU能支持多重紋理渲染,則可以在一趟紋理渲染過程中將兩張紋理混合并貼到圖元上,這樣效率會更高。
22 編程實現(xiàn)
224 渲染圖元
在渲染時改變頂點的紋理坐標(biāo),就可以實現(xiàn)rotate效果。以下代碼實現(xiàn)將圖片順時針方向旋轉(zhuǎn)90°。其中,vertex0,1,2,3分別是平面的左上、右上、左下、右下頂點。
CUSTOMVERTEX* pVertices;
hr=g_pVB- >Lock( 0, 0, (void**)pVertices, 0 );
pVertices[0].tu=0.f ; pVertices[0].tv=1.f ;
pVertices[1].tu=0.f ; pVertices[1].tv=0.f ;
pVertices[2].tu=1.f ; pVertices[2].tv=1.f ;
pVertices[3].tu=1.f ; pVertices[3].tv=0.f ;
hr=g_pVB- >Unlock();
if( SUCCEEDED( g_pd3dDevice- >BeginScene() ) )
{
g_pd3dDevice- >SetTexture( 0, g_pTexture ); //設(shè)置紋理
g_pd3dDevice- >SetStreamSource( 0,g_pVB, 0, sizeof(CUSTOMVERTEX) );
g_pd3dDevice- >SetFVF( D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1 );
g_pd3dDevice- >DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);
g_pd3dDevice- >SetTexture( 0 , NULL ) ;
g_pd3dDevice- >EndScene() ;
}
g_pd3dDevice- >Present( NULL, NULL, NULL, NULL) ;
3 使用Direct3D可編程流水線實現(xiàn)更多effect
使用固定功能流水線實現(xiàn)effect和transition具有編程簡單的優(yōu)點,只要改變頂點的位置坐標(biāo)、紋理坐標(biāo)和顏色值,就能實現(xiàn)多種特效。但以上方法也有一些限制,它適用于可以通過幾何位置、顏色和紋理坐標(biāo)變化來實現(xiàn)的特效,如圖片旋轉(zhuǎn)、掃描、移動、百葉窗、漸隱漸現(xiàn)等。對于其他方式實現(xiàn)的effect則不適用。使用Direct3D的可編程流水線則可以幫助人們實現(xiàn)更多的effect。
使用Direct3D可編程流水線技術(shù)也稱為Direct3D GPU編程。在Direct3D中可編程流水線分為可編程頂點渲染和可編程像素渲染,簡稱頂點渲染和像素渲染。對每一種三維數(shù)據(jù)模型,圖形程序設(shè)計人員均可以對它定義特定的頂點坐標(biāo)變換和光照計算程序以及像素渲染方法。Direct3D將根據(jù)每種數(shù)據(jù)特定的渲染計算方法進行渲染,包括頂點渲染和像素渲染。從而大大增強了三維圖形程序的靈活性,并且針對特定數(shù)據(jù)編寫的渲染程序能夠有效地提高圖形程序的執(zhí)行效率。
使用可編程流水線技術(shù),就是使用渲染語言編寫渲染代碼,以實現(xiàn)直接對頂點和像素的操作。在Direct3D中可以通過兩種語言來編寫這些渲染代碼[5],即高級渲染語言HLSL(highlevel shader language)和類似匯編語言的ASM(assembly shader model)。HLSL是一種類似于C的高級語言,它的學(xué)習(xí)和使用相對比較容易,目前它已成為編寫Direct3D頂點渲染和像素渲染的主流語言。在此,筆者也使用HLSL來編寫渲染代碼。HLSL的語法及相關(guān)知識在本文中不再贅述。
使用可編程流水線實現(xiàn)SlideShow中的effect的基本原理是編寫自己的頂點和像素處理代碼,以完成特定的像素處理功能。比如圖片的黑白處理效果、浮雕效果等,GPU具有很強的并行處理能力,所以使用GPU來處理這些可以并行的像素處理具有很高的執(zhí)行效率。
31 實現(xiàn)步驟
a)同固定功能流水線方式。
b)同固定功能流水線方式。
c)創(chuàng)建效果文件。效果(effect)是綜合管理頂點渲染器和像素渲染器的框架。通過使用效果,可以將頂點渲染和像素渲染統(tǒng)籌起來,而后在程序中只需加載效果文件(.fx)并從中創(chuàng)建效果接口指針,然后通過該效果接口指針就可以方便地使用頂點渲染器和像素渲染器了。效果框架中常包括技術(shù)(technique)和通道(pass) 。技術(shù)描述了一種實現(xiàn)效果的方法。一般在一個效果中,至少應(yīng)該有一個技術(shù),一個技術(shù)中也至少應(yīng)該有一個通道。
d)在程序中創(chuàng)建效果,可使用D3DXCreateEffectFromFile()從效果文件中創(chuàng)建效果,函數(shù)返回效果接口指針,然后通過效果接口指針設(shè)置效果全局變量,設(shè)置使用不同的技術(shù),最后渲染一個效果。
32 編程實現(xiàn)
下面以實現(xiàn)灰度浮雕效果為例,來說明如何通過編寫像素渲染代碼來實現(xiàn)SlideShow中的effect。浮雕效果是指圖像的前景前向凸出背景,主要是基于圖像相鄰像素的差值來實現(xiàn)的[6]。對大多數(shù)圖像而言,相鄰像素的差值可能并不大,這樣的話,圖像就有可能變黑。因此,往往在相鄰像素的差值上再加一個常量,這個常量就是浮雕底色或浮雕背景色。本文采用圖像上的一個像素和它左上方的那個像素之間差值再加上一個常量的方式來實現(xiàn)灰度浮雕效果。
321 創(chuàng)建效果文件effectEmboss.fx
float4x4 matWorldViewProj; //組合變換矩陣
float2 TextureDimension ;//紋理的尺寸
// 紋理采樣器
texture TextureMapping;
sampler2D Sampler2D=sampler_state
{Texture=〈TextureMapping〉;
MipFilter=LINEAR;
MinFilter=LINEAR;
MagFilter=LINEAR;
AddressU=WRAP;
AddressV=WRAP;
};
struct VS_OUTPUT
{ // 頂點渲染輸出結(jié)構(gòu)
float4 Position: POSITION;
float2 TextureUV: TEXCOORD0;//紋理坐標(biāo)
};
struct PS_OUTPUT
{ //像素渲染輸出結(jié)構(gòu)
float4 RGBColor : COLOR0; //像素顏色
};
// 頂點渲染器主函數(shù)
VS_OUTPUT VS(float4 Pos : POSITION, float2 vTexCoord0 : TEXCOORD0)
{
VS_OUTPUT Out=(VS_OUTPUT)0;//頂點位置
Out.Position=mul(Pos, matWorldViewProj); //坐標(biāo)變換
Out.TextureUV=vTexCoord0;
return Out;
}
// 像素渲染器主函數(shù)
PS_OUTPUT PS( VS_OUTPUT In)
{ PS_OUTPUT Output=(PS_OUTPUT)0;
float2 UpLeftTextureUV=float2(In.TextureUV.x - 1.0/TextureDimension.x , In.TextureUV.y - 1.0/TextureDimension.y);
float4 bkColor=float4(0.5, 0.5, 0.5, 1.0 );//浮雕背景色
float4 curColor=tex2D( Sampler2D, In.TextureUV ) ;
float4 UpLeftColor=tex2D(Sampler2D, UpLeftTextureUV ) ;
float4 diffColor=curColor - UpLeftColor ;
float Y=0.3 * diffColor.r + 0.59 * diffColor.g + 0.11 * diffColor.b ;//轉(zhuǎn)為灰度圖
Output.RGBColor=float4(Y, Y, Y, 0 ) + bkColor ;
return Output;}
technique TShader
{//技術(shù)
pass P0
{ VertexShader=compile vs_2_0 VS();
PixelShader=compile ps_2_0 PS();
}}
322 加載效果文件,設(shè)置全局變量
hr=D3DXCreateEffectFromFile(g_pd3dDevice, \"C:\\\\EffectEmboss.fx\",NULL,NULL,D3DXSHADER_DEBUG,NULL,g_pEffect,NULL);
D3DSURFACE_DESC surface_dest;
hr=g_pTexture- >GetLevelDesc( 0, surface_dest ) ;
float f[2]={ (float)(surface_dest.Width ), (float)( surface_dest.Height ) } ;
hr=g_pEffect- >SetFloatArray( \"TextureDimension\", f , 2 ) ;
hr=g_pEffect- >SetTexture( \"TextureMapping\", g_pTexture ) ;
hr=g_pEffect- >SetMatrix( \"matWorldViewProj\", mWorldViewProj ) ;
323 渲染效果
D3DXHANDLE hTechnique=g_pEffect- >GetTechniqueByName(\"TShade\" );
HRESULT hr=g_pEffect- >SetTechnique( hTechnique ) ;
hr=g_pEffect- >Begin( nPasses, 0 ) ;
for(UINT iPass=0; iPass < nPasses; iPass++)
{hr=g_pEffect- >BeginPass( iPass);
g_pd3dDevice- >SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX));
g_pd3dDevice- >SetFVF(D3DFVF_XYZ|D3DFVF_TEX1);
g_pd3dDevice- >DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
g_pEffect- >EndPass();
}
hr=g_pEffect- >End();
g_pd3dDevice- >EndScene();
4 結(jié)束語
用Direct3D固定功能流水線實現(xiàn)掃描效果的程序截圖如圖2所示。用Direct3D可編程流水線實現(xiàn)浮雕效果的程序截圖如圖3所示。
基于GPU通過紋理映射的方式實現(xiàn)SlideShow中的effect和transition效果,具有以下優(yōu)點:
a)編程簡單。用固定功能流水線方式,只需改變頂點的坐標(biāo)、顏色值和紋理坐標(biāo),就能實現(xiàn)多種transition。用可編程流水線方式,使用HLSL編寫渲染器代碼相對也是比較簡單的。利用Direct3D的多重紋理渲染或多趟紋理渲染,紋理層的合并是由Direct3D自動完成的,而在傳統(tǒng)的實現(xiàn)方式中,兩個圖層的合并則需要由應(yīng)用層來完成。
b)將GPU的并行處理能力用于圖像像素的處理,充分發(fā)揮了設(shè)備的硬件加速功能。在渲染過程中完成像素的處理,因而具有較高的執(zhí)行效率。同時它可以將CPU解放出來,做其他事情,有效降低CPU的使用率。特別是現(xiàn)在圖片的分辨率均很高,用CPU來處理效率比較低,這一優(yōu)勢就更加明顯。作了一個簡單的測試,處理普通的800×600大小的圖像文件,使用傳統(tǒng)的位圖圖像處理方式實現(xiàn)Pan Zoom和Fade In/Fade Out過渡效果時,CPU的使用率保持在30%~40%。而使用基于GPU的實現(xiàn)方式,CPU的使用率保持在5%以下。對于其他的一些effect和transition,使用GPU的實現(xiàn)方式相對于傳統(tǒng)的方式也有同樣的優(yōu)勢。實驗結(jié)果表明,基于GPU實現(xiàn)SlideShow中的effect和transition這種實現(xiàn)方式有效降低了CPU的使用率。
基于以上這些優(yōu)點,相信這種基于GPU的實現(xiàn)方式將具有很好的應(yīng)用前景。
參考文獻:
[1]周長發(fā).精通Visual C + +圖像編程[M].北京:電子工業(yè)出版社,2000:160.
[2] 吳恩華.圖形處理器用于通用計算的技術(shù)、現(xiàn)狀及其挑戰(zhàn)[J].軟件學(xué)報,2004, 15 (10):14931504.
[3] Microsoft公司.Microsoft DirectX software development kit[EB/OL].(20070727)[20080428].http://www.microsoft.com/downloads/details.aspx?FamilyID=529f03be133948c4bd5a8506e5acf571 DisplayLang=en.
[4] 王弟偉,沈春林.基于Direct3D的HLSL高層著色語言實現(xiàn)圖形著色效果[J].計算機應(yīng)用研究,2006, 23 (11):241243.
[5] 王德才,楊關(guān)勝,孫玉萍.精通Direct3D圖形與動畫程序設(shè)計[M].北京:人民郵電出版社,2007:410.
[6] 潘李亮.Direct3D提高篇:HLSL編程實現(xiàn)PhotoShop濾鏡效果[EB/OL].(20070329)[20080328].http://tech.it168.com/n/20070329/200703291522292.shtml.