寫在前面
- 馬上畢業了;
- 工作之後作爲弟弟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 。
我增加的是 MEM_Toon_01,這個 EMaterialShadingModel
枚舉對應材質編輯器 Details 面板中的 ShadingModel,顯示爲 “Cartoon 01”。
2. 增加對應的關鍵字
如果 ShadingModel 爲我們的"Cartoon 01",我們需要預處理判斷來走這個分支,也就是在生成 HLSL 代碼的時候,序列化的內容。
我這個版本(4.25.1)在 Engine\Source\Runtime\Engine\Private\Materials\HLSLMaterialTranslator.cpp
的 void FHLSLMaterialTranslator::GetMaterialEnvironment(EShaderPlatform InPlatform, FShaderCompilerEnvironment& OutEnvironment)
函數中增加這個判斷。(根據網上一些文章看來,之前有的版本好像在 MaterialShared.cpp
的 SetupMaterialEnvironment
中)
這裏我起的名字是“MATERIAL_SHADINGMODEL_TOON_01”,在材質編輯器打開 HLSL Code 就能看到。
3. 根據情況開啓材質接口(可選)
不同的 ShadingModel 開放的接口不一樣,可以根據情況打開或者關閉一些用不到的接口。
Engine\Source\Runtime\Engine\Private\Materials\Material.cpp
的 IsPropertyActive_Internal
函數中修改。
比如說我們的"Cartoon 01"進行着色計算的時候需要用到 “Custom Data 0” 提供數據:
也可以根據需要隱藏一些數據:
在 Engine\Source\Editor\PixelInspector\Private\PixelInspectorResult.h
中增加定義:
在Engine\Source\Editor\PixelInspector\Private\PixelInspectorResult.cpp
的 DecodeShadingModel
中進行判斷
在 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
中定義對應的關鍵字,並修改數量
根據需要在GetShadingModelColor
函數中定義,在GBuffer中着色類型的顏色
PS4不支持switch
所以用的if-else
6. 開啓CustomData寫入的關鍵字並寫入(可選)
在Engine\Shaders\Private\BasePassCommon.ush
爲關鍵字 WRITES_CUSTOMDATA_TO_GBUFFER
增加一個條件,這就是在第二步增加的關鍵字
然後在Engine\Shaders\Private\ShadingModelsMaterial.ush
的SetGBufferForShadingModel
函數中添加一個預處理判斷,如果在Toon 01着色模型下,寫入CustomData 0 的值到 GBuffer.CustomData.x
7. 獲取光源數據
在 Engine\Shaders\Private\ClusteredDeferredShadingPixelShader.usf
的 ClusteredShadingPixelShader
函數中添加我們的着色模型。
8. 開啓着色模型混合(可選)
Unreal運行多個ShadingModel混合,需要在 Engine\Shaders\Private\TiledDeferredLightShaders.usf
的 TiledDeferredLightingMain
函數中添加我們的着色模型
9. 着色計算
在 Engine\Shaders\Private\ShadingModels.ush
中的 IntegrateBxDF
函數中增加Toon 01的分支
定義一個在IntegrateBxDF
中所調用的光照計算函數
我這裏只是複製了一下Lit的函數,然後給漫反射做了一下閾值
10. 透明模式支持體積光疊加(可選)
在 Engine\Shaders\Private\BasePassPixelShader.usf
的 FPixelShaderInOut_MainPS
函數中修改預處理條件
重新打開 Unreal 編輯器
會重新編譯Shader,需要一些時間
參考
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;
下次寫個後處理之類的;
我想換電腦