Unity5 optimization of internal rendering 3: removing the fixed function

Source: Internet
Author: User
Tags unity 5

A total of 3 articles from the Aras blog, describing Unity5 's process of optimizing its own renderer
Learn how to optimize the unity5 internal renderer by drawing on the experience of the great God's commissioning and optimization

First:Unity5 optimization of internal rendering 1: Introduction

Article Two:Unity5 optimization of internal rendering 2: Cleanup

The previous article has written about cleanup and optimization. Since then, I have shifted to doing some unity5.1 work, removing the fixed function shader shaders and some other things.

What is a fixed function?Previously, the GPU had no "programmable shader programmable shaders"; by enabling and disabling certain features, the configuration was more or less flexible (mostly small). For example, let them calculate the light for each vertex, or add two map colors to each pixel.
Unity has been around for a long time, so it's natural to support fixed-function shaders. Their syntax is simple, and if you just write some simple shaders, it will run faster than the vertex/pixel shader.
For example: A shader pass is set to alpha blending, which outputs the product of the texture and color:
Blend Srcalpha Oneminussrcalpha
SetTexture [_maintex] {Constantcolor[_color] combine texture * contant}

Do exactly the same thing as Vertex + pixel and produce the same result
Blend Srcalpha Oneminussrcalpha
#pragma vertex vert
#pragma fragment Frag
#include "Unitycg.cginc"
struct V2F
FLOAT2 uv:texcoord0;
FLOAT4 pos:sv_position;
FLOAT4 _maintex_st;
v2f Vert (float4 pos:position, Float2 uv:texcoord0)
v2f o;
O.UV = Transform_tex (UV, _maintex);
return o;
Sampler2d _maintex;
Fixed4 _color;
Fixed4 Frag (v2f i): Sv_target
Return tex2d (_maintex, I.UV) * _COLOR;
Now we've removed support for fixed function GPU, and some platforms on unity4.3 (2013 years) (OpenGL ES 1.1 on mobile and Direct3D 7 GPUs on Windows). There is no technical need to write fixed-function shaders now, and there is no need for them. Unless: 1. There are many of these shaders in existing projects. 2. Just want to less typing.
In fact, fixed-function shaders also have many drawbacks:
1. They do not work on the host (Ps4,xbox One,vita), it is very difficult to generate shaders on these platforms in real time.
2. They cannot work with materialpropertyblocks, cannot be used on the rendering of Unity's sprite, nor can it be used on animated materials.
3. They are only suitable for doing very simple things, you make a simple fixed function shader, then found that need to add more features, there is no way to do more.

How does a fixed function shader perform on unity? Why? Most platforms we do not support fixed-function rendering pipelines, which are internally converted to "actual shaders" for rendering. Only one fixed feature shader can present exceptions are legacy desktop OpenGL (GL 1.x-2.x) and Direct3D 9.
To more platforms, on OpenGL ES 2.0 We implemented a similar thing to D3d9, replacing the D3d9shader binary connection assembly as a connection GLSL fragment. Then more platforms appear (D3D11, Flash, Metal), and each platform executes the "fixed function" code. The code is not particularly complex, the problem is well understood and we have done enough graphical testing to verify the work.
At every step in the process, no one doubts why we should continue to do "Why build in real time?" Instead of offline, convert it when the fixed-function shader is imported? " (if someone asks the question, the answer is, "it would make sense to do it, just need someone to do it" for a while ...) )”
A long time ago, offline conversion of fixed function shaders was not very practical because there were a number of possible variants that needed to be supported. The trickiest part is support for texture coordinates (sending UV-to-texture stages, an optional texture transformation matrix, an optional texture projection, and an optional texture coordinate generation texture coordinate generation). But hey, we've removed a lot of things from unity5. Has it become simpler? Yes.
converting a fixed function shader to a normal shader on import
The shader in Unity can be written in the form of "fixed function", for example: You can write "light on" to get the vertex-by-point lighting, which is also useful in super-sampled shader (less typing), and a lot of shader is written like this.
Now (4.,5.0/5.1) These fixed function shaders are processed at run time:
They load & parse into internal Shaderlab performance.
Whenever a new "fixed function state" is required, a new "actual shader" is generated and used to calculate
Fully platform-dependent: D3D9,D3D11,OPENGL,METAL,GLES,PSM
The host/dx12 cannot be fully executed
"Generate actual shader" when shader is imported is much better, and then all runtime code is removed.
Benefit: Remove a lot of code!
Benefit: Removing a small fraction of the useless in the render loop, it is only generated by the fixed function.
Benefits: Can work on the host, Dx12,vulkan, etc.
Benefits: Cross-platform behavior is more consistent (now there are subtle differences, such as: The high light on the mobile side is different; The fog works a little differently)
Cons: Generating a fixed function from a script through "new Material (String)" Shader will stop working
"New Material (String)" is marked as obsolete by 5.1.
means backwards compatibility. Break the change. means that 5.2 should separate the 5.0/5.1 Webplayer into a separate channel.

So I'm going to do this, removing all the runtime code for the fixed-function shader, and replacing it with just importing shader in Unity editor translates them into "normal shaders." Create an overview of data & planning work on the wiki and start programming. I thought the end result would be "I wrote a new 1000 lines of code to remove 4000 lines" But I was wrong!
Once I was working on the basics of importing shader (as a result, about 1000 lines of code), I started removing the entire fixed functionality section. It's a happy day (eg:)

About 12,000 lines of code, disappeared, really amazing!

I don't remember the fixed feature having that much code, you write it for a platform, and then it basically works, and then some new platforms appear to write new code about it, and then it basically works. Then there are n platforms, and the amount of code added together is huge, because it's not so much code all at once, so no one finds out about the problem.
Take away: Occasionally, look at the entire subsystem. You may be shocked that it expanded so many years later. Perhaps some of these things are not applicable for some reason.

Side note: Vertex-wise illumination in a vertex shaderIf there's one thing that makes it easy to fix a functional line, it's easy to combine many features. You can use a lot of lights (up to 8) they are direction light,point light or spot lighting. Just a flag flag control the high-light opening and shutting, fog fog is also the same.
It feels like "the simple form of a feature." When we put everything in the shader, we lost something important. We know that shader (vertex/fragment/... stages) cannot be combined! There are pros and cons to adding some optional features, which almost means "add twice times shader", or branch shader, or generate shader in real time.
For example, how do you write a vertex shader that can be close to 8 light sources? There are a number of ways that I'm doing now:
Detach vertex shader to "have spot light?" "Is there a point light?" "Only directional light" these conditions. I guess spot light is rarely used for fixed-vertex lighting, and they look particularly bad. So in a number of cases, there is no "calculate spot light" consumption.
The number of light sources is passed into the shader as integers, and shader loops in them. Complex: OpenGL es 2.0/webgl, loops are the number of cycles you can only count: In practice, OpenGL ES 2.0 does not have this limitation many times, but WebGL is definitely the limit. I don't have a good answer at this point. In Es2/webgl I just loop through 8 possible light sources (not using a light source set to black). A real solution, a regular loop is this:
uniform int lightcount;
// ...
for (int i = 0; i < Lightcount; ++i)
Compute Light #i
When compiling under ES2.0/WEBGL, I want to edit shader like this: (Bo main note: According to the above mentioned 8 each cycle again)
uniform int lightcount;
// ...
for (int i = 0; i < 8; ++i)
if (i = = Lightcount)
Compute Light #i
It's annoying to deal with seemingly arbitrary restrictions like this (I've heard that webGL2 has no such restrictions, which is great)
What do we have now?So now the situation is this, removing a lot of code, I got the following benefits:
1. "Fixed function style" shader can be run on all platforms (host!) dx12! )
2. They work more stably across platforms (for example: there are subtle differences between high light and attenuation in pc& phones)
3. "Fixed function style" shader can work with materialpropertyblocks, meaning it can render sprites, and so on.
4. Fixed function shader No more weird half-pixel offsets in the grating on the Windows Phone
5. Fixed function shader conversion to actual shader is easier; I added a button in shader inspector to show all the generated code; You can copy and extend it.
6. The code is reduced, and the size of the converted executable file becomes smaller. For example, the Windows kilobytes bit is small.
7. Rendering is slightly faster (even if no fixed function shader is used)

The last point is not the main goal, but it is a good benefit. There is no particularly large impact, but quite a number of branches and data are removed from the Platform graphics abstraction (only where the run-time fixed functionality is supported). I tried it on the project and saved 5% of the time in the render thread (for example: 10.2ms->9.6ms), which worked very well.

Do you have any shortcomings? Yes, there are several:
1. You can no longer create a fixed function shader at run time. Before you can do this var mat = new Material ("<fixed function Shader string>") can be run in addition to the host. For this reason, I did material (string) in unity5.1 will be marked as outdated and warn, but in fact it will stop working.
2. Backwards compatibility with web player can be disruptive if the code is developed in Unity 5.2, which means no more running on unity5.0/5.1
3. In several special cases may not work, for example: fixed function shaders use a global setting texture instead of a 2D texture. In the shader resource itself, nothing about that texture is specified, so when I generate actual shader when I import a fixed function shader, I don't know if it's a 2D or cubemap texture. So for global textures, I'm just assuming they're all 2D textures.
4. That's about it!
There are a number of potential benefits to removing support for real-time pinning functionality. Internally for all textures to change we pass something like "texture type (2D,CUBEMAP, etc.)"-but it seems that only a fixed-function pipeline will use it. Similarly, for each draw call we pass a vertex-declaration-like structure; but now I don't think I need them anymore.

Three end of article ...

------translated from: wolf96 http://blog.csdn.net/wolf96

Unity5 optimization of internal rendering 3: removing the fixed function

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.