潤稿:Kelvin Lo
我們之前分享了詳解Unity WebGL記憶體。今天我們一起來看看Unity WebGL平台如何使用低階(Low-Level)Plugin,如果你想用網頁重用現有的C/C++程式碼,例如OpenGL ES的圖形效果,就別錯過今天的內容。我們從Plugin類型、如何實現以及展示範例幾個方面進行探討。
Unity支援兩種類型的Plugin:託管(Managed)Plugin和原生(Native)Plugin。對於託管Plugin來說,WebGL與其它平台支援託管Plugin的方式一致,唯一的區別在於Plugin的託管程式集與引擎及使用者的託管程式碼會一起轉為JavaScript,這裡指asm.js/wasm。
對於原生Plugin來說,針對網頁來談"native"真的有意義嗎?如果原生指的是例如Mac,Win 32/64等底層架構,當然沒有意義。然而,Unity WebGL也支援幾種其它類型的Plugin:JavaScript、C/C++以及預編譯的LLVM位元組碼。
Unity使用手冊中有幾個WebGL平台下JavaScript和C語言Plugin的例子,並且展示了如何透過程式和它們溝通。既然可以使用C/C++原始程式碼,那就可以存取低階的Plugin介面來渲染。Unity 5.5就可以透過新加的連結器,來和低階Plugin綁定。
最初的OpenGL 2.0 Demo是用C++和GLSL寫的,所以只需做一些修改,就能和前面的原生渲染Plugin Demo完美相容。您可以下載Unity的Demo專案和Plugin原始碼。
本文介紹了Unity WebGL中低階Plugin的實現辦法。考慮到Unity WebGL平台的除錯工具並不豐富,建議可以在不同的GLES2/3 API平台上製作原型,確保WebGL平台一旦建立成功同時也能在iOS、Android或PC正常執行。
我們之前分享了詳解Unity WebGL記憶體。今天我們一起來看看Unity WebGL平台如何使用低階(Low-Level)Plugin,如果你想用網頁重用現有的C/C++程式碼,例如OpenGL ES的圖形效果,就別錯過今天的內容。我們從Plugin類型、如何實現以及展示範例幾個方面進行探討。
Unity支援兩種類型的Plugin:託管(Managed)Plugin和原生(Native)Plugin。對於託管Plugin來說,WebGL與其它平台支援託管Plugin的方式一致,唯一的區別在於Plugin的託管程式集與引擎及使用者的託管程式碼會一起轉為JavaScript,這裡指asm.js/wasm。
對於原生Plugin來說,針對網頁來談"native"真的有意義嗎?如果原生指的是例如Mac,Win 32/64等底層架構,當然沒有意義。然而,Unity WebGL也支援幾種其它類型的Plugin:JavaScript、C/C++以及預編譯的LLVM位元組碼。
Unity使用手冊中有幾個WebGL平台下JavaScript和C語言Plugin的例子,並且展示了如何透過程式和它們溝通。既然可以使用C/C++原始程式碼,那就可以存取低階的Plugin介面來渲染。Unity 5.5就可以透過新加的連結器,來和低階Plugin綁定。
如你所見,我們需要加很多程式,來看看實現Plugin需要哪些步驟。
首先,需要將Unity安裝目錄下Editor/Data/PluginAPI中的Plugin API標頭檔,複製到Plugin原始檔案所在的目錄。Plugin使用標頭檔IUnityInterface.h和IUnityGraphics.h來宣告所需的介面。由於這些標頭檔適用於特定的Unity版本,所以確保與編輯器版本同步是很重要的。註冊Plugin需要呼叫函數UnityRegisterRenderingPlugin。
extern "C" void UnityRegisterRenderingPlugin(PluginLoadFunc loadPlugin, PluginUnloadFunc unloadPlugin);
無論如何,首先需要實現Load和Unload的callback函數來取得IUnityGraphics介面,並註冊或登出用於底層渲染的圖形設備callback函數。程式如下:
實現了以上介面,就可以註冊Plugin了。
最後,啟動時需要加上C#綁定並註冊Plugin,確保UnityRegisterRenderingPlugin確實執行了。
然後需要實現OnGraphicsDeviceEvent並加上渲染碼。
請注意,如果不同的平台使用相同的Plugin原始檔案,可以檢查__EMSCRIPTEN__或UNITY_WEBGL(僅限Unity 5.6及以上版本)來條件編譯程式。
最後,如果需要瀏覽系統標頭檔,如:gl2.h,可以在Unity安裝目錄下找到:
Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/Emscripten/system/include
如果有興趣嘗試製作渲染Plugin,研究Unity官方Bitbucket上的NativeRenderingPlugin是一個非常棒的起點。它已經設定註冊了所需的callbacks,編譯了自己的著色器,並展示如何在簡單的Unity場景中渲染一個三角面。
注意,在Unity WebGL中不需要單獨建立C/C++Plugin。這個範例中的Unity專案包含一個簡單的檔(Plugins / WebGL / RenderingPlugin.cpp),其中包含了Plugin的具體實現,如下所示:
介接Plugin
首先,需要將Unity安裝目錄下Editor/Data/PluginAPI中的Plugin API標頭檔,複製到Plugin原始檔案所在的目錄。Plugin使用標頭檔IUnityInterface.h和IUnityGraphics.h來宣告所需的介面。由於這些標頭檔適用於特定的Unity版本,所以確保與編輯器版本同步是很重要的。註冊Plugin需要呼叫函數UnityRegisterRenderingPlugin。
extern "C" void UnityRegisterRenderingPlugin(PluginLoadFunc loadPlugin, PluginUnloadFunc unloadPlugin);
無論如何,首先需要實現Load和Unload的callback函數來取得IUnityGraphics介面,並註冊或登出用於底層渲染的圖形設備callback函數。程式如下:
IUnityInterfaces* s_UnityInterfaces = 0;
IUnityGraphics* s_Graphics = 0;
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_UnityInterfaces = unityInterfaces;
s_Graphics = s_UnityInterfaces->Get<IUnityGraphics>();
s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);
// Run OnGraphicsDeviceEvent(initialize) manually on plugin load
OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
}
實現了以上介面,就可以註冊Plugin了。
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API RegisterPlugin()
{
UnityRegisterRenderingPlugin(UnityPluginLoad, UnityPluginUnload);
}
最後,啟動時需要加上C#綁定並註冊Plugin,確保UnityRegisterRenderingPlugin確實執行了。
class MyRenderPlugin
{
#if UNITY_WEBGL && !UNITY_EDITOR
[DllImport ("__Internal")]
private static extern void RegisterPlugin();
#endif
void Start()
{
RegisterPlugin();
}
}
然後需要實現OnGraphicsDeviceEvent並加上渲染碼。
#include <GLES2/gl2.h>
static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
{
// OpenGL ES calls here...
}
請注意,如果不同的平台使用相同的Plugin原始檔案,可以檢查__EMSCRIPTEN__或UNITY_WEBGL(僅限Unity 5.6及以上版本)來條件編譯程式。
#if defined(UNITY_WEBGL)
// Unity WebGL-specific code
#endif
最後,如果需要瀏覽系統標頭檔,如:gl2.h,可以在Unity安裝目錄下找到:
Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/Emscripten/system/include
Plugin範例
如果有興趣嘗試製作渲染Plugin,研究Unity官方Bitbucket上的NativeRenderingPlugin是一個非常棒的起點。它已經設定註冊了所需的callbacks,編譯了自己的著色器,並展示如何在簡單的Unity場景中渲染一個三角面。
注意,在Unity WebGL中不需要單獨建立C/C++Plugin。這個範例中的Unity專案包含一個簡單的檔(Plugins / WebGL / RenderingPlugin.cpp),其中包含了Plugin的具體實現,如下所示:
#include "../../../../PluginSource/source/RenderingPlugin.cpp"
#include "../../../../PluginSource/source/RenderAPI.cpp"
#include "../../../../PluginSource/source/RenderAPI_OpenGLCoreES.cpp"
展示
最初的OpenGL 2.0 Demo是用C++和GLSL寫的,所以只需做一些修改,就能和前面的原生渲染Plugin Demo完美相容。您可以下載Unity的Demo專案和Plugin原始碼。
總結
本文介紹了Unity WebGL中低階Plugin的實現辦法。考慮到Unity WebGL平台的除錯工具並不豐富,建議可以在不同的GLES2/3 API平台上製作原型,確保WebGL平台一旦建立成功同時也能在iOS、Android或PC正常執行。
沒有留言:
張貼留言