Version: Unity 6.0 (6000.0)
言語 : 日本語
デスクトッププラットフォーム用プラグインのビルド
低レベルのネイティブプラグインレンダリング拡張

低レベルのネイティブプラグインインターフェース

Unity の ネイティブプラグインは、特定のイベントが発生したときにコールバックを受け取ることができます。これを利用して、プラグインに低レベルレンダリングを実装し、Unity のマルチスレッドレンダリングと連携できます。

インターフェースレジストリ

Unity のメインイベントをハンドルするには、プラグインは UnityPluginLoad および UnityPluginUnload の関数をエクスポートする必要があります。IUnityInterfaces を使用すると、プラグインがこれらの関数にアクセスすることができます。IUnityInterfaces は、プラグイン API の IUnityInterface.h にあります。

#include "IUnityInterface.h"
#include "IUnityGraphics.h"
// Unity plugin load event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();
}

グラフィックスデバイスへのアクセス

IUnityGraphics.h にある IUnityGraphics インターフェースを使用すると、プラグインが汎用グラフィックスデバイス機能にアクセスできるようになります。このスクリプトは、IUnityGraphics インターフェースを使用して、コールバックを登録する方法を示します。

#include "IUnityInterface.h"
#include "IUnityGraphics.h"
    
static IUnityInterfaces* s_UnityInterfaces = NULL;
static IUnityGraphics* s_Graphics = NULL;
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;
    
// Unity plugin load event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    s_UnityInterfaces = unityInterfaces;
    s_Graphics = unityInterfaces->Get<IUnityGraphics>();
        
    s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);
        
    // Run OnGraphicsDeviceEvent(initialize) manually on plugin load
    // to not miss the event in case the graphics device is already initialized
    OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
}
    
// Unity plugin unload event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginUnload()
{
    s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
}
    
static void UNITY_INTERFACE_API
    OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
{
    switch (eventType)
    {
        case kUnityGfxDeviceEventInitialize:
        {
            s_RendererType = s_Graphics->GetRenderer();
            //TODO: user initialization code on graphics device initialization. 
            For example, D3D11 resource creation.
            break;
        }
        case kUnityGfxDeviceEventShutdown:
        {
            s_RendererType = kUnityGfxRendererNull;
            //TODO: user graphics API code to call on graphics device shutdown.
            break;
        }
        case kUnityGfxDeviceEventBeforeReset:
        {
            //TODO: user graphics API code to call before graphics device reset.
            break;
        }
        case kUnityGfxDeviceEventAfterReset:
        {
            //TODO: user graphics API code to call after graphics device reset.
            break;
        }
    };
}

レンダースレッドのプラグインコールバック

プラットフォームと使用可能な CPU の数が許す限り、Unity でマルチスレッドを使用してレンダリングすることができます。

ノート: マルチスレッドレンダリングを使用すると、レンダリング API のコマンドは、MonoBehaviour スクリプトを実行するスレッドとは完全に別のスレッドで実行されます。メインスレッドとレンダースレッドの間で通信が行われるため、メインスレッドがレンダースレッドに渡した作業量によっては、プラグインがすぐにレンダリングを開始しない場合があります。

プラグインからレンダリングするには、マネージプラグインスクリプトから GL.IssuePluginEvent を呼び出します。これにより、以下のコード例に示すように、Unity のレンダーパイプラインがレンダースレッドからネイティブ関数を呼び出します。例えば、Camera の OnPostRender 関数から GL.IssuePluginEvent を呼び出すと、この関数は、カメラがレンダリングを終了するとすぐにプラグインコールバックを呼び出します。

ネイティブプラグインのコード

// Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
{
    // User rendering code
}
    
// Freely defined function to pass a callback to plugin-specific scripts
extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    GetRenderEventFunc()
{
    return OnRenderEvent;
}

マネージプラグインコード

#if UNITY_IPHONE && !UNITY_EDITOR
[DllImport ("__Internal")]
#else
[DllImport("RenderingPlugin")]
#endif
private static extern IntPtr GetRenderEventFunc();
    
// Queue a specific callback to be called on the render thread
GL.IssuePluginEvent(GetRenderEventFunc(), 1);

UnityRenderingEvent コールバックのシグネチャは、ネイティブレンダリングプラグインのサンプルの IUnityGraphics.h にあります。

OpenGL グラフィックス API を使用したプラグイン

OpenGL オブジェクトには 2 種類あります。

  • OpenGL コンテキスト間で共有されるオブジェクト: テクスチャ、バッファ、レンダーバッファ、サンプラー、クエリ、シェーダー、 プログラムオブジェクトなど。
  • OpenGLごとのコンテキストオブジェクト: 頂点配列、フレームバッファ、プログラムパイプライン、変換フィードバック、同期オブジェクトなど。

Unity は複数の OpenGL コンテキストを使用します。エディターとプレイヤーの起動時と終了時にはマスターコンテキストに依存し、レンダリング時には専用のコンテキストを使用します。つまり、kUnityGfxDeviceEventInitialize および kUnityGfxDeviceEventShutdown のイベント中にコンテキストごとのオブジェクトを作成することはできません。

追加リソース

デスクトッププラットフォーム用プラグインのビルド
低レベルのネイティブプラグインレンダリング拡張