OpenGL高級技術(shù)專題二-New_第1頁
OpenGL高級技術(shù)專題二-New_第2頁
OpenGL高級技術(shù)專題二-New_第3頁
OpenGL高級技術(shù)專題二-New_第4頁
OpenGL高級技術(shù)專題二-New_第5頁
已閱讀5頁,還剩90頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

OpenGL高級技術(shù)專題二北京大學(xué)人機交互與多媒體實驗室朱龍佰zlb@2004年5月21日專題內(nèi)容多通道繪制技術(shù)幀緩存應(yīng)用技術(shù)高級反走樣技術(shù)高級線繪制技術(shù)高級紋理映射技術(shù)5多通道繪制技術(shù)關(guān)于多通道繪制技術(shù)定義:在不同的條件下,多次繪制同一場景或場景的一部分,各次繪制的結(jié)果按照一定的邏輯合成最后的圖像.意義:有時在現(xiàn)有的條件下(硬件條件和軟件條件等),不能一次就生成最后的圖像,但通過多次繪制并結(jié)合多次的繪制結(jié)果能生成最后的圖像.例如在硬件或軟件驅(qū)動程序不支持多紋理映射的時候,可以采用多通道繪制技術(shù)來實現(xiàn)多紋理映射,每次應(yīng)用單個紋理進行映射,然后融合各次的結(jié)果.5多通道繪制技術(shù)多通道繪制技術(shù)的應(yīng)用模式獨立模式:每一通道的繪制都是獨立的,后面的繪制不使用前面繪制的結(jié)果,各次繪制沒有順序要求.一般是多次繪制的結(jié)果按照一定的邏輯疊加或融合形成最后的圖像.這是最簡單的多通道繪制模式.例如多通道紋理映射就是這種模式.關(guān)聯(lián)模式:后面的繪制要使用前面的繪制設(shè)置的環(huán)境,各次繪制不能交換順序.最后的圖像一般是最后一次繪制的結(jié)果,但也可能需要疊加或融合前面繪制的部分結(jié)果.這是使用最多的多通道繪制模式,后面的高級技術(shù)中將會大量地使用這種多通道繪制技術(shù).6幀緩存應(yīng)用技術(shù)OpenGL幀緩存與片元測試深度緩存(DepthBuffer)的應(yīng)用模板緩存(StencilBuffer)的應(yīng)用累積緩存(AccumulationBuffer)的應(yīng)用6幀緩存應(yīng)用技術(shù)OpenGL幀緩存與片元測試所有3D加速顯卡都支持的最基本的幀緩存

ColorBuffers&DepthBuffer普通3D加速顯卡基本上都支持的幀緩存

StencilBuffer&AccumulationBuffer高檔3D加速顯卡支持的額外幀緩存

P-Buffer&MultisampleBuffer6幀緩存應(yīng)用技術(shù)OpenGL幀緩存與片元測試片元測試流水線(FragmentOperationsPipeline)6幀緩存應(yīng)用技術(shù)深度緩存的應(yīng)用深度緩存的主要應(yīng)用模式:利用深度緩存以及深度測試構(gòu)造場景在LightSpace中的深度圖(DepthMap);深度圖作為后續(xù)繪制通道的參考,通常將深度圖保存到紋理中.主要應(yīng)用:1陰影(Shadow)2散色(Scatter)3CSG4隱藏線消除5非真實感繪制6幀緩存應(yīng)用技術(shù)模板緩存的應(yīng)用模板緩存的主要應(yīng)用模式:使用模板緩存和模板測試標(biāo)記像素的狀態(tài);結(jié)合多通道繪制技術(shù),每通道繪制都與模板緩存的值比較,并根據(jù)比較結(jié)果修改模板緩存的值.模板緩存是許多特效快速實現(xiàn)的基礎(chǔ)硬件,Doom3就是利用模板緩存實現(xiàn)陰影的.常見的利用模板緩存的應(yīng)用有:鏡面反射(在特效中介紹)陰影繪制物體輪廓(在高級線繪制技術(shù)中介紹)貼花效果(Decal)(在特效中介紹)復(fù)雜平面的模式填充,漸進填充實體幾何造型(CSG)6幀緩存應(yīng)用技術(shù)累積緩存的應(yīng)用累積緩存的主要應(yīng)用模式:使用多通道繪制技術(shù)多次繪制場景,每次繪制都將視圖體稍作抖動,在累積緩存加權(quán)平均所有的繪制結(jié)果.主要應(yīng)用:1反走樣(Antialiasing)2運動模糊(MotionBlur)3景深(DepthofField)4柔和陰影(SoftShadow)5圖象處理(ImageProcessing)6幀緩存應(yīng)用技術(shù)小結(jié)現(xiàn)在有大量的特效是基于幀緩存實現(xiàn)的,3D程序開發(fā)者使用幀緩存設(shè)計了許多巧妙的特效算法,平時可以積累這些技術(shù).幀緩存的應(yīng)用有許多技巧,但基本上都是基于幀緩存的主要應(yīng)用模式開發(fā)的.7高級反走樣技術(shù)走樣(Aliasing)與反走樣(Antialiasing)基于AlphaBlending的反走樣基于Super-sampling的反走樣基于Multisample的全屏反走樣FSAA(Full-ScreenAntialiasing)7高級反走樣技術(shù)走樣與反走樣定義:圖形信號是連續(xù)的,而在光柵顯示系統(tǒng)中,用來表示圖形的卻是一個個離散的象素.這種用離散量表示連續(xù)量引起的失真現(xiàn)象稱之為走樣(Aliasing),也稱為混淆;用于減少或消除這種現(xiàn)象的技術(shù)稱為反走樣(Antialiasing).典型的走樣:鋸齒線,鋸齒邊,細節(jié)失真,狹小圖形遺失等。7高級反走樣技術(shù)走樣與反走樣AliasingSceneAntialiasingScene7高級反走樣技術(shù)基于AlphaBlending的反走樣基本原理:將直線看作是單像素寬度的矩形,像素看作是有面積的正方形;對與直線相交的每個像素,計算其被直線覆蓋的面積占像素面積的百分比a,用a作為Alpha值,與幀緩存中已有的像素的顏色值混合(Blend),產(chǎn)生該像素最后的顏色值.由于要計算像素面積覆蓋,所以AlphaBlending反走樣本質(zhì)上是基于Area-Sampling的.0.43140.59760.07280.12220.36540.68770.06950.10120.05980.57440.38330.10110.03340.63020.32550.05790.89440.90510.83020.87467高級反走樣技術(shù)基于AlphaBending的反走樣OpenGL的實現(xiàn)啟用混合glEnable(GL_BLEND)glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)啟用反走樣glEnable(GLenumcap)cap:GL_POINT_SMOOTH,GL_LINE_SMOOTH,GL_POLYGON_SMOOTH設(shè)置反走樣質(zhì)量glHint(GLenumtarget,GLenummode)target:GL_POINT_SMOOTH_HINT

//點平滑(反走樣)質(zhì)量

GL_LINE_SMOOTH_HINT

//線平滑(反走樣)質(zhì)量

GL_POLYGON_SMOOTH_HINT

//多邊形平滑(反走樣)質(zhì)量mode:GL_FASTEST

//最快的模式

GL_NICEST

//最好的模式

GL_DONT_CARE

//任何模式均可7高級反走樣技術(shù)基于AlphaBlending的反走樣局限性因為是基于AlphaBlending的,就相當(dāng)于繪制透明對象,所以要求對場景中的對象排序,按照由遠到近(Back-to-Front)的順序繪制,否則就會產(chǎn)生錯誤的反走樣結(jié)果.反走樣的代價與場景的幾何復(fù)雜性成正比,對于幾何結(jié)構(gòu)非常復(fù)雜的場景,用AlphaBlending反走樣將會嚴(yán)重地降低繪制效率.所以不適合全屏反走樣.基于AlphaBlending的,自然需要有Alpha通道,但是目標(biāo)顏色緩存并不一定存在Alpha通道.當(dāng)然現(xiàn)在的顯卡都支持Alpha通道,這不會是一個問題.7高級反走樣技術(shù)基于Super-sampling的反走樣Super-sampling:把一個像素(Pixel)看作是由若干子像素(Sub-pixel)構(gòu)成的整體,計算每個子像素的值,將這些值加權(quán)平均作為像素的值.7高級反走樣技術(shù)基于Super-sampling的反走樣Super-sampling實現(xiàn):不可能直接采樣子像素,但有一種近似的間接子像素采樣方式:將場景作子像素偏移(Sub-pixelOffset),使子像素偏移到其所屬像素的中心,此時所得的像素值便可看作是子像素的值.Sub-pixelScreenPixelGridSub-pixelOffset7高級反走樣技術(shù)基于Super-sampling的反走樣OpenGL的支持:基于Super-sampling的反走樣需要累積子像素,也就是要累積每次偏移后繪制的圖像,最后求平均值,作為場景的最終繪制結(jié)果.累積緩存(AccumulationBuffer)正好可以實現(xiàn)此功能.OpenGL實現(xiàn)過程://循環(huán)一定次數(shù)(等于一個像素包含的子像素個數(shù)),累積圖像For(jitter=0;jitter<ACC_NUM;jitter++){ 1.清除顏色緩存和深度緩存等:glClear

2.偏移場景3.繪制場景

4.累積繪制的結(jié)果:glAccum(GL_ACCUM,1.0/ACC_NUM)}5.返回累積且已做了平均的結(jié)果:glAccum(GL_RETURN,1.0)7高級反走樣技術(shù)基于Super-sampling的反走樣場景偏移的實現(xiàn)方法偏移場景就是要抖動視圖體(ViewVolume),視圖體是由投影矩陣(ProjectionMatrix)和模視矩陣(Model-viewMatrix)定義的,所以修改投影矩陣或模式矩陣可以抖動視圖體.一般來說將子像素偏移換算為投影矩陣的抖動值比較容易,所以一般是修改投影矩陣.但對正交投影來說,抖動模視矩陣也比較容易.7高級反走樣技術(shù)基于Super-sampling的反走樣場景偏移:正交投影修改模式矩陣,透視投影修改投影矩陣.正交投影(OrthographicProjection)場景的偏移方法:voidortho_jitter(GLfloatxoff,GLfloatyoff){ GLintviewport[4];GLfloatortho[16];GLfloatscalex,scaley;glGetIntegerv(GL_VIEWPORT,viewport);glGetFloatv(GL_PROJECTION_MATRIX,ortho);scalex=(2.0f/ortho[0])/viewport[2];//(right–left)/viewport[2]scaley=(2.0f/ortho[5])/viewport[3];//(top–bottom)/viewport[3]glTranslatef(xoff*scalex,yoff*scaley,0.0f);}7高級反走樣技術(shù)基于Super-sampling的反走樣透視投影(PerspectiveProjection)的場景偏移方法:voidfrustum_jitter(GLdoubleleft,GLdoubleright,GLdoublebottom,GLdoubletop,GLdoublenear,GLdoublefar,GLdoublexoff,GLdoubleyoff){GLfloatscalex,scaley;GLintviewport[4];glGetIntegerv(GL_VIEWPORT,viewport);scalex=(right-left)/viewport[2];scaley=(top-bottom)/viewport[3];

glFrustum(left-xoff*scalex,right-xoff*scalex,top-yoff*scaley,bottom-yoff*scaley,near,far);}7高級反走樣技術(shù)基于Super-sampling的反走樣采樣抖動值(偏移值):采樣抖動值的選擇要盡量使子像素在像素矩形內(nèi)均勻分布,或者是成Gaussian分布.教材上提供了一些抖動的經(jīng)驗值,可以參考使用.7高級反走樣技術(shù)基于Super-sampling的反走樣基于Super-sampling的反走樣是完全基于圖像空間的反走樣,所以反走樣代價與場景幾何復(fù)雜性無關(guān),只與圖像分辨率有關(guān).不依賴于場景中對象的繪制順序,不需要預(yù)先對場景中的對象做back-to-front排序.使用簡單,所有繪制及狀態(tài)設(shè)置都不需要變化,只需在每次繪制時修改投影矩陣或模視矩陣.顯然,基于Super-sampling的反走樣是基于多通道繪制的,反走樣的質(zhì)量與繪制通道數(shù)成正比,反走樣的代價也與繪制通道數(shù)成正比,而繪制通道數(shù)是很容易控制的,所以可以在質(zhì)量和效率之間作平滑的過渡.基于Super-sampling的反走樣代價較高,而且需要有硬件的累積緩存支持.7高級反走樣技術(shù)基于Multisample的全屏反走樣(FSAA)像素(Pixel)與樣品(Sample):樣品是像素矩形內(nèi)的一個采樣點,相當(dāng)于一個子像素,一個像素內(nèi)可包含多個采樣點,這樣的像素就是Multisample像素.樣品也具有深度和模板信息,對它們的操作同對像素的深度和模板信息的操作一樣.7高級反走樣技術(shù)基于Multisample的全屏反走樣(FSAA)基本原理:像素值是其包含的樣品值的加權(quán)平均.這與Super-sampling反走樣相似.不同的是:Multisample中的子像素(Sample)是確實存在的,其值是真實的計算結(jié)果;而Super-sampling中的子像素是虛擬的,其值是間接的近似結(jié)果.Multisample反走樣其實就是預(yù)先計算一個更高分辨率的圖像,然后從該高分辨率圖像中采樣獲取用于顯示的低分辨率圖像,而采樣過程的加權(quán)平均類似一個低通濾波,可起到平滑邊界的作用,從而實現(xiàn)反走樣.7高級反走樣技術(shù)基于Multisample的全屏反走樣(FSAA)硬件的支持可實現(xiàn)Multisample反走樣的硬件提供了額外的sample緩存,稱為MultisampleBuffer,sample的值(顏色,深度,模板值)都保存在此緩存中.所以這需要消耗更多的顯存(VideoMemory).當(dāng)包含MultisampleBuffer時,就不存在單獨的Z-Buffer和StencilBuffer,即使不需要存儲深度值和模板值.但MutilsampleBuffer和ColorBuffers(right/left,front/back,aux)是并存的.支持Multisample時所需的顯存容量:Vid_mem=sizeof(Front_buffer)+sizeof(Back_buffer)+num_samples*(sizeof(Front_buffer)+sizeof(ZS_buffer))7高級反走樣技術(shù)基于Multisample的全屏反走樣OpenGL實現(xiàn)OpenGL對Multisample的擴展WGL_ARB_pixel_format//查詢像素格式擴展

WGL_ARB_multisample//查詢Multisample像素格式

GL_ARB_multisample//Multisample功能擴展GL_NV_multisample_filter_hint//Multisample過濾核設(shè)置擴展實現(xiàn)Multisample反走樣的一般步驟1.查詢支持Multisample的像素格式2.選擇并設(shè)置支持Multisample的像素格式

3.啟用Multisample功能

7高級反走樣技術(shù)基于Multisample的全屏反走樣OpenGL實現(xiàn)查詢支持Multisample的像素格式:設(shè)置Multisample像素格式前一般首先查詢哪種像素格式支持Multisample.使用查詢像素格式擴展函數(shù)可以實現(xiàn)像素格式查詢.查詢像素格式擴展函數(shù):BOOLwglGetPixelFormatAttribivARB(HDChdc,//繪制設(shè)備句柄,使用GetDCintiPixelFormat,//指定的像素格式intiLayerPlane,UINTnAttributes,//查詢的屬性的個數(shù)constint*piAttributes,//查詢的屬性int*piValues);//返回的屬性值7高級反走樣技術(shù)基于Multisample的全屏反走樣OpenGL實現(xiàn)選擇支持Multisample的像素格式:使用以前的像素格式選擇函數(shù)(ChoosePixelFormat)無法選擇支持Multisample的像素格式,使用選擇像素格式擴展可實現(xiàn)此功能.設(shè)置像素格式仍然使用原來的SetPixelFormat函數(shù).選擇像素格式的擴展BOOLwglChoosePixelFormatARB(HDChdc,//繪制設(shè)備句柄constint*piAttribIList,//整數(shù)表示的(Type,Value)表constFLOAT*pfAttribFList,//浮點數(shù)表示的(Type,Value)表UINTnMaxFormats,//要求返回的最多像素格式int*piFormats,//返回的匹配像素格式列表UINT*nNumFormats);//返回的匹配像素格式個數(shù)7高級反走樣技術(shù)基于Multisample的全屏反走樣OpenGL實現(xiàn)像素格式屬性中與Multisample相關(guān)的兩個屬性

WGL_SAMPLE_BUFFERS_ARB//是否支持Multisample的屬性WGL_SAMPLES_ARB//單位像素的Sample個數(shù)屬性查詢支持Multisample的像素格式舉例intiAttributes[3];intiResults[3];iAttributes[0]=WGL_DOUBLE_BUFFER_ARB;iAttributes[1]=WGL_SAMPLE_BUFFERS_ARB;iAttributes[2]=0;status=wglGetPixelFormatAttribivARB(hDC,

pxlfmt,0,

2,

iAttributes,

iResults);7高級反走樣技術(shù)基于Multisample的全屏反走樣OpenGL實現(xiàn)選擇支持Multisample像素格式舉例intpixelFormat,numFormats;floatfAttributes[]={0,0};intiAttributes[8];iAttributes[0]

=WGL_DOUBLE_BUFFER_ARB,;iAttributes[1]=TRUE;iAttributes[2]=WGL_SAMPLE_BUFFERS_ARB;iAttributes[3]=TRUE;iAttributes[4]=WGL_SAMPLES_ARB;iAttributes[5]=2;iAttributes[6]=0;iAttributes[7]=0;status=wglChoosePixelFormat(hDC,iAttributes,fAttributes,1,&pixelFormat,&numFormats);7高級反走樣技術(shù)基于Multisample的全屏反走樣OpenGL實現(xiàn)啟用/禁用Multisample功能

與Multisample開關(guān)相關(guān)的擴展?fàn)顟B(tài)變量

GL_MULTISAMPLE_ARB

啟用Multisample:glEnable(GL_MULTISAMPLE_ARB)

禁用Multisample:glDisable(GL_MULTISAMPLE_ARB)注:啟用Multisample反走樣功能后,GL_POINT_SMOOTH,GL_LINE_SMOOTH和GL_POLYGON_SMOOTH等功能就無效了,即不能再進行基于AlphaBlending的反走樣.7高級反走樣技術(shù)基于Multisample的全屏反走樣Multisample過濾核(FilterKernel)過濾核就是用來加權(quán)平均Samples的權(quán)重模板(Mask)4Sample4TapBox

Multi-Sampling4Sample9TapBox

Multi-Sampling7高級反走樣技術(shù)基于Multisample的全屏反走樣設(shè)置Multisample過濾核NAVIDAI提供了1個與過濾核設(shè)置相關(guān)的擴展?fàn)顟B(tài)GL_MULTISAMPLE_FILTER_HINT_NV用glHint函數(shù)來設(shè)置過濾核,有兩種模式:GL_FASTEST,GL_NICESTglHint(GL_MULTISAMPLE_FILTER_HINT_NV,GL_FASTEST);glHint(GL_MULTISAMPLE_FILTER_HINT_NV,GL_NICEST);SamplesFASTESTNICEST22Samples2TapsBox2Samples5TapsQuincunx44Samples4TapsBox4Samples9TapsBox7高級反走樣技術(shù)基于Multisample的全屏反走樣2sample2tap4sample9tap2sample5tap4sample4tap7高級反走樣技術(shù)基于Multisample的全屏反走樣基于Multisample的反走樣不同與基于Super-sampling的反走樣,基于Multisample的反走樣是一次繪制實現(xiàn)的,所以效率比Super-sampling高得多.基于Multisample的反走樣的代價同樣與場景的幾何復(fù)雜性無關(guān),不依賴于場景中對象的繪制順序.基于Multisample的反走樣已成為衡量現(xiàn)代顯卡性能的重要指標(biāo)之一.7高級反走樣技術(shù)References[1]TheAccumulationBuffer:HardwareSupportforHigh-QualityRendering.PaulHaeBerli,KurtAkeley.ACMSIGGRAPH1990.(經(jīng)典論文)[2]ANewSimpleandEfficientAntialiasingwithSubpixelMasks.AndreasSchilling.ACMSIGGRAPH1991.[3]OpenGLPixelFormatsandMultisampleAntialiasing.SebastienDomine.NVIDIA,2001.8高級線繪制技術(shù)常用的線繪制方式隱藏線消除(HiddenLineRemoval)輪廓線繪制(SilhouetteEdges)

小結(jié)8高級線繪制技術(shù)常用的線繪制方式采用線繪制模式繪制多邊形.glPolygonMode(GL_FRONT_AND_BACK,GL_LINE)使用簡單,但效率較低,因為繪制多邊形需要一些額外的處理,且被兩個多邊形共享的線段需要繪制兩次.兩次繪制同一條線,在某些情況下可能產(chǎn)生錯誤的結(jié)果.例如反走樣時,會使繪制兩次的部分更亮.直接繪制線,繪制時可以判斷是否在重復(fù)繪制同一線段,從而使每條線段只繪制一次.glBegin(GL_LINES)glBegin(GL_LINE_LOOP)glBegin(GL_LINE_STRIP)8高級線繪制技術(shù)隱藏線消除TeapotwithouthiddenlinesTeapotwithhiddenlines8高級線繪制技術(shù)隱藏線消除使用深度緩存的2通道繪制的OpenGL實現(xiàn):1.禁寫顏色緩存

glColorMask(0,0,0,0);2.啟用深度測試

glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);3.以多邊形填充模式繪制對象,要使用多邊形偏移(Pass1)

glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);glPolygonOffset(1.1f,4.0f);glEnable(GL_POLYGON_OFFSET_FILL);//啟用多邊形偏移drawScene();

glDisable(GL_POLYGON_OFFSET_FILL);4.啟用顏色緩存

glColorMask(1,1,1,1);5.采用兩種線繪制方式之一繪制對象中包含的線段(Pass2).8高級線繪制技術(shù)輪廓線繪制輪廓(Silhouette):將一束平行光沿視線方向照射物體,在物體背面的屏幕上形成的2D圖像的邊界.輪廓線繪制是非真實感繪制(NPR)應(yīng)用的主要技術(shù)之一.Silhouette與Contour:Contour一般也譯為輪廓,但Contour與Silhouette是有區(qū)別的,Contour是Silhouette的子集。Silhouette譯為側(cè)面影象更貼切一些.SilhouetteEye8高級線繪制技術(shù)輪廓線繪制使用模板緩存的5通道繪制的OpenGL實現(xiàn)1.獲取視口glGetIntegerv(GL_VIEWPORT,vRect);2.禁用深度緩存,禁寫顏色緩存glDisable(GL_DEPTH_TEST);glColorMask(0,0,0,0);3.設(shè)置模板測試為始終通過狀態(tài),并用參考值代替模板緩存中的值glEnable(GL_STENCIL_TEST);glStencilFunc(GL_ALWAYS,1,1);glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);4.在多邊形填充模式下繪制對象(Pass1)5.設(shè)置模板測試在模板值為0時通過,且保持原模板值glStencilFunc(GL_EQUAL,0,~0);glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);6.使顏色緩存可寫glColorMask(1,1,1,1);8高級線繪制技術(shù)輪廓線繪制使用模板緩存的5通道繪制的OpenGL實現(xiàn)7.將視口向y正方向平移1個像素單位,繪制對象(Pass2)glViewport(vRect[0],vRect[1]+1,vRect[2],vRect[3]);8.將視口向y負方向平移1個像素單位,繪制對象(Pass3)glViewport(vRect[0],vRect[1]-1,vRect[2],vRect[3]);9.將視口向x正方向平移一個像素單位,繪制對象(Pass4)glViewport(vRect[0]+1,vRect[1],vRect[2],vRect[3]);10.將視口向x負方向平移一個像素單位,繪制對象(Pass5)glViewport(vRect[0]-1,vRect[1],vRect[2],vRect[3]);11.回復(fù)視口原位置glViewport(vRect[0],vRect[1],vRect[2],vRect[3]);8高級線繪制技術(shù)輪廓線繪制結(jié)合模板緩存和深度緩存的3通道繪制的OpenGL實現(xiàn).1.清除顏色緩存和模板緩存,清除深度緩存2.啟用深度測試,禁用模板測試,禁寫顏色緩存glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);glDepthMask(1);glDisable(GL_STENCIL_TEST);glColorMask(0,0,0,0);3.在填充模式下繪制對象,并使多邊形向遠剪切面偏移(Pass1)glEnable(GL_POLYGON_OFFSET_FILL);glPolygonOffset(1.0f,2.0f);renderobjects;4.禁寫深度緩存,禁用多邊形偏移glDisable(GL_POLYGON_OFFSET_FILL);glDepthMask(0);8高級線繪制技術(shù)輪廓線繪制結(jié)合模板緩存和深度緩存的3通道繪制的OpenGL實現(xiàn).5.設(shè)置模板測試一直通過,并在通過深度測試時對模板值求反glEnable(GL_STENCIL_TEST);glStencilFunc(GL_ALWAYS,0,0);glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);6.啟用面剪切,剪切掉背面glEnable(GL_CULL_FACE);7.在多邊形線繪制模式下繪制對象(Pass2)glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);renderobjects;8.使顏色緩存可寫,禁用面剪切g(shù)lColorMask(1,1,1,1);glDisable(GL_CULL_FACE);9.設(shè)置模板測試為在模板值為1通過glStencilFunc(GL_EQUAL,1,1);glStenciOp(GL_KEEP,GL_KEEP,GL_KEEP);glDisable(GL_DEPTH_TEST);10.繪制一個能夠覆蓋整個視口的矩形(Pass3)8高級線繪制技術(shù)輪廓線繪制以上兩個方法產(chǎn)生的結(jié)果并不完全相同,第2個輪廓線繪制算法除繪制了輪廓線外,還繪制了邊界線(TrueEdges).盡管這不太正確,但有時候也是需要這種效果的,因為這樣更加容易識別對象的形狀.Silhouette+TrueEdgesSilhouette8高級線繪制技術(shù)線繪制技術(shù)小結(jié)這里介紹的線繪制技術(shù)都是多通道繪制,且都使用了幀緩存(主要是深度緩存和模板緩存).前面的繪制通道用幀緩存為后面的繪制通道設(shè)定條件,多個繪制通道結(jié)合在一起形成最后的條件,這個條件一般就標(biāo)記了最后需要繪制的線.基于幀緩存的線繪制技術(shù)都是基于圖像空間的算法,基于圖像空間的算法的好處就是速度快,與場景復(fù)雜度無關(guān),只與圖像分辨率有關(guān).但基于圖像空間的算法容易走樣,特別是依賴于深度緩存的算法,由于深度緩存的不精確性和多邊形深度值計算的差異性,使得結(jié)果常常帶有錯誤的痕跡.使用了深度緩存的繪制技術(shù),一般都要使用多變形偏移(glPolygonOffset).8高級線繪制技術(shù)References[1]ADeveloper’sGuidetoSilhouetteAlgorithmforPolygonalModel.TobiasIsenberg,IEEEComputerSociety,2003.[2]SilhouetteLineDisplayfromShadedModels.P.Rustagi,IrisUniverse,Fall1989,pp.42-44.[3]

Algorithmfordrawingboundaryplussilhouetteedgesforasolid.K.Akeley,PersonalCommunication,1998.9高級紋理映射技術(shù)投影紋理映射(ProjectiveMapping)環(huán)境紋理映射(EnvironmentMapping)9高級紋理映射技術(shù)投影紋理映射ProjectiveTextureMapping[FromNVIDIAOpenGLSDK.Projspot]9高級紋理映射技術(shù)陰影紋理映射ShadowTextureMapping[Fromdemos.ShadowMapping]9高級紋理映射技術(shù)投影紋理映射的原理9高級紋理映射技術(shù)投影紋理映射的原理9高級紋理映射技術(shù)投影紋理坐標(biāo)的產(chǎn)生投影紋理映射的核心問題是:給場景中每個頂點(x,y,z,w)按照投影的原理產(chǎn)生一個紋理坐標(biāo)(s,t,r,q),通過該坐標(biāo)索引投影紋理的圖像.即尋找一個變換T,使得:

sxt=Tyrzqw9高級紋理映射技術(shù)投影紋理坐標(biāo)的產(chǎn)生

Pp:ProjectorProjectionMatrixVp:ProjectorViewMatrixVe-1:InverseofEye(Camera)ViewMatrixThefirstmatrix:Map[-1,1]to[0,1]9高級紋理映射技術(shù)投影紋理坐標(biāo)的產(chǎn)生-OpenGL實現(xiàn)OpenGL中除Model-ViewMatrix,ProjectionMatrix外,還有一個TextureMatrix.TextureMatrix就是用來變換紋理坐標(biāo)的.OpenGL中有自動產(chǎn)生紋理坐標(biāo)的函數(shù):glTexGen{d,f,i}[v]glGenTexfv(GLenumcoord,GLenumpname,constGLfloat*params)coord:GL_S,GL_T,GL_R,GL_Q;pname:GL_EYE_PLANEparams:(p1,p2,p3,p4)

glGenTexf(GLenumcoord,GLenumpname,GLenumGLfloat)coord:GL_S,GL_T,GL_R,GL_Q;pname:GL_TEXTURE_GEN_MODEparams:GL_EYE_LINEAR9高級紋理映射技術(shù)投影紋理坐標(biāo)的產(chǎn)生-OpenGL實現(xiàn)

在GL_EYE_LINEAR模式下,紋理坐標(biāo)是這樣計算的:g=x*p1’+y*p2’+z*p3’+w*p4’(p1’,p2’,p3’,p4’)=(p1,p2,p3,p4)*M-1

M-1:當(dāng)前Model-ViewMatrix的逆矩陣,OpenGL在計算GL_EYE_LINEAR紋理坐標(biāo)的時候自動乘以該矩陣.所以進行紋理投影變換的時候,要把Te的最后一個Ve-1除掉,將當(dāng)前Model-View設(shè)為ViewMatrix;或者不除掉Ve-1,而把當(dāng)前Model-View設(shè)為單位矩陣(Identity)

.把Te中除掉Ve-1后的矩陣設(shè)為當(dāng)前TextureMatrix.一種效率更高的方法是不應(yīng)用TextureMatrix,而是直接把(p1,p2,p3,p4)設(shè)為Te的對應(yīng)行:S-row1,T-row2,R-row3,Q-row4.我們一般應(yīng)用此方法.9高級紋理映射技術(shù)投影紋理映射的一般步驟(不考慮遮擋)1計算Projector的ProjectionMatrixglMatrixMode(GL_PROJECTION);……glGetFloatv(GL_PROJECTION_MATRIX);2計算Projector的ViewMatrixglMatrixMode(GL_MODELVIEW);……glGetFloatv(GL_MODELVIEW_MATRIX);3計算Te=Pb*Pp*Pv4產(chǎn)生紋理坐標(biāo)glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);glTexGenfv(GL_S,GL_EYE_PLANE,Te.GetRow(0));glEnable(GL_TEXTURE_GEN_S);5綁定紋理對象,繪制場景glBindTexture(GL_TEXTURE_2D,projectiveTexture);glEnable(GL_TEXTURE_2D);DrawScene();9高級紋理映射技術(shù)投影紋理映射與一般紋理映射的結(jié)合2PassRendering:Pass1:繪制一般紋理映射的場景;Config_Regular_Pass;DrawScene();Pass2:繪制投影紋理映射的場景;glEnable(GL_BLEND);//融合兩幅場景glBlendFunc(GL_ONE,GL_ONE);//簡單的相加融合Config_Projective_Pass;DrawScene();

有遮擋的投影其實就是要產(chǎn)生陰影,要與陰影紋理映射結(jié)合起來.9高級紋理映射技術(shù)投影紋理映射與一般紋理映射的結(jié)合多紋理映射算法:設(shè)置兩個紋理單元,一個應(yīng)用于一般紋理映射,一個應(yīng)用于投影紋理映射.對一般紋理映射,使用glMultiTexCoordARB指定紋理坐標(biāo),而對于投影紋理,則不用指定紋理坐標(biāo),紋理坐標(biāo)采用自動生成方式.TexUnit1:激活紋理單元1,設(shè)置一般紋理映射的過濾參數(shù)、紋理環(huán)境、紋理矩陣等,綁定一般紋理對象.TexUnit2:激活紋理單元2,設(shè)置自動坐標(biāo)產(chǎn)生方式和紋理矩陣等,綁定投影紋理對象.此紋理單元作為投影紋理映射的通道.

多紋理映射算法比多通道算法效率高,因為多紋理映射只繪制一次場景.9高級紋理映射技術(shù)投影映射的幾個問題走樣不確定:過濾投影紋理與一般紋理映射一樣會有過走樣,但在投影紋理中存在走樣不確定:當(dāng)前投影方向正對相機視線的時候,放大過濾走樣最明顯;當(dāng)投影方向與相機視線重合時,走樣最小.9高級紋理映射技術(shù)投影映射的幾個問題背投現(xiàn)象:投影紋理映射不像真正的投影儀,只在一個方向投影,投影紋理映射會產(chǎn)生兩個方向完全相反的投影.如果在背面的投影視錐體內(nèi)有可見對象存在,則在這些對象上也會有投影紋理映射,這顯然是錯誤的.解決方法1:在投影點設(shè)置一個與投影方向垂直的剪切面,在進行投影紋理映射時,啟用該剪切面,從而使得背面的對象不被繪制.解決方法2:使用一個1DTexture(2個紋元0與1),自動紋理坐標(biāo)產(chǎn)生模式為計算頂點到投影面的距離,這樣在正面的頂點索引到的紋元值為1,在背面的頂點索引到的紋元值為0.9高級紋理映射技術(shù)關(guān)于陰影映射(ShadowMapping)Image-spaceshadowdeterminationCompletelyimage-spacealgorithmmeansnoknowledgeofscene’sgeometryisrequiredmustdealwithaliasingartifactsWellknownsoftwarerenderingtechniquePixar’sRenderManusesthealgorithmBasicshadowingtechniqueforToyStory,etc.9高級紋理映射技術(shù)陰影映射的原理light

sourceeye

positiondepthmapZ=Afragment’s

lightZ=Bdepthmapimageplaneeyeviewimageplane,

a.k.a.theframebuffer9高級紋理映射技術(shù)陰影映射的原理light

sourceeye

positiondepthmapZ=Afragment’s

lightZ=Bdepthmapimageplaneeyeviewimageplane,

a.k.a.theframebuffer9高級紋理映射技術(shù)陰影映射的原理—陰影判斷2Pass算法:Pass1:在LightSpace中繪制場景,進行深度測試,深度緩存中的內(nèi)容即是深度圖(DepthMap),或稱為陰影圖(ShadowMap).Pass2:在EyeSpace中繪制場景,對光柵后生成的每個片元(Fragment)P的向量(x,y,z),設(shè)將其變換到LightSpace中后為(x’,y’,z’),設(shè)在深度圖中(x’,y’)位置上的深度值為d,則陰影判斷如下:如果z’>d,則P在陰影區(qū)如果z’<=d,則P在非陰影區(qū)深度圖保存在紋理中,陰影紋理映射就是把EyeSpace中的片元變換到LightSpace后的深度值與深度圖中對應(yīng)位置的深度值進行比較,確定該片元是否在陰影區(qū)中.9高級紋理映射技術(shù)陰影映射—深度圖的構(gòu)造使用深度緩存(z-buffer).繪制場景,進行深度測.使用glPolygonOffset將深度緩存中的值向后稍作偏移.拷貝深度緩存的內(nèi)容到紋理(深度圖).DepthMapFromLightSpaceSceneFromLightSpace9高級紋理映射技術(shù)陰影映射—深度圖的索引(Lookup)顯然,需要把EyeSpace中的向量(x,y,z,w)變換到LightSpace,再變換到深度圖的TextureSpace,得到紋理坐標(biāo)(s,t,r,q).(s/q,t/q)就用來索引深度值.這與投影紋理映射中的將EyeSpace中的點變換到投影紋理空間的過程完全一樣,只不過現(xiàn)在投影紋理換成了深度圖.9高級紋理映射技術(shù)陰影映射—OpenGL的支持1copydepthbuffertotexture函數(shù):voidglCopyTexImage2D(GLenumtarget,

GLintlevel,

GLenuminternalFormat,

GLintx,

GLinty,

GLsizeiwidth,

GLsizeiheight,

GLintborder

)參數(shù):指定internalFormat為GL_DEPTH_COMPONENT.2ShadowComparisonvoidglTexParameteri(

GLenumtarget,

GLenumpname,

GLintparam

)對參數(shù)pname和param擴展以下值來支持陰影比較GL_TEXTURE_COMPARE_MODE_ARB

GL_COMPARE_R_TO_TEXTUREGL_TEXTURE_COMPARE_FUNC_ARBGL_DEPTH_TEXTURE_MODE_ARB

9高級紋理映射技術(shù)陰影映射—OpenGL實現(xiàn)典型的深度圖生成過程glEnable(GL_DEPTH_TEST);//啟用深度測試glDepthFunc(GL_LESS);glEnable(GL_POLYGON_OFFSET_FILL);//啟用多邊形偏移glPolygonOffset(1.1f,4.0f);glColorMask(0,0,0,0);//禁寫顏色緩存drawScene();//繪制場景glEnable(GL_TEXTURE_2D);glGenTextures(1,&depthMap);//創(chuàng)建深度圖紋理對象glBindTexture(GL_TEXTURE_2D,depthMap);//綁定深度紋理glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,0,0,depthMap_sizeX,depthMap_sizeY,0);//拷貝到紋理9高級紋理映射技術(shù)陰影映射—OpenGL實現(xiàn)典型的陰影比較過程glBindTexture(GL_TEXTURE_2D,depthMap);//綁定深度圖紋理glEnable(GL_TEXTURE_2D);//啟用深度比較glTexParameteri(GL_TEXTURE_2D,

GL_TEXTURE_COMPARE_MODE_ARB,

GL_COMPARE_R_TO_TEXTURE);//深度比較函數(shù)(ifr<=texturethennotinshadow)glTexParameteri(GL_TEXTURE_2D,

GL_TEXTURE_COMPARE_FUNC_ARB,GL_LEQUAL);//深度比較應(yīng)產(chǎn)生的結(jié)果的形式glTexParameteri(GL_TEXTURE_2D,

GL_DEPTH_TEXTURE_MODE_ARB,GL_ALPHA);9高級紋理映射技術(shù)陰影映射的一般實現(xiàn)過程3pass算法Pass1:在LightSpace中繪制場景,生成深度圖Pass2:在EyeSpace中繪制只有環(huán)境光照或漫反射光照較弱時的場景.Pass3:啟用陰影映射和自動紋理坐標(biāo)生成,在EyeSpace中繪制有正常光照時的場景.9高級紋理映射技術(shù)References[1]ProjectiveTextureMapping.CassEveritt.NVIDIA./object/Projective_Texture_Mapping.html

[2]FastShadowsandLightingEffectsUsingTextureMapping.MarkSegal.SIGGRAPH1992.(投影映射的原創(chuàng)論文)[3]CastingCurvedShadowsOnCurvedSurfaces.LanceWilliams.SIGGRAPH1978.(陰影映射的原創(chuàng)論文).[4]Renderingantialiasedshadowswithdepthmaps.WilliamReeves.SIGGRAPH87.(陰影反走樣的經(jīng)典論文)[5]ShadowMappingTutorial./tutorials/[6]MSDN.Keyword:glTexGen9高級紋理映射技術(shù)環(huán)境映射(EnvironmentMapping)9高級紋理映射技術(shù)環(huán)境映射定義:將對象周圍的環(huán)境編碼到紋理中,對該對象表面用環(huán)境紋理進行紋理映射,使對象表面呈現(xiàn)出對周圍環(huán)境反射的效果.條件:假設(shè)周圍環(huán)境離對象無限遠,對象本身是不可自反射(Self-reflection)的.這樣對象上某一點的環(huán)境顏色由反射向量(ReflectiveVector)唯一決定.

nerreflectivesurfaceenvironmentmapeye9高級紋理映射技術(shù)環(huán)境映射反射向量的計算

r=e–2(n·e)nenrerre.nAssumingeandnareallnormalized9高級紋理映射技術(shù)環(huán)境映射環(huán)境映射的一般實現(xiàn)過程創(chuàng)建一個或多個二維環(huán)境圖(2DEnvironmentMap)

,將反射體周圍360度范圍內(nèi)的環(huán)境編碼到環(huán)境圖中;計算反射體中每個頂點的法向量(Normal);根據(jù)視點到反射體上一點的視線向量和該點的法向量計算反射向量;使用反射向量計算紋理坐標(biāo)(環(huán)境圖參數(shù)化);使用紋理坐標(biāo)到環(huán)境圖中采樣紋元,對像素進行著色.環(huán)境映射的兩個要點構(gòu)造環(huán)境圖根據(jù)反射向量計算紋理坐標(biāo)環(huán)境映射有三種常用的參數(shù)化方法球面映射(SphereMapping),OpenGL直接支持雙拋物面映射(Dual-paraboloidMapping)立方映射(CubeMapping),OpenGL擴展支持9高級紋理映射技術(shù)球面映射(SphereMapping)球面映射所使用的環(huán)境圖相當(dāng)于在正交投影下看到的一個完全反射球的可見半球面.假定反射球為無限小,與周圍的環(huán)境的距離為無限遠.球面映射使用的環(huán)境圖稱為球面圖(SphereMap).9高級紋理映射技術(shù)球面映射紋理坐標(biāo)的計算

根據(jù)視點指向被繪制頂點的向量V與該頂點的法向量N計算該頂點的球面映射紋理坐標(biāo).9高級紋理映射技術(shù)球面映射OpenGL實現(xiàn)OpenGL能夠自動生成球面紋理坐標(biāo)實現(xiàn)過程:1設(shè)置球面紋理坐標(biāo)自動產(chǎn)生

glEnable(GL_TEXTURE_GEN_S);glEnable(GL_TEXTURE_GEN_T);glTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);glTexGenf(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);2綁定球面紋理,繪制球面映射對象.glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D,sphereMap);drawObject();glTexGenf(GLenumcoord,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP)參數(shù):coord:GL_S,GL_T9高級紋理映射技術(shù)球面映射球面圖的生成1拍攝一個反射球的照片.問題:拍攝的相機會在球面圖中.2用fisheyelens拍攝環(huán)境.問題:fisheyelens不能夠拍攝360度的完整視域.3用程序動態(tài)生成.9高級紋理映射技術(shù)球面紋理映射球面圖的動態(tài)生成1以反射球的中心為相機中心,設(shè)置90度的視角,繪制上下左右前后六個方向的視圖,6個方向上的視口相同,根據(jù)繪制的結(jié)果生成6個紋理(glCopyTexImage2D),形成一個立方圖(CubeMap).相機正對視點生成的那個紋理為立方圖的前面,其它5個紋理根據(jù)這個面依次指定所屬面.LeftViewBottomViewTopViewRightViewBackViewFrontView9高級紋理映射技術(shù)球面映射球面圖的動態(tài)生成2將該立方圖打包成球面圖,立方圖的每個面對應(yīng)球面圖的一個子區(qū)域,立方圖各個面與球面圖的子區(qū)域的對應(yīng)關(guān)系如下圖Front&BackFaceSub-MeshesRight&LeftFaceSub-MeshesTop&BottomFaceSub-Meshes9高級紋理映射技術(shù)球面紋理映射球面圖的動態(tài)生成3計算立方圖上的點到球面圖上的點映射關(guān)系,生成球面圖的網(wǎng)格;根據(jù)該映射關(guān)系指定紋理對象和紋理坐標(biāo),繪制球面網(wǎng)格,拷貝繪制結(jié)果到紋理生成球面圖的紋理.

立方圖與球面圖的映射關(guān)系的計算舉例說明如下:設(shè)y=-1面(BottomView)上一點(0.5,0.5),則其轉(zhuǎn)換為反射向量(0.5,-1,0.5),根據(jù)球面紋理坐標(biāo)的計算公式,計算該反射向量的球面紋理坐標(biāo)(s,t),把(s,t)看作球面圖上的點的位置。9高級紋理映射技術(shù)球面映射的局限性球面映射的結(jié)果雖然很漂亮,但一般來說是不正確的;只有在假設(shè)反射體與被反射體相距無限遠時才是正確的.球面映射是視點相關(guān)(ViewDependent)的,所以視點變化后,需要重新生成球面圖.所以不適合視點經(jīng)常改變的場景繪制.球面紋理坐標(biāo)在頂點上分配,在多邊形內(nèi)插值,然而球面圖是非線性空間,所以這種插值是不正確的.本應(yīng)該跨球面圖邊界插值計算的紋理坐標(biāo)會在球面圖內(nèi)部插值,這是完全錯誤的.ReasonableWrong9高級紋理映射技術(shù)立方

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論