Unity Shader Getting Started Essentials learning notes-3rd Unity Shader Foundation

Source: Internet
Author: User

SOURCE Candycat http://blog.csdn.net/candycat1992/article/


In general, we need to work with the materials and unity shader in unity to achieve the desired results. One of the most common processes is.

1) Create a material

2) Create a Unity Shader and assign it to the material created in the previous step

3) Assign the material to the object to be rendered

4) Adjust the properties of unity shader in the material panel to achieve satisfactory results

Shows how unity shader and materials work together to control the rendering of objects.

The materials in unity need to work with a gameobject mesh or particle Systems component. It determines what our game objects look like (which, of course, requires unity shader).

The Unity Shader Foundation: Shaderlab

Unity Shader provides a layer of abstraction for controlling the rendering process. If you don't use Unity Shader (top left), developers need to deal with a lot of file settings to make the picture look the way they want, and with the help of Unity Shader (top right), developers only need to use Shaderlab to write unity The shader file will do all the work.

In unity, all unity Shader are written using Shaderlab. Shaderlab is a descriptive language that unity offers to write unity Shader. It uses some semantics nested inside curly braces to describe the structure of a unity shader file. These structures contain many of the data required for rendering, such as the various properties required by the shader in the properties statement block, which will appear in the material panel. Shaderlab is designed to resemble Cgfx's Direct3D Effects (. Fx) language, all of which define everything needed to display a material, not just shader code.

The infrastructure for a unity Shader is as follows

Unity will compile these constructs into real code and Shader files behind the platforms used, and developers only need to deal with unity Shader.

The structure of Unity Shader

The first line of each unity shader file requires shader semantics to specify the name of the unity shader. The name is defined by a string, such as "MyShader". When you select the Unity Shader for a material, these names appear in the drop-down panel of the material panel. You can control where unity shader appears in the material panel by adding a slash ("/") to the string.

The properties semantic block contains a series of attributes that will appear in the material panel.

The properties semantic block is usually defined as follows:

Properties  {      name ("display Name", PropertyType) = defaultvalue  }  

Developers declare these properties to make it easy to adjust various material properties in the material panel. If we need to access them again in shader, we need to use the name of each property. In unity, the names of these properties usually begin with an underscore. The name displayed is the name that appears on the material panel. We need to specify its type for each property, and the common property type is the following table. In addition, we also need to specify a default value for each property, which is shown on the material panel the first time we assign the unity shader to a material.

Each Unity Shader file can contain more than one subshader semantic block, but at least one, unity will scan all Subshader semantic blocks when unity needs to load the unity Shader. Then select the first subshader to run on the target platform. If none is supported, unity uses the unity Shader specified by fallback semantics.

The reason unity provides this semantics is that different graphics cards have different capabilities.

The definitions contained in the Subshader semantic block are usually as follows.

A series of pass and optional status and label settings are defined in Subshader. Each pass defines a complete rendering process, but if the number of passes is too large, it often results in degraded rendering performance. Therefore, we should try our best to use the minimum number of pass. Status and labels can also be declared in pass. The difference is that some of the label settings in Subshader are specific. In other words, these tag settings are not the same as the tags used in the pass. For state settings, the syntax used is the same. However, if we set this up in Subshader, it will be used for all passes.

Shaderlab provides a set of instructions for rendering status, which can set the various states of the video card, and the following table gives the rendering state setting options that are common in Shaderlab.

When the above rendering state is set in the Subshader block, it will be applied to all passes. If we don't want to do this (for example, in double-sided rendering, we want to remove the front side of the first pass to render the back, and in the second pass to remove the back to render on the front), you can set the above separately in the pass semantics block.

The Subshader tag is a key-value pair whose keys and values are string types. These key-value pairs are a bridge of communication between the Subshader and the rendering engine. They are used to tell Unity's engine: Subshader how and when I want to render this object. The following types of tags are supported:

Note that the above tags can only be declared in the Subshader, but not in the pass block. Pass blocks can also define labels, but they are different from the Subshader label type.

The pass semantic block is defined as follows:

First, we can define the name of the pass in the pass, for example:

" Mypassname "  

With this name, we can use Shaderlab's Usepass command to directly use the pass in other unity Shader, for example:

" Myshader/mypassname "  

This can improve the reusability of the code. It is important to note that because unity internally converts the names of all passes into uppercase letters, you must use the Usepass command with uppercase names.

Second, we can set the render state for pass. The Subshader state setting is universally applicable to pass. In addition to the state settings mentioned above, we can also use the shader command for fixed render pipelines in pass.

Pass also sets the label, but its label is different from the Subshader label. These tabs are used to tell the rendering engine how we want to render the object. The following table shows the type of labels used in the pass.

In addition to the normal pass definitions above, Unity Shader supports special passes for code reuse or for more complex effects.

Following the various subshader semantics blocks, it can be a fallback instruction. It is used to tell unity that if all of the above Subshader are not allowed on this video card, use this lowest level.

It has the following semantics:

" name "  // or   Fallback off  

As mentioned above, we can tell unity who the lowest shader is by a string, and we can also turn off the fallback feature.

In fact, Fallback can also affect the projection of shadows. When rendering a shaded texture, unity looks for a shadow-cast pass in each unity shader. Normally, we don't need to implement a pass by ourselves, because the built-in shader used by fallback contains such a generic pass. Therefore, it is important to set fallback correctly for each unity shader.

The form of Unity Shader

Although Unity shader can do a lot of things, its most important task is to specify the code required for various shaders. These shader codes can be written in the Subshader semantic block (the practice of the surface shader) or in the pass semantics block (vertex/slice shader and fixed function shader practices).

In unity, we can use the following 3 forms to write Unity Shader. Regardless of the form, the shader code in the real sense needs to be included in the Shaderlab semantic block as follows:

" MyShader "   {      properties      {          // required for various attributes       }      subshader      {           // The real shader code will appear here          . // surface shader or vertex/element shader or Fixed function shader      }  

A surface shader is a type of shader code created by unity itself. It requires very little code, and unity does a lot of work behind it, but the cost of rendering it is relatively large. It is essentially the same as the vertex/chip shader that is discussed below. That is, when a surface shader is provided to unity, it is still converted to the corresponding vertex/slice shader behind it. As we can see, the surface shader is a higher level abstraction of Unity's vertex/element shader. The value of its existence is that unity handles a lot of light detail for us, so we don't have to worry about these annoying things.

A very simple surface shader instance code is as follows:

Shader"custom/simple Surface Shader"{subshader {Tags {"Rendertype"="Opaque"} cgprogram#pragmaSurface Surf LambertstructInput {float4 color:color;          }; voidSurf (INPUT in,inout surfaceoutput o) {O.albedo=1; } ENDCG} Fallback"Diffuse"    }  

As can be seen from the above procedure, the surface shader is defined between Cgprogram and ENDCG in the Subshader semantic block. The reason is that the surface shader does not require developers to care about how many passes to use, how each pass is rendered, and unity will do it for us behind the scenes. All we have to do is tell it: "Use these textures to fill the color, use this normal texture to fill the normals, and use the Lambert illumination model." ”

The code between Cgprogram and ENDCG is written using CG/HLSL, which means we need to nest the CG/HLSL language in the Shaderlab language. It is worth noting that the CG/HLSL is provided by unity after encapsulation, its syntax is almost the same as the standard CG/HLSL syntax, but it is still slightly different, such as some of the acoustic functions and usage unity does not provide support.

In unity we can use the CG/HLSL language to write vertex/slice shaders. They are more complex, but more flexible.

The sample code for a very simple vertex/chip shader is as follows:

Shader"custom/simple vertextframent Shader"{subshader {Pass {cgprogram#pragmaVertext Vert#pragmaFrament Fragfloat4 Vert (float4 v:position): sv_position {returnMul (UNITY_MAX_MVP,V); } float4 Frag (): sv_target {return fixed(1.0,1.0,1.0,1.0); } ENDCG} }}

Like a surface shader, the code for a vertex/slice shader needs to be defined between Cgprogram and ENDCG, but unlike the vertex/slice shader, it is written in the pass semantics block, not within the subshader. The reason is that we need to define the shader code we need to use for each pass. While we may need to write more code, the benefits are high flexibility. More importantly, we can control the implementation details of the rendering. Similarly, the code between Cgprogram and ENDCG is also written using CG/HLSL.

Both of these unity Shader forms use a programmable pipeline. For some older devices, they do not support a programmable pipeline shader, so at this point we need to use a fixed function shader to complete the rendering. These shaders tend to do only a few very simple effects.

A very simple fixed function shader sample code is as follows:

" Tutorial/basic "   {      properties{          "Main Color" , color) = (1,0.5 ,0.5,1)      }      subshader{          pass{              material{                  Diffuse[_color]              }              Lightinh on  }   }}

As you can see, the code for the fixed function shader is defined in the pass semantics block, which is equivalent to some of the rendering settings in the pass.

For fixed function shaders, we need to write completely using the syntax of Shaderlab, rather than using CG/HLSL.
Because most GPUs now support a programmable rendering pipeline, this fixed-line programming has been gradually discarded. In fact, in Unity5.2, all fixed function shaders are behind unity being compiled into corresponding vertex/slice shaders, so the true fixed function shader no longer exists.

How to choose which unity Shader:

Unless there is a very clear need to use a fixed function shader, such as the need to run the game on very old devices, do not use a fixed function shader.

If you want to deal with a variety of light sources, you might prefer to use a surface shader, but be careful about how it performs on the mobile platform.

Using a vertex/slice shader is a better choice if there is a small amount of light, such as only one parallel light.

More importantly, if you have a lot of custom rendering effects, the vertex/slice shader is better.

Unity Shader Getting Started Essentials learning notes-3rd Unity Shader Foundation

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.