最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

matcap原理

2022-09-08 11:00 作者:Lucas_dudu  | 我要投稿

材質(zhì)捕捉(material capture)簡(jiǎn)稱 MatCap ,材質(zhì)通過(guò)渲染一個(gè)球到紋理而被捕捉。同類的詞有動(dòng)態(tài)捕捉(motion capture,簡(jiǎn)稱 mocap)。matcap 流行于 2007年時(shí)的三維雕刻軟件 ZBrush ,在雕刻構(gòu)建物體模型時(shí),沒(méi)有網(wǎng)格、材質(zhì)信息,通過(guò) matcap ,藝術(shù)家們可以快速有效地得到反饋,直觀地查看模型形狀起伏的變化。

雕刻(sculpting)


渲染需要幾何體、光源、材質(zhì)、shader 的共同參與。matcap 將光源、材質(zhì)信息直接烘焙到一張紋理上,渲染時(shí)直接拿來(lái)用。在不同的 matcap 紋理之間切換,它能很真實(shí)地表現(xiàn)出各類材質(zhì)信息。它不考慮光源信息,也就沒(méi)有實(shí)際的光照計(jì)算。增加一盞燈或都去掉,照還是不照,效果就在那里,不增不減。你可以把材質(zhì)的各種屬性(粗糙度、各向異性),以及各種效果(硬陰影、反射、Fresnel)信息預(yù)先寫(xiě)入紋理,渲染時(shí)不會(huì)增加開(kāi)銷。甚至可以在 matcap 上作文章,在兩個(gè) matcap 紋理之間混合(alpha blending)。

其原理也好理解,圓內(nèi)任意一點(diǎn)可以映射成半球面上的單位法向量,然后每個(gè)像素有一個(gè)顏色,所以可以建立從法向量到顏色的映射。圓內(nèi)存儲(chǔ)了半球面上所有朝向的顏色,通過(guò)查表向量來(lái)給物體表面上色。注意是正交投影,不是透視投影,透視做不到看到半球的邊緣。紋理坐標(biāo) texcoord = vec2(u, v) 在[0, 1]x[0, 1]范圍,法向量 normal = vec3 (x, y, z) 的 Z 軸分量 z ≥ 0。中央的紋理坐標(biāo)為 (0.5, 0.5),法向量為 (0, 0, 1)。texcoord 和 normal 是一一對(duì)應(yīng)關(guān)系,可以在烘焙時(shí)從 normal 推導(dǎo)出 texcoord,可以在渲染時(shí)從 texcoord 推導(dǎo)出 normal。

渲染時(shí)的 GLSL shader 代碼如下:

? ? 在圖形學(xué)里會(huì)遇到多種坐標(biāo)系,涉及到物體空間(object space)、世界空間(world space)、視圖空間(view space)、切向空間(tangent space)的轉(zhuǎn)換。轉(zhuǎn)換可視作乘以一個(gè)矩陣,反向變換則視作乘以其逆矩陣。在軟件中雕刻物體,我們希望這個(gè) normal 是視圖空間的,即光源相對(duì)相機(jī)固定,如同入礦井作業(yè)工人佩戴在頭上的照明燈一樣,很方便查看正對(duì)位置的幾何形狀。在游戲中,normal 一般是世界空間的,光源相對(duì)世界固定。

  從物體空間到世界空間,normal 的變換與 position 的變換有所不同。position 乘以model 矩陣變換到世界空間。normal 則要乘以model 矩陣轉(zhuǎn)置的逆(或逆的轉(zhuǎn)置,效果一樣)變換到世界空間。我在這里解答過(guò)。

  大多時(shí)候你發(fā)現(xiàn),normal 按 position 的做法來(lái),好像效果也沒(méi)錯(cuò)。的確,如果變換的物體是剛體(rigid body),或者矩陣的縮放系數(shù)是 vec3(1, 1, 1),仍然正確。此時(shí)矩陣是單位正交矩陣,存在性質(zhì)矩陣的逆等于矩陣的轉(zhuǎn)置?M?1=MT。于是,逆的轉(zhuǎn)置等于兩次轉(zhuǎn)置,回到自身M。當(dāng)然,如果有先驗(yàn)條件(precondition)——變換是統(tǒng)一的縮放(uniform scaling),對(duì)乘后得到的向量Mv再 normalize() 一下,也能保證正確。

  view 矩陣通過(guò) right/forward/up 三個(gè)標(biāo)準(zhǔn)正交基(orthonormal basis)構(gòu)成,是正交矩陣(orthogonal matrix)無(wú)疑。提醒一下括號(hào)里的單詞,orthogonal 是正交的,orthonormal 比 orthogonal 多出了歸一化,是單位正交的。model 矩陣卻沒(méi)有保證,可能混合著縮放系數(shù),甚至非均勻縮放,即各個(gè)軸上的縮放系數(shù)不一致。如果不確定物體的變換是否滿足上面提到的性質(zhì),就老老實(shí)實(shí)來(lái)。

 

 matcap 渲染出的效果竟這么好使,那么,哪里可以獲取呢?根據(jù)難易程度,獲取 matcap 有以下幾種途徑:

  1. 網(wǎng)上搜索關(guān)鍵詞,下載圖片使用。軟件社區(qū)送溫暖,如ZBrush 分享了一些 MatCap 庫(kù)。

  2. 自行打光,安置環(huán)境,對(duì)材質(zhì)球取景拍攝。

  3. 用 Blender、Modo、ZBrush 這樣的3D建模軟件渲染。

  4. 在游戲引擎中烘焙渲染,寫(xiě)程序生成。

  5. 手工繪制紋理,后期可借助 Photoshop 調(diào)色。

  如果無(wú)法從3D建模軟件安裝包里直接獲取 matcap 圖片資源,可以在工程中生成。打開(kāi)建模軟件,新建一個(gè)球,細(xì)分(subdivide)多次到表面足夠光滑,應(yīng)用上軟件里內(nèi)置的 matcap 效果,調(diào)整好相機(jī)位置,烘焙時(shí)用正交投影,導(dǎo)出這張預(yù)覽圖片,尺寸以 512x512、1024x1024 為宜,太小則邊緣存在瑕疵。

  制作圖片是有一定要求的,要求圖片是正方形,并保證圖片中的圓跟圖像邊緣相切,不能多也不能少!因?yàn)閳A中的任意一點(diǎn),跟球面的法向量對(duì)應(yīng),渲染計(jì)算涉及到半球面上的各個(gè)朝向,所以要鋪滿。然后制作matcap的時(shí)候,盡量不要參雜過(guò)多的高頻細(xì)節(jié)。

上面是3D渲染方案,你也可以嘗試布置一兩盞燈,用 Phong 光照明方程?I=Ia+Id+Is=kaIa+kdId(l→?n→)+ksIs(v→?r→)shineness?生成 matcap 圖片。觀察方向是正上方,平行投影取?v→?= (0, 0, 1),?n→?在半球面上變化著,反射方向?r→?用 shader 里的內(nèi)置函數(shù) reflect 計(jì)算,式子為 I - 2 * dot(I, N) * N,這里有其推導(dǎo)。因?yàn)椴簧婕绊旤c(diǎn)的坐標(biāo)變換,只有向量,不用走圖形學(xué)的可編程的功能管線(programmable function pipeline),遍歷圖片上圓內(nèi)每個(gè)像素計(jì)算,每個(gè)像素對(duì)應(yīng)一個(gè)法向量?n→?,思路清晰,這里不多講。

  下面給出我用代碼生成的打側(cè)光的圖片。徑向?qū)ΨQ。中心最黑,越靠近邊緣越亮。

halo

不計(jì)算光照,直接將法向量編碼成顏色的效果如下。對(duì)應(yīng)blender里面的check_normal+y.exr。需要留意 X、Y 分量的取值范圍[-1, +1]到[0, 1]的轉(zhuǎn)換。

map normal vector to RGB color

附上代碼。因?yàn)閳D片的Y軸朝下,紋理的V軸朝上,計(jì)算需要上下翻轉(zhuǎn)一下

講解到這,就可以結(jié)束了。饒有興趣的,可繼續(xù)觀摩一下 3D 建模軟件 Blender 里 matcap 的實(shí)現(xiàn),學(xué)一學(xué)別人的代碼和思路。

  圖中的 matcap 資源在 <DIR>/datafiles/studiolights/matcap/ 目錄下。通過(guò)命令行 sudo apt-get install blender 安裝的,對(duì)應(yīng)的 DIR 為 /usr/share/blender/,如果自己從官方下載解壓的包, DIR 則為解壓里的版本號(hào)目錄,如2.91。目錄下都是 .exr 格式的圖片。比起現(xiàn)有的8位和16位的圖像文件格式,OpenEXR 文件有更高的動(dòng)態(tài)范圍(HDR)和色彩精確度。圖片是 half 浮點(diǎn)精度,可以用 GIMP 軟件打開(kāi)查看或修改。上面我們用代碼生成的 normal 圖,對(duì)應(yīng)文件夾里的 check_normal+y.exr。

  Blender 是開(kāi)源軟件,源碼從 git://git.blender.org/blender?下載,GitHub 上也有官方鏡像[1]。matcap 資源在 release/datafiles/studiolights/matcap/,可以用 locate jade.exr 命令馬上定位到。Blender 自 2.8 版本開(kāi)始,要求硬件支持 OpenGL 3.3 以上版本。


  進(jìn)入到 workbench 里的 shaders 目錄(source/blender/draw/engines/workbench/shaders/),與 matcap 相關(guān)的兩個(gè) shader 程序?yàn)?workbench_composite_frag.glsl?和?workbench_matcap_lib.glsl。

  其中,宏 V3D_LIGHTING_STUDIO、V3D_LIGHTING_MATCAP、V3D_LIGHTING_FLAT 分別對(duì)應(yīng)上面 viewport shading 界面下的 studio | matcap | flat 三個(gè)選項(xiàng)。關(guān)鍵代碼 get_matcap_lighting() 函數(shù)來(lái)自 workbench_matcap_lib.glsl 文件。

  GLSL 代碼是基于字符串編譯的,而不是文件,所以看不到 #include 的語(yǔ)法。 OpenGL 的函數(shù)?glShaderSource?是支持 shader 字符串?dāng)?shù)組編譯的,少有人用。

  Blender、Unreal 引擎采用 #include 語(yǔ)法,靈活性更高,需要在編譯 shader 前預(yù)處理替換文本[2]。代碼中 BLENDER_REQUIRE 的預(yù)處理在?draw_manager_shader.c。

  materialBuffer 和 normalBuffer 是通過(guò) FBO 渲染出的兩張紋理。當(dāng)選擇用 matcap 時(shí),將片元的朝向信息 gl_FrontFacing 編碼到 materialBuffer 的 alpha 通道,見(jiàn)workbench_prepass_frag.glsl。在 viewport 成了2D 平面,需要4個(gè)頂點(diǎn)數(shù)據(jù)渲染一個(gè)平面,uvcoordsvar 在 vertex shader 階段是通過(guò) gl_VertexID 計(jì)算出的,沒(méi)有通過(guò) VBO 傳遞頂點(diǎn)屬性數(shù)據(jù)。

  get_view_vector_from_screen_uv 函數(shù)見(jiàn)名知意,代碼如下。ProjectionMatrix[3][3] == 0.0 用來(lái)檢測(cè)是透視投影,還是平行投影。透視投影的 M[3][3] 為0,平行投影的 M[3][3] 為1。vec4 ViewVecs[2];存儲(chǔ)了視錐體 NDC(-1.0, -1.0, -1.0) 和 NDC(1.0, 1.0, 1.0) 的坐標(biāo),以及near、far 深度信息。代碼可以看成 z = 1 平面上的uv坐標(biāo)投影到半球面上,得到觀看方向上的單位向量。平行投影則始終朝上 (0, 0, 1)。

  workbench_normal_decode 來(lái)自文件 workbench_common_lib.glsl,有 decode 就有 encode,功能是壓縮、解壓一個(gè)單位法向量。為什么要壓縮存儲(chǔ)法向量?因?yàn)樗薅烁↑c(diǎn)數(shù)的范圍在 [-1.0, +1.0] 區(qū)間;存在關(guān)系?x2+y2+z2=1;延遲渲染(deferred rendering)里的 G-Buffer 要存儲(chǔ)很多通道的數(shù)據(jù),帶寬尤其寶貴,騰出空間給其它通道用。對(duì)于壓縮出現(xiàn)過(guò)多方法[3],最常見(jiàn)的是存儲(chǔ)x、y,丟棄z,運(yùn)行時(shí)還原 z = sqrt(1 - x * x - y * y)。其他方法和效率對(duì)比分析,見(jiàn)提到的鏈接。代碼中的 workbench_float_pair_decode 則是另一個(gè)壓縮,將 roughness 和 metallic 合成一個(gè)浮點(diǎn)數(shù),再分解使用。

  以下為 workbench_matcap_lib.glsl 文件代碼。matcap_uv_compute 函數(shù)進(jìn)行了一些“騷”操作,讓人不明所以,即使注釋中說(shuō)明了構(gòu)建正交基。該段代碼來(lái)自?Frisvad?的文章《從3D單位向量構(gòu)建正交單位基,省去歸一化的方法》[4]。 從單位向量 I = (x, y, z) 找到兩個(gè)正交基為?b1→=(1?x21+z,?xy1+z,?x)?和?b2→=(?xy1+z,1?y21+z,?y)?。具體的數(shù)學(xué)推導(dǎo)和改進(jìn)方案,見(jiàn)我的這篇知乎文章。對(duì)于頻繁執(zhí)行的代碼片段,優(yōu)化一點(diǎn)點(diǎn)能得到大的提升。Hughes-M?ller 方法用了 normalize() 操作,F(xiàn)risvad 用一次除法換取移除 normalize() 操作。將向量 N 投影到?b1→,b2→?張成的平面上,得到該平面上的uv坐標(biāo)。

  代碼中的 flipped(或 matcap_orientation)對(duì)應(yīng)上面圖中齒輪下的雙向箭頭<-->,matcap 的效果可以左右鏡像,類似圖片的左右翻轉(zhuǎn),這個(gè)功能對(duì)雕刻還是有用的,方便對(duì)比查錯(cuò)。我們將漫反射和高光烘焙到一起了,而 Blender 將 diffuse 和 specular 分開(kāi)成兩張紋理,且用 use_specular 控制是否開(kāi)啟高光,use_specular 對(duì)應(yīng)界面最下方的 specular lighting 單選項(xiàng)。

  matcap 選項(xiàng)的左邊是 studio,studio light 里預(yù)置了幾個(gè)燈光布局。點(diǎn)擊旁邊的齒輪圖標(biāo),可以自定義場(chǎng)景中燈光的布局。參數(shù)有漫反射顏色、高光顏色、光滑度、方向,拖拽修改可以看到場(chǎng)景中實(shí)時(shí)的光照效果變化,默認(rèn)值初始化在文件?studiolight.c?的BKE_studiolight_default 函數(shù),然后 release/datafiles/studiolights/studio/ 目錄下也有幾個(gè)預(yù)制燈光。

  對(duì)于低模(low poly)的渲染,可以使用法線貼圖(normal mapping)技術(shù)。對(duì)于高細(xì)節(jié)的模型減面,生成低模,兩者建立映射關(guān)系后,烘焙出法線貼圖。使用 normal map 而不是頂點(diǎn)的 normal 屬性,可以展示模型的更多細(xì)節(jié)。

matcap原理的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
峡江县| 深水埗区| 苍梧县| 龙里县| 肥东县| 锦屏县| 偏关县| 临颍县| 定日县| 古交市| 巨野县| 玛纳斯县| 额尔古纳市| 静乐县| 边坝县| 搜索| 柳林县| 辽宁省| 泗阳县| 新郑市| 获嘉县| 新宁县| 永州市| 远安县| 宜阳县| 夏津县| 吉水县| 耒阳市| 偃师市| 岐山县| 布拖县| 清新县| 安乡县| 弋阳县| 梨树县| 高碑店市| 化德县| 观塘区| 江北区| 兴化市| 临江市|