Search Unity

Last year we launched a series of technical blog posts on WebGL, starting with a couple of posts on memory. Now it’s time to continue with a new topic.
Have you ever needed/wanted to re-use existing C/C++ code in a web page? Perhaps a graphics effect written in OpenGL ES? With Unity WebGL there is a way!

Unity supports two types of plugins: managed and native. On WebGL, managed plugins are supported like on other platforms. The only difference is that the managed assembly of the plug-in is converted, along with the engine and user’s managed code, to JavaScript (asm.js/wasm to be specific).

What about native plugins? Does it even make sense to talk about something “native” on the web? When referring to native as something specific to the underlying architecture (mac, win32/64, etc.), it certainly does not. However, Unity WebGL does support several other types of plugins: JavaScript, C/C++ and pre-compiled LLVM byte code.

 

In the Unity User Manual, there are a couple of examples of both JavaScript and C plugins that demonstrate how to interact with them via scripts. So, since we can use C/C++ sources, what’s stopping us from accessing the Low-Level plugin interface for rendering purposes? Well… nothing in Unity 5.5 ;-)

In fact, Unity 5.5 adds the missing hooks to allow you to register a low-level plugin:

As you can see, the amount of code we had to add is massive. Now let’s see what you need to do to implement your plug-in!

 

Implementation

First of all, you need to copy the Plugin API headers from the Unity install path Editor/Data/PluginAPI to the location that will contain your plug-in source file(s).

The headers you are interested in are IUnityInterface.h and IUnityGraphics.h, which declare the interfaces needed for the plugin. Remember that these headers are specific to a version of Unity, so it’s important to keep them in sync with the Editor.

The function you need to call to register your plugin is UnityRegisterRenderingPlugin:

 

However, first you need to implement both Load and Unload callbacks to get the IUnityGraphics interface and register/unregister the graphics device event callback for your low-level rendering. Here is an example:

 

Once those are implemented, you can register them:

 

And finally, you need to add the the C# binding and register the plug-in on startup (so that UnityRegisterRenderingPlugin is actually executed):

 

Then all you need to do is to implement OnGraphicsDeviceEvent and add your rendering code.

 

Note that if the same plug-in source files are used on different platforms, you can check __EMSCRIPTEN__ or UNITY_WEBGL (5.6+ only) to conditionally compile your code:

 

Finally, if you need to browse system headers (e.g.: gl2.h), you can find those in your Unity install path under: Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/Emscripten/system/include

Sample plug-in

Our NativeRenderingPlugin on Bitbucket is a great starting point if you are interested in trying to make your own rendering plug-in. It’s already setup to register the required callbacks, compile own Shaders, and it demostrates how to render a triangle on top of a simple Unity Scene.

Note that on Unity WebGL, there is no need to build the C/C++ plug-in separately. The Unity project of this sample contains a simple file (Plugins/WebGL/RenderingPlugin.cpp), which includes the actual implementation of the plug-in and looks like the following:

 

Demo

If you are viewing this page on a browser/device supported by Unity WebGL, see the demo below, which demonstrates a Mandelbrot effect written in OpenGL ES via Native Rendering Plugin:

 


The original OpenGL 2.0 demo was written in C++ and GLSL, so we only had to make a few modifications to make it work with our Native Rendering Plugin sample mentioned earlier.

If you want to take a peek at this demo Unity project and plug-in source code, click here to download them.

Conclusion

There might be several different reasons for writing low-level plug-ins; at least now you know that it is possible. One final suggestion: considering the lack of debugging tools on Unity WebGL, you might want to prototype on a different GLES2/3 API platform, so that you only build for WebGL once everything works properly on iOS/Android or Standalone.

Have fun!

Ya no se aceptan más comentarios.

  1. Pоrtability: can yoᥙ have this along with you as you get around your house or even when you
    traveⅼ?

  2. Α one hand release and also a complеtely removable swing
    stop device ensure tҺat dߋesn’t open out … Leɑqrn more.

  3. #Ьabygates.

  4. Oopps, double post. This form has some bugs in Chrome and Firefox. Had to copy and paste content in order to submit. And even then there’s an error message after posting…

  5. The WebGL plugin system is very flexible. It lets you do things like [Speech Detection] in the Browser!

  6. Big fan of the WebGL plugin system. It lets you do things like Speech Detection in the Browser!
    https://github.com/tgraupmann/UnityWebGLSpeechDetection

  7. Any road-map to mobile browser?

    1. When we first launched the WebGL built target in Unity we decided to only support desktop browsers because of the technical limitations of this platform (e.g.: memory and performance). Since then we have been spending a lot of time on optimizations, especially on the memory consumption front. Meanwhile, browsers are also getting more performant and memory efficient. Lastly, hardware specs of new mobile devices are getting better and better. All these factors are contributing to make mobile support possible at some point but we think we are not there yet and it’s hard to predict when that will be the case.

  8. New features new bugs!
    we spent several month on our game and now crash on some devices !

    1. Marco Trivellato

      enero 20, 2017 a las 8:36 am

      This is not exactly a new feature. Anyway, if you post in the webgl forum about your crash, we can try to help you.

  9. Nicholas Ventimiglia

    enero 19, 2017 a las 7:29 pm

    This looks like fun, I cant wait !