One of the new features in Unity 5.1 is a new unified OpenGL rendering backend.
Until now, we had a separate renderer for OpenGL ES 2.0, one for OpenGL ES 3.0 (that shared a good deal, but not all, code with ES 2.0) and then a completely different one for the desktop OpenGL (that was stuck in the OpenGL 2.1 feature set). This, of course, meant a lot of duplicate work to get new features in, various bugs that may or may not happen on all renderer versions etc.
So, in order to get some sense into this, and in order to make it easier to add features in the future, we created a unified GL renderer. It can operate in various different feature levels, depending on the available hardware:
All the differences between these API versions are baked into a capabilities structure based on the detected OpenGL version and the extensions that are available. This has multiple benefits, such as:
One of the first new features we brought to the new OpenGL renderer is compute shaders and image loads/stores (UAVs in DX11 parlance). And again, as we have an unified codebase, it is (more or less) automatically supported on all GL versions that support compute shaders (desktop OpenGL 4.3 onwards and OpenGL ES 3.1 onwards). The compute shaders are written in HLSL just as you'd do on DX11 in previous versions of Unity, and they get translated to GLSL. You'll use the same Graphics.SetRandomWriteTarget scripting API to bind the UAVs and the same Dispatch API to launch the compute process. The UAVs are also available on other shader stages if supported by the HW (do note that some, usually mobile, GPUS have limitations on that, for example the Mali T-604 in Nexus 10 only supports image loads/stores in compute shaders, not in pixel or vertex shaders).
Both tessellation and geometry shaders from DX11 side should work directly on Android devices supporting Android Extension Pack. The shaders are written as usual, with either #pragma target 50 or #pragma target es31aep (see below for the new shader targets), and it'll "just work" (if it doesn't, please file a bug).
Here's a short list of other things that are working mostly the same as on DX11
There are some differences to the feature set available in DX11, apart from things discussed above:
The shader compilation process for ES 2.0 and the old desktop GL renderer (and, until now, for ES3.0 as well) is as follows:
The problem with this is that neither of the modules above support anything later than Shader Model 3.0 shaders, effectively limiting the shaders to DX9 feature set. In order to compile HLSL shaders that use DX11 / Shader Model 5.0 features, we are using the following shader compilation pipeline for GL ES 3.0 and above, and for all desktop GL versions running on unified GL backend:
The new shader pipeline seems to be working fairly well for us, and allows us to use the shader model 5.0 features. It also can benefit from the optimizations the D3D compiler performs (but also all the drawbacks of having a bytecode that treats everything as vec4's, always). As a downside, we'll have a dependency to the D3D compiler and the language syntax it provides, so we'll have to go through some hoops to get our Unity-specific language features through (such as sampler2D_float for sampling depth textures).
Existing OpenGL ES 3.0 (and of course, OpenGL ES 2.0) shaders should continue to work as they did previously. If they do not, please file a bug.
For Unity 5.1 release, we are not yet deprecating the legacy OpenGL renderer, so it will still be used on OS X and on Windows when using the -force-opengl flag. The desktop GL renderer is still considered very experimental at this point, but it will be possible to activate it with the following command line arguments for both the editor and standalone player (currently Windows only, OSX and Linux are on our TODO list):
Remember to include the corresponding shaders in the Standalone Player Settings dialog (uncheck the "Automatic Graphics API" checkbox and you'll be able to manually select the shader languages that will be included).
Note that these flags (including the ES flags) can also be used when launching the editor, so the user will see the rendering results of the actual ES shaders that will be used on the target. Also note that these features are to be considered experimental on desktop at this stage, so experiment with these at your own risk. In 5.1, you can also use the standalone player to emulate GL ES targets: In Player settings just make sure you include GL ES2/3 shaders in the graphics API selection and start the executable with one of the -force-glesXX flags above. We're also working on getting this to function on Linux as well.
There are some known issues with running ES shaders on the desktop: Desktop and mobiles use different encoding for normal maps and lightmaps, so the ES shaders expect the data to be in different encoding than what's being packaged alongside the standalone player build. The OpenGL Core shader target should work as expected.
On iOS, the only change is that the ES 3.0 shaders will be compiled using the new shader pipeline. Please report any breakage. ES 2.0 and Metal rendering should work exactly as before. Again, please report any breakage.
On Android, if the “Automatic Graphics API” checkbox is cleared, you can select which shaders to include in your build, and also set manifest requirements for OpenGL ES 3.1 and OpenGL ES 3.1 + Android Extension Pack (remember to set your required API level to Android 5.0 or later as well). The default setting is that the highest available graphics level will always be used.
AN IMPORTANT NOTE:
Apart from some fairly rare circumstances, there should never be any need to change the target graphics level from Automatic. ES 3.1 and ES 3.0 should work just as reliably as ES 2.0, and if this isn't the case, please file a bug. (Of course it is possible to write a shader using #pragma only_renderers etc that will break on ES3 vs ES2 but you'll get the idea.) Same applies to the desktop GL levels once we get them ready. The Standard shader is currently configured to use a simpler version of the BRDF on ES 2.0 (and also cuts some other corners here and there for performance reasons), so you can expect the OpenGL ES 3.0 builds to both have more accurate rendering results and have slightly lower performance figures compared to ES 2.0. Similarily, directional realtime lightmaps require more texture units than is guaranteed to be available in ES 2.0, so they are disabled there.
When writing ShaderLab shaders, the following new #pragma target enums are recognized:
When using the existing #pragma targets, they map to following GL levels:
For including and excluding shader platforms from using a specific shaders, the following #pragma only_renderers / exclude_renderers targets can be used:
As described above, a common GL codebase allows us to finally bring more features to the OpenGL / ES renderer. Here are some things we'll be working on next (no promises, schedule- or otherwise, your mileage may vary, please talk with your physician before use, and all the other usual disclaimers apply):