為Unity3D編寫Low-level Native Plugin(OpenGL Renderer Plugin)作渲染


為Unity3D編寫Low-level native plugin插件,主要是用作對Unity自帶的render pipeline作拓展使用,可以在其渲染的各個stage插入用戶自己的渲染代碼。

具體的編寫過程與之前的Native Plugin編寫差不多,也是用extern "C"對C++代碼進行封裝,然后導出dll。但是對於renderer plugin來說,有幾個接口是必須要定義的,就如同Unity Documentation上說的那樣。這幾個接口的頭文件可以在Unity安裝文件夾的Editor子文件夾下面的某個子文件夾下面。在寫自己的renderer plugin的時候,要把這些頭文件給包含到項目中。這幾個必須的接口為:

1、void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces);

2、void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload();

顧名思義,就是Plugin的加載和卸載。

在這兩個函數中,我們可以對自己的Opengl renderer進行初始化、資源創建及資源銷毀等操作。

注意:1、在Unity提供的實例中,OpenGL的部分采用的是靜態編譯的形式,而我之前采用的一直是動態編譯的形式。

   2、我在實驗Unity提供的實例的過程中,把所有的源文件轉移到我自己的項目中,編譯出來的dll在Unity中卻完全沒有效果。采用Visual Studio自帶的dumpbin工具對dll導出的符號進行了一番對比之后,發現我的項目導出的符號與Unity示例項目導出的符號有出入,例如,Unity導出的符號為UnityPluginLoad = _UnityPluginLoad@0, 而我的項目導出的為_UnityPluginLoad@0 = _UnityPluginLoad@0,即導出的符號與實際函數的名字並不完全一樣,那么在Unity的manged code中,dllimport導入的默認EntryPoinit就會不一樣,如果不做特殊處理,假設都是聲明如下:

[DllImport("PluginName")]

public static extern UnityPluginLoad(...)

那么我的項目的dll應該就找不到對應函數的入口,所以就不起作用。 后來我發現,示例項目采用了Module Defination文件對dll導出的符號進行設設置。我在我的項目文件中也創建了對應的.def文件,並在項目-屬性-Linker-Input中對應的條目進行設置之后,重新build得到的dll用dumpbin查看之后,就跟示例工程中的一樣了。

那么接下來,如何在Unity的Manged Code中編寫代碼將我自己的Render Code插入到Unity Pipeline中呢? 有兩種方式:

1、CommandBuffer。查詢Unity Documentation發現,Commandbuffer的描述為:List of graphics commands to execute.其中有一個函數為IssuePluginEvent,接收一個IntPtr callback參數和一個int eventID參數,該函數可以將一個進行渲染的回調函數加入到渲染命令Buffer。然后怎么將這個CommandBuffer加入到render pipeline的對應Stage呢?答案在Camera和Light類中,這兩個類中都有一個名為AddCommandBuffer的函數,以Camera為例,有一個類型為Rendering.CameraEvent的參數和一個類型為Rendering.CommandBuffer的函數。第二個參數一目了然,第一個參數是一個enum類型,這里面有相機在渲染pipeline各個階段的enum。

2、GL.IssuePluginEvent. 具體參數看文檔吧,布羅啰嗦了。這個函數沒說在啥階段,你可以把這個函數放在Camera.OnpostRender函數中,然后對應的渲染就在對應的時刻進行。

 

那個渲染的回調函數也要按照Unity給的接口在嚴格實現,具體接口在那些頭文件里有,就是:

void UNITY_INTERFACE_API UnityRenderingEvent(int eventID).

 

值得注意的另外一點是,原生OpenGL世界坐標系是右手坐標系,但是Unity中的世界坐標系是左手坐標系。因此,在從Unity中向Native Renderer Plugin中傳遞世界坐標系中的位置和方向數據時,要注意對x軸的值取反(乘以-1)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM