在UE4中創建新的Shading Model

寫在前面

  • 馬上畢業了;
  • 工作之後作爲弟弟TA使用商業引擎 Unreal 產出,我對它還很陌生,有些擔憂;
  • 個人感覺還是 Unity 好用,Unreal彷彿是寫了一個遊戲模板,大部分用戶直接套,特殊需求不得不改源碼,辛虧UE4開源,或者說UE4不開源沒法用;
  • 大學最後半年各種事情,最後十幾天必須趕緊熟悉一下Unreal,害怕自己去了公司被工友嫌棄;
  • 我的引擎版本是 UE 4.25.1 源碼版;
  • 我是UE萌新,說的不對請見諒,歡迎指正;
  • 我發現在知乎的網友們知道點點贊同,CSDN大家只知道白嫖?!

我的 6300hq 打開 VS 之後,卡的讓人難以忍受,智能提示插件大概率不工作,辛虧我脾氣好
我電腦太辣雞了

正文

下面是新建ShadingModel的流程

C++ 部分

1. 增加一個Shading Model枚舉

Engine\Source\Runtime\Engine\Classes\Engine\EngineTypes.h 文件的 enum EMaterialShadingModel 中添加一個新的 Shading Model 。
EngineTypes
我增加的是 MEM_Toon_01,這個 EMaterialShadingModel 枚舉對應材質編輯器 Details 面板中的 ShadingModel,顯示爲 “Cartoon 01”。

2. 增加對應的關鍵字

如果 ShadingModel 爲我們的"Cartoon 01",我們需要預處理判斷來走這個分支,也就是在生成 HLSL 代碼的時候,序列化的內容。
我這個版本(4.25.1)在 Engine\Source\Runtime\Engine\Private\Materials\HLSLMaterialTranslator.cppvoid FHLSLMaterialTranslator::GetMaterialEnvironment(EShaderPlatform InPlatform, FShaderCompilerEnvironment& OutEnvironment) 函數中增加這個判斷。(根據網上一些文章看來,之前有的版本好像在 MaterialShared.cppSetupMaterialEnvironment 中)
GetMaterialEnvironment
這裏我起的名字是“MATERIAL_SHADINGMODEL_TOON_01”,在材質編輯器打開 HLSL Code 就能看到。

3. 根據情況開啓材質接口(可選)

不同的 ShadingModel 開放的接口不一樣,可以根據情況打開或者關閉一些用不到的接口。
Engine\Source\Runtime\Engine\Private\Materials\Material.cppIsPropertyActive_Internal 函數中修改。
比如說我們的"Cartoon 01"進行着色計算的時候需要用到 “Custom Data 0” 提供數據:
IsPropertyActive_Internal
也可以根據需要隱藏一些數據:
Engine\Source\Editor\PixelInspector\Private\PixelInspectorResult.h 中增加定義:
PixelInspectorResult
Engine\Source\Editor\PixelInspector\Private\PixelInspectorResult.cppDecodeShadingModel 中進行判斷
PixelInspectorResult
Engine\Source\Editor\PixelInspector\Private\PixelInspectorDetailsCustomization.cpp 中的 CustomizeDetails 關閉一些參數:
在這裏插入圖片描述

4. 編譯鏈接一下引擎

現在可以把編輯器關了,用VS生成一下UE4,這裏的生成 == 編譯 + 鏈接;
編譯時間根據CPU和硬盤性能決定,強烈建議把引擎放固態,我電腦太辣雞,頭睡覺前編譯的;
再打開Unreal的材質編輯器,選擇ShadingModel爲新添加的,我這裏是“Cartoon 01”
在這裏插入圖片描述
可以看到,Custom Data 0 接口啓用了

Shader 部分

5. 在Shader中定義關鍵字

Engine\Shaders\Private\ShadingCommon.ush 中定義對應的關鍵字,並修改數量
ShadingCommon
根據需要在GetShadingModelColor函數中定義,在GBuffer中着色類型的顏色
GetShadingModelColor
PS4不支持switch所以用的if-else

6. 開啓CustomData寫入的關鍵字並寫入(可選)

Engine\Shaders\Private\BasePassCommon.ush 爲關鍵字 WRITES_CUSTOMDATA_TO_GBUFFER 增加一個條件,這就是在第二步增加的關鍵字
BasePassCommon
然後在Engine\Shaders\Private\ShadingModelsMaterial.ushSetGBufferForShadingModel函數中添加一個預處理判斷,如果在Toon 01着色模型下,寫入CustomData 0 的值到 GBuffer.CustomData.x
SetGBufferForShadingModel

7. 獲取光源數據

Engine\Shaders\Private\ClusteredDeferredShadingPixelShader.usfClusteredShadingPixelShader 函數中添加我們的着色模型。
ClusteredShadingPixelShader

8. 開啓着色模型混合(可選)

Unreal運行多個ShadingModel混合,需要在 Engine\Shaders\Private\TiledDeferredLightShaders.usfTiledDeferredLightingMain 函數中添加我們的着色模型
TiledDeferredLightShaders

9. 着色計算

Engine\Shaders\Private\ShadingModels.ush 中的 IntegrateBxDF 函數中增加Toon 01的分支
IntegrateBxDF
定義一個在IntegrateBxDF中所調用的光照計算函數
Toon01BxDF
我這裏只是複製了一下Lit的函數,然後給漫反射做了一下閾值

10. 透明模式支持體積光疊加(可選)

Engine\Shaders\Private\BasePassPixelShader.usfFPixelShaderInOut_MainPS 函數中修改預處理條件
在這裏插入圖片描述

重新打開 Unreal 編輯器

會重新編譯Shader,需要一些時間
ViewPort
MaterialEidtor

參考

https://blog.felixkate.net/2016/05/22/ue4-adding-a-custom-shading-model-part-ii/
https://zhuanlan.zhihu.com/p/90265818
https://medium.com/@lordned/ue4-rendering-part-6-adding-a-new-shading-model-e2972b40d72d
https://zhuanlan.zhihu.com/p/36840778
https://zhuanlan.zhihu.com/p/63133742

寫在最後

關於(可選),反正源碼在手裏,足夠熟悉之後,如果有需要,所有腳本都能改;
我可能得在工作中慢慢實踐才能真正熟悉Unreal;
下次寫個後處理之類的;
我想換電腦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章