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

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

Unity3D: 使用深度檢測的方法進行描邊

2022-03-10 10:12 作者:krosshj  | 我要投稿

1 通過深度信息做邊緣檢測

另一種描邊的思路是在圖像處理層面做邊緣檢測。下圖是對顏色信息進行邊緣檢測的效果。

可以看到,檢測出來的邊緣是非?!半s亂”的,它將圖像所有顏色不一致或者說變化較大的地方都標記出來了,這樣對于表面顏色本身很復(fù)雜的物體(圖形)也會檢測出很多細小的邊緣,而這些并不能算得上是邊緣,更精確的說應(yīng)該是顏色差異的位置。

在實時渲染中,我們看到的圖像本身就是我們渲染出來的,我們是具備整個世界的所有構(gòu)成要素,我們自然就具備當前畫面的深度信息。

想一想,如果兩個物體它們相對于鏡頭的深度位置不一樣,那么邊緣處的深度信息應(yīng)該會有斷層,那么邊緣檢測算法正好可以找到這些斷層所在。


1.1 通過 PostProcessingStack 處理深度信息


1.1.1 安裝與準備

我們需要能夠進行后處理的地方,所以在Unity中,可以使用 Post Processing Stack 來處理。這是一個Package,可以直接在 Package Manager 中搜索并安裝。

這里是它的官方文檔【https://docs.unity3d.com/Packages/com.unity.postprocessing@3.1/manual/index.html】,講解了如何使用等信息。

安裝好了之后,我們需要在場景上設(shè)置好后處理的功能。

首先需要在相機對象上添加 post-process layer 和 post-process volume 兩個組件。

給相機指定一個 layer,名字隨便,這里使用?post-processed。并且在 post-process layer 中的 layer 屬性也指定為一樣的 layer。

在 post-process volume 中勾選?is Global,并 new 一個新的 profile 出來。

這個 profile 對象就可以在上面添加各種后處理的效果了。

比如我現(xiàn)在的場景是這樣的:

加一個系統(tǒng)自帶的暗角(Vignette)的效果。

暗角效果演示

接下來,我們要自己定義一個后處理效果的實現(xiàn)。

根據(jù)官方指南【https://docs.unity3d.com/Packages/com.unity.postprocessing@3.1/manual/Writing-Custom-Effects.html】所提到的方法,先創(chuàng)建一個 C# 腳本,并把下面這些代碼 copy 進去。

上面這一段只是示例代碼,有一些地方需要說明一下。

"Custom/Grayscale" 代碼中的這個部分,是定義了這個后處理效果的路徑,后面可以在 profile 對象的 Add effect... 中找到,如下圖所示:

"Hidden/Custom/Grayscale" 代碼中的這個部分,是 Shader 的路徑。

上面這個 C# 文件,只是負責和 Profile 對象建立聯(lián)系,定義好一些可以后面調(diào)節(jié)的參數(shù),并傳給shader,具體的工作還要在 shader 中做。

首先將代碼改寫一下,變成我們需要的實現(xiàn)。

然后就可以添加上這個效果。

接下來定義一個 shader ,這個shader 的代碼也比較特殊,我們直接從官方指南上copy一份,再做改動。

這個shader執(zhí)行的結(jié)果就是將圖像變成灰度圖。

OK,后處理的框架已經(jīng)搭好了,接下來我們要獲取深度信息,并做相應(yīng)的處理。


1.1.2 使用深度信息做邊緣檢測


1.1.2.1 深度buffer 叫什么名字?

根據(jù) Unity 的這一篇文檔《CameraDepthTexture》【https://docs.unity3d.com/Manual/SL-CameraDepthTexture.html】可以得知,深度buffer的名字是?_CameraDepthTexture

所以我們在 shader 中申明它,并讀取出來看看。

然后一運行你會發(fā)現(xiàn)什么都沒有,一片漆黑。我們還漏了兩個步驟沒有做。

1.給相機添加一個 depthTextureMode,讓它輸出深度buffer

2.根據(jù)?Unity 文檔中這一段的描述,如果shader沒有 shadow casting,就不會顯示在 camera depth buffer 上。

Depth texture is rendered using the same shader
passes as used for shadow caster rendering
(ShadowCaster pass type). So by extension, if a shader does not support shadow casting (i.e. there’s no shadow caster pass in the shader or any of the fallbacks), then objects using that shader will not show up in the depth texture.

因此,我們在物體的shader上最后加一個這個:

OK,接下來我們就可以看到深度圖了。

如果看到的深度圖不清楚,可以調(diào)節(jié) Camera 的遠近平面屬性來控制。


1.1.2.2 做邊緣檢測

我們定義一個 _Scale?表示要取鄰近多遠的像素。

在 shader 中取四個鄰近的像素點,并進行邊緣檢測的計算,最后輸出這個顏色。

最終的效果如下所示:

再添加一個閾值參數(shù),對其進行二值化。

1.1.3 深度信息邊緣檢測的局限性

當相機和實際觀察的物體相對較遠時,被觀察的物體之間的深度差別就會相對較小,用這個方法進行邊緣檢測,這些物體的邊緣就會連在一起,即當相機在較遠的地方觀察時,被觀察的對象之間的深度信息差異過小,無法檢測出良好的邊緣信息。


2 通過法線信息做邊緣檢測

另一種方法是通過得到屏幕空間的法線信息做邊緣檢測。


2.1 如何獲得法線信息(兩種方法)


2.1.1 通過相機設(shè)置獲取法線信息

可以通過設(shè)置 Camera 的 DepthTextureMode 來獲取屏幕空間的法線信息。

這樣設(shè)置之后,我們就有一個全局的深度法線紋理,名字是:_CameraDepthNormalsTexture,我們可以通過?DecodeDepthNormal?這個方法將深度和法線信息從里面解析出來。

從哪里知道名字是_CameraDepthNormalsTexture?
這篇文章里面提到的: https://www.ronja-tutorials.com/post/018-postprocessing-normal/


2.1.2 通過ReplacementShader獲取法線信息


2.2 通過法線信息做邊緣檢測計算

最終我們使用下面這段代碼來做邊緣檢測


3.2.2 如何得到法線信息(方法二)

使用 ReplacementShader

請參考這里:https://docs.unity3d.com/Manual/SL-ShaderReplacement.html


參考資料

* 【CameraDepthTexture: 相機如何設(shè)置可以得到深度和法線紋理】https://docs.unity3d.com/Manual/SL-CameraDepthTexture.html

* 【Difference between tex2D and SAMPLE_TEXTURE2D (Post Processing effect): SAMPLE_TEXTURE2D的源碼是什么】https://forum.unity.com/threads/difference-between-tex2d-and-sample_texture2d-post-processing-effect.651580/

*【Postprocessing with Normal Texture: 深度和法線的信息會存在哪里】https://www.ronja-tutorials.com/post/018-postprocessing-normal/

*【UnityCG源碼: DecodeDepthNormal是怎么實現(xiàn)的】https://gist.github.com/hecomi/9580605


全文完


Unity3D: 使用深度檢測的方法進行描邊的評論 (共 條)

分享到微博請遵守國家法律
安阳市| 任丘市| 沭阳县| 韶关市| 仁寿县| 谢通门县| 江油市| 江津市| 郧西县| 雷州市| 沅陵县| 佛山市| 武邑县| 萍乡市| 凤冈县| 文化| 贵溪市| 白沙| 北辰区| 宁都县| 开远市| 荔波县| 荣成市| 阳江市| 永安市| 麟游县| 淄博市| 丹巴县| 加查县| 高要市| 定西市| 青冈县| 大丰市| 门源| 永和县| 高阳县| 秦安县| 托里县| 盐池县| 库尔勒市| 沙河市|