国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于Unity Shader石油泄漏現(xiàn)象模擬的研究

2020-07-15 05:04劉賢梅葛昊天
關(guān)鍵詞:模擬出偏移量紋理

劉賢梅,葛昊天,趙 婭

(東北石油大學(xué) 計(jì)算機(jī)與信息技術(shù)學(xué)院,黑龍江 大慶 163318)

0 引 言

近年來不斷發(fā)展成熟的虛擬現(xiàn)實(shí)技術(shù)(virtual reality),利用計(jì)算機(jī)圖形學(xué)、三維建模、多媒體等多種技術(shù)手段[1],可以在計(jì)算機(jī)上實(shí)現(xiàn)逼真的三維場景的渲染,為模擬石油生產(chǎn)過程中的意外情況,提高工人的突發(fā)情況應(yīng)急處理能力,應(yīng)急仿真系統(tǒng)應(yīng)運(yùn)而生。在模擬石油泄漏事故的應(yīng)急仿真系統(tǒng)中,石油泄漏現(xiàn)象的流動(dòng)效果的模擬具有重大意義。傳統(tǒng)的模擬方式以粒子系統(tǒng)為主,但是使用粒子系統(tǒng)時(shí),隨著粒子數(shù)目的增加,需要的內(nèi)存增加,運(yùn)行速率也變得很慢。

隨著硬件設(shè)備的不斷發(fā)展,GPU(graphics processing unit,圖形處理單元)性能的大幅度提高,由于GPU的可編程著色器的存在,開發(fā)人員可以通過可編程著色器(Shader)[2],對(duì)頂點(diǎn)及像素進(jìn)行靈活的處理,模擬出更多逼真的效果。2006年上海師范大學(xué)蘇蘊(yùn)等人通過渲染流水線的可編程著色器的控制,完成對(duì)于室內(nèi)光的各種形式(點(diǎn)光源、平行光源等)的真實(shí)感模擬[3]。2015年,海軍航空工程學(xué)院的王彥等人通過可編程著色器完成大面積動(dòng)態(tài)海洋紅外視景仿真,提高了水流的真實(shí)感[4]。因此,針對(duì)石油泄漏的流動(dòng)效果,可以采用可編程著色器(Shader)進(jìn)行模擬,不僅能夠模擬出石油流動(dòng)的效果,還不需要消耗很多內(nèi)存,能夠一直保持一個(gè)較快的運(yùn)行速率。

Unity是一個(gè)專業(yè)的游戲引擎,而Unity的著色器(Unity Shader)是對(duì)著色器上層的一個(gè)抽象,它負(fù)責(zé)將輸入的Mesh(網(wǎng)格)以指定的方式與輸入的貼圖或者顏色等組合作用,輸出紋理[5]。文中首先探討了著色器和著色器語言,并對(duì)Unity Shader的文件結(jié)構(gòu)與分類進(jìn)行探討,然后通過Unity Shader控制底層GPU中的可編程著色器,采用紋理切換方法與基于噪聲的方法對(duì)輸入的貼圖進(jìn)行處理,模擬出石油流動(dòng)的效果。

1 著色器

1.1 著色器與著色器語言

Shader,中文翻譯為“著色器”,其本質(zhì)是作用于渲染流水線上的一段程序,能夠控制渲染流水線的特定階段進(jìn)行計(jì)算,以達(dá)到目標(biāo)效果?,F(xiàn)代可編程渲染流水線的最大特點(diǎn)在于GPU內(nèi)部硬件設(shè)計(jì)具有可編程性,可以通過程序控制GPU內(nèi)部渲染流水線。GPU中的可編程結(jié)構(gòu),包括頂點(diǎn)著色器和片元著色器,即可以針對(duì)頂點(diǎn)和像素進(jìn)行編程[6]。因此,可以在頂點(diǎn)和像素著色器中編寫具有不同功能的程序來處理輸入信息,使整個(gè)處理過程更具靈活性和可控性。

Shader的主流編程語言有HLSL、GLSL、CG。HLSL(high level Shader language)是微軟基于DirectX的語言,只能運(yùn)行在Windows平臺(tái)上[7]。GLSL(OpenGL Shading language),是用在OpenGL中著色編程的語言,也是一門跨平臺(tái)的著色器語言。Cg語言(C for graphics)是為GPU編程設(shè)計(jì)的高級(jí)著色器語言,由NVIDIA公司開發(fā)[8],可作為片段程序鑲嵌在Unity Shader程序中。

1.2 Unity Shader

1.ShaderLab。

為了避免直接控制底層著色器,Unity提供一層抽象——Unity Shader,此外還提供了一種專門為Unity Shader服務(wù)的語言——ShaderLab。它是一種說明性的語言,使用了一些嵌套在花括號(hào)內(nèi)部的語義,這些語義包含了渲染所需的數(shù)據(jù),包括著色器所需的各種屬性[9]。而Unity會(huì)自動(dòng)將ShaderLab文件編譯成控制GPU中各個(gè)著色器的代碼。

2.ShaderLab文件的結(jié)構(gòu)。

一個(gè)ShaderLab的基礎(chǔ)文件結(jié)構(gòu)如下所示:

Shader”ShaderName”

{

Properties{

//屬性

}

SubShader{

//顯卡A使用的著色器

}

SubShader{

//顯卡B使用的著色器

}

......

Fallback”VertexList”

}

對(duì)各個(gè)部分的釋義如下:

(1)Properties。

Properties語義塊中包含了一系列屬性,并且這些屬性會(huì)出現(xiàn)在材質(zhì)面板中,定義方式通常如下:

_Name("Display Name",type)=defaultValue[{options}]

這些屬性的存在是為了能夠更好地調(diào)整材質(zhì)的屬性,方便在著色器中訪問它們?!癉isplay Name”是出現(xiàn)在材質(zhì)面板上的名字,type是屬性的類型,常用的屬性類型如表1所示,defaultValue是指定的默認(rèn)值。

表1 Properties語義塊支持的屬性類型

(2)SubShader。

一個(gè)Shader有多個(gè)SubShader。一個(gè)SubShader可理解為一個(gè)Shader的渲染方案。即SubShader是為了針對(duì)不同的渲染情況而編寫的。每個(gè)Shader至少1個(gè)SubShader。Unity會(huì)掃描所有的Unity Shader,然后選擇第一個(gè)能夠在目標(biāo)平臺(tái)上運(yùn)行的SubShader。SubShader語義塊中包含的定義如下:

SubShader

{

Pass{ }

}

一個(gè)SubShader是由Pass塊來執(zhí)行的。每個(gè)Pass定義了一次完整的渲染流程。在Pass內(nèi),定義了輸入輸出結(jié)構(gòu)體,在結(jié)構(gòu)體中進(jìn)行光照,法線與空間變換等的計(jì)算。

(3)FallBack。

在各個(gè)SubShader語義塊之后,會(huì)存在一個(gè)FallBack,它會(huì)規(guī)定最低級(jí)的Shader是哪一個(gè)。由于一段Shader有可能在不同等級(jí)的顯卡上運(yùn)行,而顯卡的能力也是參差不齊的。所以,F(xiàn)allBack相當(dāng)于留了一條“后路”,以保證若之前所有的SubShader都無法在當(dāng)前的顯卡上運(yùn)行,則運(yùn)行FallBack所指定的Shader[10]。

1.3 Unity Shader的形式

(1)表面著色器。

表面著色器(surface Shader)是Unity創(chuàng)造的一種著色器代碼類型。它在本質(zhì)上就是對(duì)頂點(diǎn)/片元著色器的封裝,省去了一些重復(fù)代碼編寫的工作量。也就是Unity在提供一個(gè)表面著色器之后,在背后仍然將它變?yōu)轫旤c(diǎn)片元著色器。但是相比于頂點(diǎn)/片元著色器,表面著色器更加簡潔,效率更高[11]。

(2)頂點(diǎn)/片元著色器。

相比于表面著色器,頂點(diǎn)/片元著色器(vertex/fragment Shader)更加復(fù)雜,但同時(shí)靈活性更高??梢愿鶕?jù)自己當(dāng)前的不同需求,編寫控制頂點(diǎn)著色器和片元著色器的代碼,對(duì)GPU渲染流水線中的可編程部分直接進(jìn)行靈活的控制。

(3)固定函數(shù)著色器。

上述的兩種Shader都使用了可編程管線,而對(duì)于一些比較老舊的,不支持可編程管線著色器的設(shè)備,則需要使用固定函數(shù)著色器(fixed function Shader)來完成渲染[12],這些著色器往往只能完成一些比較簡單的效果,目前很少使用。

1.4 Unity Shader的使用方法

首先根據(jù)需求,選擇一種Unity Shader形式,編寫Shader著色程序。然后在工程中新建材質(zhì)球,將上述寫好的著色器程序賦給材質(zhì)球,并給材質(zhì)球設(shè)置貼圖,作為著色器程序的輸入,最后將材質(zhì)球附在物體模型上,就得到了目標(biāo)效果[13]。

2 石油流動(dòng)效果的實(shí)現(xiàn)

針對(duì)石油的泄漏現(xiàn)象,為模擬出石油流動(dòng)時(shí)石油的主體部分,在3dsMax中制作出一個(gè)邊緣光滑,形狀不規(guī)則的物體,作為模擬石油流動(dòng)的主體模型。石油主體模型在3dsMax中的截圖如圖1所示。

圖1 模型截圖

2.1 基于紋理切換的石油流動(dòng)效果設(shè)計(jì)與實(shí)現(xiàn)

該方法實(shí)現(xiàn)石油流動(dòng)效果采用的是表面著色器(surface Shader),規(guī)定了兩個(gè)偏移速度x,y,速度乘以隨時(shí)間變化的時(shí)間變量得到偏移量。對(duì)圖片進(jìn)行偏移計(jì)算之后的點(diǎn)進(jìn)行采樣,獲得偏移點(diǎn)的顏色值作為返回值輸出,以達(dá)到石油流動(dòng)的效果。流程圖如圖2所示。

圖2 紋理切換流程

在Properties塊中,需要聲明貼圖與貼圖的x,y軸偏移速度。輸入的主紋理貼圖的格式是2D,而偏移速度為范圍在(0,100)之間的數(shù)值。

_WaterTex("水的紋理圖:",2D)="white" {}

_XSpeed("X軸方向的紋理滾動(dòng)速度",:

Range(-10,10))=1

_YSpeed("Y軸方向的紋理滾動(dòng)速度",:

Range(-10,10))=1

Properties塊結(jié)束后,需要在SubShader塊(渲染方案)中,嵌套CG代碼塊。首先,通過結(jié)構(gòu)體Input,將模型頂點(diǎn)的uv值作為surf函數(shù)的輸入。在表面函數(shù)surf中,對(duì)貼圖進(jìn)行計(jì)算。通過內(nèi)置的時(shí)間變量_Time乘以x軸,y軸方向的偏移速度,得到偏移量,通過x軸偏移量與y軸偏移量的組合,得到偏移量scrolledUV,并與頂點(diǎn)的uv值相加得到偏移量,通過tex2D函數(shù),對(duì)貼圖在偏移處進(jìn)行采樣,得到偏移處的顏色值。由于偏移量隨時(shí)間改變而改變,因此,采樣得出的顏色值也會(huì)隨時(shí)間改變,這樣就類似于貼圖在進(jìn)行運(yùn)動(dòng),以實(shí)現(xiàn)流動(dòng)的效果。

fixed xValue=_XSpeed*_Time;

fixed yValue=_YSpeed*_Time;

UV+=fixed2(xValue,yValue);

half4 c=tex2D(_WaterTex,UV);

o.Albedo=c.rgb;

2.2 基于紋理切換的石油流動(dòng)效果展示

圖3為使用紋理切換方法在RenderDoc中截取的八幀圖像。

圖3 RenderDoc中的截圖(1)

使用上述方法模擬在場景中發(fā)生漏油的效果如圖4所示。

圖4 紋理切換方法模擬效果圖

2.3 基于噪聲的石油流動(dòng)效果的設(shè)計(jì)與實(shí)現(xiàn)

使用上述方法能夠有效模擬出石油流動(dòng)的效果,但是無法模擬出石油在光照下的反射與折射效果。因此,引入噪聲圖片,對(duì)噪聲進(jìn)行采樣得到的隨機(jī)值,來實(shí)現(xiàn)貼圖的動(dòng)態(tài)扭曲效果,以實(shí)現(xiàn)貼圖的反射折射效

果,提高模擬的真實(shí)感。

在圖形學(xué)中使用噪聲是為了把一些隨機(jī)變量引入到程序中,如火焰、地形、云朵的模擬等等都要使用隨機(jī)變量。在圖形學(xué)中稱這種噪聲為“白噪聲”(功率譜密度在整個(gè)頻域內(nèi)均勻分布的噪聲)[14]。噪聲的基礎(chǔ)來自于隨機(jī)數(shù),若屏幕上的每個(gè)像素點(diǎn)給一個(gè)0~1之間的隨機(jī)數(shù)來表示像素點(diǎn)的亮度[15],就能得到白噪聲紋理。因此可以通過對(duì)白噪聲圖片進(jìn)行采樣以得到隨機(jī)數(shù),完成對(duì)于石油反射折射效果的模擬。

該方法采用的是頂點(diǎn)/片元著色器。在該模擬中,對(duì)噪聲圖進(jìn)行采樣,其中對(duì)采樣點(diǎn)設(shè)置時(shí)間變量,隨著時(shí)間不斷發(fā)生偏移,它提供的R值就會(huì)不停的變化,將R值再與頂點(diǎn)數(shù)據(jù)相加作為采樣點(diǎn),對(duì)主貼圖進(jìn)行采樣,將得到的顏色作為輸出,那么圖片就會(huì)出現(xiàn)動(dòng)態(tài)的扭曲效果,就實(shí)現(xiàn)了想要的石油流動(dòng)效果。

流程圖如圖5所示。

圖5 噪聲模擬流程

在Pass通道嵌套的CG代碼段中,首先對(duì)頂點(diǎn)著色器進(jìn)行控制,在頂點(diǎn)階段主要完成兩個(gè)工作,包括把頂點(diǎn)坐標(biāo)從模型空間轉(zhuǎn)換到裁剪空間,再使用紋理的屬性(_MainTex_ST.xy,_MainTex_ST.zw)對(duì)頂點(diǎn)坐標(biāo)進(jìn)行計(jì)算,得到該階段計(jì)算之后的紋理坐標(biāo)。主要計(jì)算過程如下:

v2f vert(appdata v)

{ o.vertex=UnityObjectToClipPos(v.vertex);

o.uv=TRANSFORM_TEX(v.uv,_MainTex);

}

在片元著色器中,實(shí)現(xiàn)的是噪聲模擬方法的主體。首先設(shè)置時(shí)間變量乘以速度,得到偏移量,偏移量與頂點(diǎn)數(shù)據(jù)相加作為采樣點(diǎn),對(duì)噪聲圖片進(jìn)行采樣,得到rgb值,此時(shí),將R值提出,作為隨機(jī)數(shù),再與頂點(diǎn)數(shù)據(jù)相加,作為采樣點(diǎn)對(duì)主貼圖進(jìn)行采樣,得到對(duì)應(yīng)點(diǎn)的rgb值,作為返回值返回。圖片就會(huì)出現(xiàn)動(dòng)態(tài)的扭曲效果,就實(shí)現(xiàn)了想要的石油流動(dòng)效果。

fixed4 frag(v2f i):SV_Target{

fixed4 noise_col=tex2D(_NoiseTex,i.uv + fixed2(_Time.y*_XSpeed, 0));

fixed uOffset=noise_col.r;

fixed vOffset=noise_col.r;

fixed4 col=tex2D(_MainTex, i.uv+ _Intensity*fixed2(uOffset, vOffset));

UNITY_APPLY_FOG(i.fogCoord, col);}

2.4 基于噪聲的石油流動(dòng)效果展示

圖6為使用上述方法模擬時(shí)在RenderDoc中截取的八幀圖像。

圖6 RenderDoc中的截圖(2)

使用上述方法模擬在場景中發(fā)生漏油的效果如圖7所示。

圖7 噪聲方法模擬效果圖

3 結(jié)束語

利用Unity Shader技術(shù),模擬出石油的流動(dòng)效果。首先對(duì)著色器進(jìn)行簡單介紹,然后針對(duì)Unity Shader,探討ShaderLab的結(jié)構(gòu)及其分類。通過ShaderLab的兩種形式—表面著色器和頂點(diǎn)/片元著色器,完成兩種石油流動(dòng)效果的模擬。一種使用紋理切換方式,引入時(shí)間變量對(duì)貼圖進(jìn)行采樣,實(shí)現(xiàn)貼圖運(yùn)動(dòng)效果;另一種對(duì)噪聲進(jìn)行采樣,得到隨機(jī)數(shù),通過該隨機(jī)值與頂點(diǎn)進(jìn)行組合進(jìn)行采樣,貼圖就會(huì)出現(xiàn)動(dòng)態(tài)的扭曲效果,完成對(duì)石油流動(dòng)效果的模擬。

猜你喜歡
模擬出偏移量紋理
基于BP網(wǎng)絡(luò)的中速走絲切割加工參數(shù)優(yōu)選研究
春 夜
肺紋理增多是病嗎?
童夢
基于AutoLISP的有軌起重機(jī)非圓軌道動(dòng)態(tài)仿真
卷煙硬度與卷接、包裝工序相關(guān)性分析
TEXTURE ON TEXTURE質(zhì)地上的紋理
以南北地震帶為例研究面向地震應(yīng)急的宏觀震中與微觀震中偏移模型
放射夕陽之光
消除凹凸紋理有妙招!