UE4 角色预览与头像生成 CaptureSceneComponent2D 看这一篇就够了
游戲開發中的預覽
在游戲開發過程中,對角色的預覽,和某些情況下生成頭像是比較常見的需求。有些引擎,可以創建一個額外的場景和相機,然后將需要的內容放置到合適的位置,然后可以獲得想要的圖像。在UE4中不是這樣,沒法創建其他的場景,我們需要使用CaptureSceneComponent2D,字面意思看出來這是個場景捕獲的組件,它就是用來捕獲我們想要的場景內容到2D圖像上。
CaptureSceneComponent2D如何使用
這個組件的使用相當簡單,首先我們新建一個第三人稱的示例工程,使用以下基本步驟:
對,就是這么簡單,這個時候我們已經得到了一張捕獲的紋理。那么這個紋理如何使用呢?可以跟普通的貼圖一樣使用,不過稍微有一點點區別,這個稍后再說。
使用RenderTarget2D
為了使用剛剛捕獲的圖像,我們可以建立一個界面來展示它。
創建一個界面藍圖,并放上一個圖像控件,并設置圖像控件Brush中的圖片為之前的RT_Preview,然后在關卡藍圖里面,設置一個按鍵響應,把這個界面給展示出來。這里選擇F鍵。
運行游戲之后,按F鍵,發現界面上啥也沒有。原來RenderTarget紋理的透明度比較特別(具體是怎樣還沒有研究),我們回到場景,再次選中SceneCapture2D對象,在Details面板找到Catpture Source選項,然后選擇如下。再次運行我們就可以看到界面中的圖像。
只捕獲想要獲取的對象
從上面的截圖可以看出來,角色背后的藍天及場景中的其他內容都被捕獲了。在實際應用中,這些部分一般來說是不需要的。那么如何設置只捕獲特定內容呢?
依然是SceneCapture2D對象,它的屬性中有個參數叫Primitive Render Mode, 這個就是用來控制繪制內容模式的,它有個叫做Use ShowOnly List的模式,這個模式就可以指定一些對象,然后只捕獲這部分內容。
使用這個模式的一個小問題是,如果在編輯器中直接選擇這個選項,那么TextureTarget中的預覽將會消失。所以我們在編輯器中不修改它的模式,而在藍圖中動態設置。
結果如下:可以看到場景部分都消失了,不過還有藍的白的背景在。這部分內容應該是屬于透明內容。下一節我們再把它給去除掉。在這里我們使用了Show Only ActorComponents 即只捕獲特定的Actor對象,也可以使用Show Only Components節點來添加指定的組件,可以做到比Actor更細化的控制。后面還會講到。
去除不透明的背景,創建UI材質
- 把MaterialDomain設置為User Interface,因為這個才是是給UI用的
- 把BlendMode設置Translucent因為我們需要透明屬性
- 把之前建的RT_Preview拖入圖表中,按如圖連線
- 1-x節點叫 OneMinus
回到界面藍圖,之前圖片的Image選擇的是RT_Preview,是直接使用的紋理,現在改成MT_Preview,使用新建的材質。
再次運行游戲,按F鍵可以看到如下畫面,背景中的藍白色已經去除了。
到了這里,我們捕獲的內容基本上已經符合了預期:
- 只捕獲特定的角色
- 背景是透明的,便于在界面上顯示
然而,它還不能正直使用在游戲中,為什么?
改進
目前我們捕獲的對象是場景中的玩家對象,玩家對象會移動,一旦移動我們就捕獲不到了。這個問題有兩個解決方法,
- 第一個是可以把捕獲控件綁在玩家身上,跟著玩家一起動。這個方案也還有問題,那就是玩家會播很多動作,可能并不是你想要捕獲的,除了特殊使用目的,不建議使用。
- 創建一個專門的捕獲Actor,在其中放入特定的Mesh,然后捕獲組件只捕獲自己Actor中的指定Mesh或者特定Actor。此方案需要管理一個臨時Actor。
接下來就以第二個方案來簡述實際操作。
運行游戲,按F鍵,可以看到界面跟之前展示的一樣,不同的是:
-
玩家走動,不會影響界面
-
場景中多了一個模型,這是我們SpawnActor引入的一個模型
我們SpawnActor只是為了用于捕獲,不希望主攝像機可以看到,那么這里又有兩個方法:
- 把臨時Actor放遠一點(這個方案有些意外的效果,后面再說)
- 讓主攝像機看不到這個臨時Actor
我們先來說第二中方案,如何讓主攝像機屏蔽或者說過濾掉我們得臨時Actor。首先打開ACapturePreview藍圖,選中SkeletalMesh,然后在細節面板上找到Renderring選項卡,點擊下面的三角形展開高級選項,如下圖:
這里有兩個選項,Owner No See(擁有者不可見) Only Owner See(僅擁有者可見) ,利用Owner No See這個選項,再把臨時對象的Owner設置成主角Actor,那么主角就看不到這個臨時Actor了(對于網絡游戲,在客戶端創建的臨時Actor,其他人本來就看不見,所以也不用擔心。)
-
勾選Owner No See
-
在Spawn之后,將Owner設置成主角Character
再次運行游戲,按F之后,已經看不到臨時對象了,界面表現則是和之前一樣。
這里可能有人要問了,為什么不選擇OnlyOwnerSee,然后把Owner設置成自己呢?這里的問題是Owner不能設置成自己,如果要選擇OnlyOwnerSee,則必須將模型與SceneCaptureComponent拆成2個Actor來實現,這也是個方法,但是需要管理兩個臨時對象,具體的實現就大家自行實現吧。
為什么不把臨時Actor放遠一點來拍攝?
在一定程度上來說,沒啥問題,但是如果Actor離主相機太遠,引擎會對Actor進行優化,導致捕獲的效果非常糟糕,一方面是LOD的原因,一方面未啟用LOD的情況下,離的足夠用,也會強制優化。
不斷的將距離設置的更大之后,可以發現界面上的效果越來越差,直到不能接受。最后一項Actor離主角的距離是40000000。當然你可能不會設置那么遠,只要找一個合適的位置讓玩家當前看不到他就是可以接受的。如果你發現界面上的效果達不到預期的時候,就要考慮是否因為距離過大導致的。
另外,也是接下來要講的,使用正交投影來獲取2D頭像的時候,對距離比透視投影要敏感非常多,距離設置到10000就有明顯的區別。
所以推薦的做法是前面說的那種,將臨時對象放在離主角比較近的地方,但讓主角看不到他。
2D頭像的獲取
3D預覽使用透視投影,2D頭像由于離的非常近,如果繼續使用透視投影,很容易出現比例不協調的問題,比如鼻子可能非常大,其他部位特別小,不符合要求。
這個時候就要使用正交投影,繼續使用剛剛的ACapturePreview對象,選中SceneCaptureComponent2D組件,找到Projection選項卡,ProjectionType選擇Orthographic,選擇之后OrthoWidth變得可用,這個選項類似Field,越大則范圍越大,越小則范圍越小。在這個模式下,相機的遠近不會改變捕獲的范圍,需要修改OrthoWidth才有效果。例如下面的選項,設置為50,可以看到TextureTarget部分的預覽。
注意紅框中的兩個選項,PrimitiveRenderMode在前面有提到,為了方便在未運行時預覽TextureTarget,這里不做修改,使用藍圖代碼在運行時修改模式為ShowOnlyList。CaptureEveryFrame是每幀捕獲的意思,可想而知這個選項會帶來相當的消耗。對于2D頭像來說,是靜態的,只需要捕獲一幀就可以了,所以這里取消勾選。
2D頭像在3D的基礎上只是兩點不同:
- 投影方式修改
- 去除CaptureEveryFrame
接下來,探討個稍微復雜點的情況。通過上面的介紹大家基本上明白了,捕獲的基本流程:
- 創建RenderTarget
- 創建使用RenderTarget的材質
- 界面圖像使用指定材質
- 創建臨時Actor,捕獲圖像,更新RenderTarget
這個過程中,我們創建了一個RenderTarget,一個材質,一個臨時對象。如果我們在游戲中需要同時顯示多個動態捕獲的頭像怎么辦?那就得創建N個RenderTarget,N個材質,N個臨時對象?下面就來介紹一種全動態RenderTarget+材質的創建方案,對于捕獲Actor,如果各個需要的場景對鏡頭沒有區分要求,那其實可以使用同一個,然后動態的修改SkeletonMesh就可以。
全動態生成2D頭像
打開WBP_Head藍圖,新建函數UpdateImgMat,新增Input參數,類型選擇為Material Instance Dynamic, 并命名為 ImgMat
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LqmuSM9B-1586704838239)(image-20200412223739043.png)]
并實現函數,此函數可以讓我們使用動態材質來填充圖像。
這三個節點,首先創建一個RenderTarget2D ,然后根據MT_Preview來創建一個動態材質示例,第三個節點就是把前面的RenderTarget2D傳遞給材質的MainTex參數。這就是我們第一步把材質中的紋理提升為參數的目的。實際上動態材質的核心就是上面三個節點,接下來需要做兩件事:
- 把材質傳遞給界面控件
- 把RenderTarget傳遞給捕獲Actor
界面已經提供了接口,調用一下即可,ACapturePreview也需要提供一個接口來接受RenderTarget數據。
函數內容也很簡單
接下來就是稍微改造一下Level Blueprint中的函數CreateDynamicHead 分成四個步驟:
-
創建界面
-
創建臨時Capture對象
-
創建動態的RenderTarget及材質
-
將材質傳遞給界面對象,將RenderTarget傳遞給Catpture對象
按鍵F的響應則只需要直接調用該函數
按F運行游戲,發現頭像跟之前沒有任何的區別。
沒有區別就對了,這里只是展示一種動態構建的方法,效果并沒有改變。對于界面上多個頭像的展示,跟前面的代碼結構類似,不同的界面,使用不同的預覽對象,自行設置就好。由于大家各自使用的RenderTarget和材質都是動態的,所以不會相互干擾,這是主要目的。
總結
以上是生活随笔為你收集整理的UE4 角色预览与头像生成 CaptureSceneComponent2D 看这一篇就够了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linpack性能测试记录
- 下一篇: 智慧养老之居家养老解决方案