文档

Unity Engine

Unity Engine

低级原生插件接口

Implement low-level rendering in your native plug-ins.
阅读时间4 分钟最后更新于 1 个月前

Unity 中的原生插件可以在发生某些事件时接收回调。此功能可用于实现插件中的低级渲染,以便低级渲染能够与 Unity 的多线程渲染一起使用。

接口注册表

要处理主要的 Unity 事件,插件必须导出
UnityPluginLoad
和
UnityPluginUnload
函数。IUnityInterfaces 使插件能够访问这些函数,您可以在插件 API 中的
IUnityInterface.h
中找到这些函数:
#include "IUnityInterface.h"#include "IUnityGraphics.h"// Unity plugin load eventextern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces){ IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();}

访问图形设备

使用
IUnityGraphics
接口(可在
IUnityGraphics.h
中找到)可让插件访问通用图形设备功能。此脚本演示了如何使用
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 eventextern "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 eventextern "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 的渲染管线从渲染线程调用原生函数,如下代码示例所示。例如,如果从摄像机的 OnPostRender 函数调用 GL.IssuePluginEvent,则在该摄像机已完成渲染后,函数将立即调用插件回调。
原生插件代码:
// Plugin function to handle a specific rendering eventstatic void UNITY_INTERFACE_API OnRenderEvent(int eventID){ // User rendering code} // Freely defined function to pass a callback to plugin-specific scriptsextern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRenderEventFunc(){ return OnRenderEvent;}
托管插件代码:
#if UNITY_IPHONE && !UNITY_EDITOR[DllImport ("__Internal")]#else[DllImport("RenderingPlugin")]#endifprivate static extern IntPtr GetRenderEventFunc(); // Queue a specific callback to be called on the render threadGL.IssuePluginEvent(GetRenderEventFunc(), 1);
原生渲染插件示例的 IUnityGraphics.h 中提供了
UnityRenderingEvent
回调的签名。

使用 OpenGL 图形 API 的插件

有两种 OpenGL 对象:
  • OpenGL 上下文共享的对象,例如纹理、缓冲区、渲染缓冲区、采样器、查询、着色器和程序对象。
  • Per-OpenGL 上下文对象,例如顶点数组、帧缓冲区、程序管线、变换反馈和同步对象。
Unity 使用多个 OpenGL 上下文。在初始化和关闭编辑器和播放器时,Unity 依赖于主上下文,但我们使用专用上下文进行渲染。即,在
kUnityGfxDeviceEventInitialize
和
kUnityGfxDeviceEventShutdown
事件期间无法创建每个上下文的对象。

其他资源