簡介:
在實時渲染(Real-Time rendering)中,陰影映射(Shadow mapping)過程是限制渲染速度的一個非常重要的環(huán)節(jié),因為在每一幀渲染之前,我們還需要對整個場景進行一次深度緩沖(depth buffer)的渲染(shadow pass),用來檢測物體是否在陰影中。
本工具的作用是,針對該過程,對場景中的物體進行離線(off-line)的預處理,將那些在渲染中投射的陰影沒有意義的物體標記出來,這樣,在渲染過程中,就可以通過讀取標記,在shadow
pass過程中忽略這些物體,進而對渲染過程進行加速。
原理:
之前提到有些物體在陰影映射中,它所投射的陰影是“無意義”的,這種“無意義”主要分以下兩種情況:
- 該物體完全被其他物體所遮擋:
在這種情況下,根據(jù)shadow mapping的原理,任何處于該物體陰影之下的物體同時也會完全處于其他物體的陰影之下,因此在shadow pass這種物體可以完全忽略。 - 該物體所投射的陰影中并不存在其他物體:
在這種情況下,在渲染中,并不會有任何物體的顏色計算需要該物體所投射的陰影,因此該陰影也是沒有意義的。(這種情況最多發(fā)生在地形(Terrain)上)
使用說明:
環(huán)境設置:
本工具使用Visual Studio 2012編譯,所需要的庫文件以及頭文件均在工具根目錄的include文件夾以及l(fā)ib文件夾中,同時所需要的.dll文件均在工具根目錄的debug文件夾中。-
配置文檔:
程序的可配置文檔是在根目錄下的GlobalSetting.xml,用戶可以通過修改配置文檔來配置工具的輸入與參數(shù),其中可修改的輸入與參數(shù)如下:- 場景管理系統(tǒng)總目錄(Resource_Path):即所使用的場景管理系統(tǒng)BWResource的總目錄,全部chunks,models等信息所保存的目錄。
- 區(qū)塊資源目錄(Universe_Path):即區(qū)塊(chunks)等信息所在目錄。
- 窗口以及高度映射圖的大小(Window_HMap_size):即窗口以及高度圖的長和寬。
- 鄰近區(qū)塊數(shù)量(Num_Chunks):在檢測某一區(qū)塊中的物體時,需要將周圍的區(qū)塊全部考慮在內(nèi),因為當前區(qū)塊的物體可能會遮擋或被周圍的區(qū)塊的物體所遮擋。在這里可以設置需要考慮在內(nèi)以當前區(qū)塊為中心的鄰近區(qū)塊的行列數(shù)(left, right, top, bottom)。
- 光源集合(Light_Set):因為光源可能存在多個或是一天的光源的位置及角度也會變化,因此本工具支持多光源輸入,工具會逐一對不同光源進行檢測,并將不同光源的結(jié)果寫入.chunks文件的shadow字段中。
- 光源(Light):對于多光源輸入,直接可以通過在配置文檔中按照下述樣例格式添加<Light></Light>即可。光源的可配置的屬性如下:
a. 位置(Position)
b. 方向(Direction):通過設置光源的水平夾角(horizontal angle)與垂直夾角(vertical angle)。(關(guān)于方向的設置可參考下圖)
c. 投影類型(ProjectionType):目前只支持Directional光(如有需求,很容易修改)
d. 投影矩陣的參數(shù)(Projection_Parameters): 寬度(Width),高度(Height),近剪裁平面距離(Near),遠剪裁平面距離(Far)。 - 蒙版偏差(Stencil_Bias):該屬性決定了在蒙版寫入時,需要剪裁掉地形高度以上多少偏差的物體。(為了避免地形高度信息保存在的texture精度不足的誤差)
- 渲染延遲(Render_Delay):該屬性可以設置檢測不同chunk或者不同光源下的渲染的間隔時間,因為在檢測結(jié)束后會渲染出結(jié)果在窗口中,因此可以通過設置較大的間隔時間來觀察檢測結(jié)果(檢測結(jié)果會用顏色標記),或是設置為0達到最快的檢測速度。(單位為毫秒ms)
配置文檔的基本格式如下:
<?xml version="1.0" encoding="gb2312"?>
<Node>
<Header>
<EngName>Global Parameters Setting</EngName>
</Header>
<Parameters>
<Resource_Path type="string" describe="BWResource Manager source path">
res
</Resource_Path>
<Universe_Path type="string" describe="Universe(chunks) source path">
universes/eg/jd_shuijing
</Universe_Path>
<Window_HMap_size describe="Window and Height Map size">
<Width type="int">1280</Width>
<Height type="int">800</Height>
</Window_HMap_size>
<Num_Chunks describe="Num of the nearby chunks to consider">
<Left type = "int">1</Left>
<Right type = "int">1</Right>
<Top type = "int">1</Top>
<Bottom type = "int">1</Bottom>
</Num_Chunks>
<Light_Set describe="Light Settings">
<Light> <!--- 光源1 -->
<Pos describe="Light Pos">
<World_X type = "double">100.0</World_X>
<World_Y type = "double">100.0</World_Y>
<World_Z type = "double">100.0</World_Z>
</Pos>
<Direction describe = "Light Direction">
<Horizontal type = "double">3.92699081699</Horizontal>
<Vertical type = "double">-0.78539816339</Vertical>
</Direction>
<ProjectionType type = "string" describe = "Directional/Point">
Directional
</ProjectionType>
<Projection_Parameters>
<Width type = "double">300.0</Width>
<Height type = "double">300.0</Height>
<Near type = "double">-500.0</Near>
<Far type = "double">1500.0</Far>
</Projection_Parameters>
</Light>
<Light> <!--- 光源2 -->
<Pos describe="Light Pos">
<World_X type = "double">0.0</World_X>
<World_Y type = "double">100.0</World_Y>
<World_Z type = "double">0.0</World_Z>
</Pos>
<Direction describe = "Light Direction">
<Horizontal type = "double">0.78539816339</Horizontal>
<Vertical type = "double">-0.78539816339</Vertical>
</Direction>
<ProjectionType type = "string" describe = "Directional/Point">
Directional
</ProjectionType>
<Projection_Parameters>
<Width type = "double">300.0</Width>
<Height type = "double">300.0</Height>
<Near type = "double">-500.0</Near>
<Far type = "double">1500.0</Far>
</Projection_Parameters>
</Light>
</Light_Set>
<Stencil_Bias type = "double">
0.0005
</Stencil_Bias>
<Render_Delay type = "int">
0
</Render_Delay>
</Parameters>
</Node>
工具運行:
設置好配置文檔之后,直接運行工具即可自動處理。在工具運行中,將會出現(xiàn)兩個窗口,一個窗口為渲染窗口,在該窗口可以看到從光源角度出發(fā),進行渲染的圖像,其中灰色用來標記周圍鄰近的chunks,紅色標記陰影無意義的物體,綠色標記陰影有意義物體??梢酝ㄟ^增大Render_Delay來更長時間的觀察結(jié)果。另一個窗口為控制臺窗口,這里可以看到chunk處理的結(jié)果,以及從配置文件中讀取成功的參數(shù)信息。-
運行結(jié)果:
如上述所示,運行結(jié)果會實時顯示在渲染窗口中。與此同時,檢測結(jié)果還會寫入到場景文件中的.chunk文件的<shadow>字段中<terrain> <resource> ffffffffo.cdata/terrain </resource> <shadow> 2 </shadow> </terrain>
,同時對于model,還會將結(jié)果寫入model下的<PrimitiveGroup>中
<model>
<resource> objects/area/st/model/rock.model </resource>
<dye>
<name> com_tex_shiq01 </name>
<tint> huang </tint>
</dye>
<uuid> 6055E290-4CC63BB3-1E14A3AE-0DFBE9A0 </uuid>
<transform>
<row0> -0.991167 0.118751 0.820961 </row0>
<row1> -0.662710 0.655975 -0.894993 </row1>
<row2> -0.498893 -1.107288 -0.442164 </row2>
<row3> 46.615074 -96.943344 12.009224 </row3>
</transform>
<affectByBlend> true </affectByBlend>
<specPixelPerMeter> 20.000000 </specPixelPerMeter>
<shadow> 2
<RenderSet>
<Geometry>
<PrimitiveGroup> 2 </PrimitiveGroup>
</Geometry>
</RenderSet>
</shadow>
</model>
寫入格式為32位的int格式,其中每一位代表從一個光源(Light)出發(fā)的檢測結(jié)果,同時model下<shadow>字段。在讀取檢測信息的時候,需要按位讀取,其中從右數(shù)第一位開始代表光源1到光源N,例如:僅光源01與光源02,若檢測結(jié)果為光源02為有意義,01無意義,則寫入<PrimitiveGroup>的結(jié)果為2,即*****0010(前面位數(shù)省略)。
而對于寫入<shadow>的結(jié)果,如果同一個model存在多個RenderSet或PrimitiveGroup,則結(jié)果為其model下所有PrimitiveGroup結(jié)果的位或。
<model>
<resource> objects/area/zw/model/zw_mlqm01_6381.model </resource>
<uuid> BCF2EFBF-46D323BC-204E259B-CB3D47BA </uuid>
<transform>
<row0> -0.327740 -0.027205 0.326609 </row0>
<row1> 0.000000 0.461894 0.038475 </row1>
<row2> -0.327741 0.027205 -0.326609 </row2>
<row3> 10.023972 -88.602753 57.472660 </row3>
</transform>
<affectByBlend> true </affectByBlend>
<dye>
<name> Material #35 </name>
<tint> bai </tint>
</dye>
<shadow> 3
<RenderSet>
<Geometry>
<PrimitiveGroup> 2 </PrimitiveGroup>
<PrimitiveGroup> 3 </PrimitiveGroup>
</Geometry>
</RenderSet>
</shadow>
</model>