Interpreting the compiling of Shader Series 2 by CG in Unity and interpreting unitycgshader
In the example in the previous article, we can see that the output parameters of the vertex shader are directly transmitted as the form parameters of the fragment shader, so a problem may arise, where is the form parameter of the vertex coloring tool passed from?
The shape parameter of the vertex shader is the meshRenderer component of the gameObject that passes all mesh data to OpenGL at a time per frame. This intermediate process is often called a draw call. It is more efficient to transmit a large amount of mesh information at a time as a draw call than to transmit a small amount of mesh information multiple times.
In the previous example, we only accept the POSITION information transmitted by MeshRenderer. In fact, there is still a lot of information that is not accepted. To receive some Mesh information data in the vertex coloring tool, you only need to get the corresponding information after the correct semantics of the parameters. All the mesh information obtained by the vertex coloring tool based on the semantics are: float4 vertex: POSITION; // vertex coordinates.
Float4 tangent: TANGENT; // tangent, a type of trigonometric function. tan is the tangent of the mesh to the surface normal.
Float3 normal: NORMAL; // surface method vector, Which is normalized to the unit length in the object Coordinate System
Float4 texcoord: TEXCOORD0; // 0th sets of texture coordinate system
Float4 texcoord1: TEXCOORD1; // 1st sets of texture coordinate system
Fixed4 color: COLOR; // color, usually constant
Similarly, we can declare the input struct of a vertex shader, which contains all the above information, and then pass this struct as a form parameter to the entry function of the vertex shader.
Built-in predefined input struct of Unity: you only need to reference UnityCg. cginc header files (directory Unity> Editor> Data> CGIncludes) can be directly used using preset struct, which have appdata_base appdata_tan and appdata_full:
struct appdata_base {float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};struct appdata_tan {float4 vertex : POSITION;float4 tangent : TANGENT;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};struct appdata_full {float4 vertex : POSITION;float4 tangent : TANGENT;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;float4 texcoord1 : TEXCOORD1;fixed4 color : COLOR;};
You can directly select the appropriate input struct as needed. We can write code in this form:
Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct vertexOutput {float4 pos : SV_POSITION;float4 col : TEXCOORD0;};vertexOutput vert(appdata_full input){vertexOutput output;output.pos = mul(UNITY_MATRIX_MVP, input.vertex);output.col = input.texcoord;return output;}float4 frag(vertexOutput input) : COLOR{return input.col;}ENDCG}
You can see the effect of running on the sphere:
Example 2: fake Color Image
Before learning about a pseudo-color image, it is more important to regard the color as a vector, So we focus on one of the components of this vector, so that the other components remain unchanged. For example, when the texcoord parameter in the input information of sphere is passed to the segment color with the semantic TEXCOORD0, the component of the color in the red direction is the final x coordinate color of texcoord. That is to say, whether the color is pure red, pure yellow, or pure foreign red, the red weight is always 1. (The three primary colors of the computer are red, green, and blue. Yellow is not one of the three primary colors. Yellow is also synthesized from Red.) The relative color is pure blue, pure green, or pure blue, and the red weight is always 0. Let's take a look at the role of the following line of code:
output.col = float4(input.texcoord.x, 0.0, 0.0, 1.0);
Obviously, the x parameter of texture coordinates is used as the red component to construct a color vector. The green and blue components are constant at 0, and the opacity is constant at 1, in this case, the sphere is a one-dimensional linear color sphere with the x coordinate of the texture coordinate as the variable element. (It can also be understood that the latitude of the earth is a variable, forming a earth composed of Black (,) to red)
View the effect of this pseudo-color sphere after horizontal Reverse Rotation
When we imagine that we only focus on the red weight of the color, we can see that when the rotation sphere rotates from 0 ° to 360 ° and then returns to 0 °, the red weight changes from 0 to 1, cycle. It is very similar to the latitude coordinates of the planetary surface.
Similarly, the following line of code is used to form a linear color sphere from black to green with the longitude of the sphere as the yuan:
output.col = float4(0.0, input.texcoord.y, 0.0, 1.0);
It can be imagined that the Antarctic of this sphere should be black (,), and the Arctic should be green)
To see the effect of this pseudo-colored sphere from the south pole of the sphere
Here, in fact, the concept of False Color, PS friends should be able to immediately think of the channel, in fact, is the red channel green channel and blue channel, however, from the vector point of view, they are the components of the color vector. We can understand that the color is a mixture of three channels, or it can be considered as a combination vector of three components.
Texture coordinates (texture coordinates) are ideal for displaying colors because their values range from 0 ~ 1. Therefore, a texture coordinate can be mapped to a color one by one without any conversion.
The normal vectors on coordinates can also be used to represent colors, but must be converted. Because the value range of the normal vector is-1 to + 1, assuming that the normal vector of a coordinate x, y, and z is α, the range of α is (-1,-1, -1) to (, 1), it is very easy to map it to a color by mathematical conversion:
α and (, 1) are added to the vector and then divided with 2 to obtain a vector from (, 0) to (, 1, the fourth Opacity is called an RGBA color vector. So the code is:
output.col = float4((input.normal + float3(1.0, 1.0, 1.0)) / 2.0, 1.0);
I will not give it here. You can try it by yourself.
It can be seen that if we want to display the data in the mesh information in color, if each component of the value range of the original information is not [0, 1], we only need to change the value range of the original information to this range, so that each component does not exceed the range [0, 1], we can establish a one-way ing between mesh information and color.
If the color returned in the following three lines of code is the correct color, we only need to determine whether the col vector component has exceeded the [0, 1] range. Beyond this range, we can only see the black color:
Output. col = input. texcoord-float4 (1.5, 2.3, 1.1, 0.0); // The rgba intervals are [-1.5, 0.5], [-2.3,-1.3], [-1.1, -0.1], [], cannot be mapped to the color output. col = float4 (input. texcoord. z); // The rgba ranges from 0 to 1, [0, 1], [0, 1], and [0, 1], respectively, and can be mapped to the color output. col = input. texcoord/tan (0.0); // the denominator is 0, which is meaningless in mathematics. Because the value is infinite, the interval is [0, ∞].
Let's look at the complicated one. To determine whether the following output colors are correct, we need some knowledge of dot multiplication and cross multiplication:
output.col = dot(input.normal, float3(input.tangent)) *input.texcoord;output.col = dot(cross(input.normal, float3(input.tangent)),input.normal) * input.texcoord;output.col = float4(cross(input.normal, input.normal), 1.0);output.col = float4(cross(input.normal,float3(input.vertex)), 1.0);
Sorry, I have already returned all the dot multiplication and cross multiplication to my teacher. It seems that I have to go back to school to study again! I cannot solve it ~
The radian function radians () and noise () always return Black:
output.col = radians(input.texcoord);output.col = noise(input.texcoord);
Through this part of knowledge, we have mastered: 1. What are the input parameters of the vertex coloring machine? 2. How to display the input information in color format?
How to Learn shader
Learning Methods
(1) From Simplicity to complexity: Write the Shader by yourself, start from the simplest writing, pass the simple test, and add it to the Shader a little bit.
(2) Multi-Debug: for example, there is a float variable x. If the range of x is [], the color of float4 (x, 1) is output in the frag fragment function, and the value of x is observed in red; if the range of x is [], the float4 (x/, 0,) color can be output in the frag fragment function. The method is as simple as needed.
(3) view UnityCG. cginc and other files, and the built-in Shader of unity, that is, Build-in Shader.
Build-in Shader
(4) reading books: It is recommended that you read more books while reading this tutorial. Recommended English The CG Tutorial, that is, The Chinese version of The Cg Tutorial _ programmable real-time graphics authoritative guide
Links to related teaching materials
Tips
(1) view UnityCG. cginc and other files
When the CG of Vertex and Fragment is used, # include "UnityCG. cginc" is used to define many functions, such as TRANSFORM_TEX and UNITY_TRANSFER_DEPTH. How can we view these definitions?
Windows path: Unity \ Editor \ Data \ CGIncludes
Mac path: Right-click unity icon-> show contents-> Data-> CGIncludes
This folder contains the Unity Shader library, such as UnityCG. cginc, UnityCG. glslinc, and Lighting. cginc. Open
UnityCG. cginc (single Dev, etc.), and then you can view the definition of related functions.
(2) e-book learning skills
Chinese e-books are easy to learn and understand, but most of them are photocopies.
An English e-book can be used to search for knowledge points with keywords.
(3) Use # prama only_renderers d3d9 to limit the compilation platform. (3) (4) Better use results
(4) Open the compiled Shader and view the corresponding assembly code or OpenGL ES code.
Method: left-click the single-host shader file and click Open Compiled Shader in the Inspector panel.
A Brief Introduction to the ShaderLab For Unity3D syntax
It's also a newbie who just got in touch with Shader. It means it's a bit confusing to learn it at the beginning. Here are some of my own understandings and I don't know if it can help you.
1. the SV_POSITION here is called the output semantics. Semantics is a concept proposed in GPU programming. This definition may be long. I am afraid I cannot tell you clearly or mislead you, you can bind the input/output of cg to the semantics in Baidu's next article.
2. # pragma vertex vert is a preprocessing command that indicates the vertex program of a function named by vert, which is fixed, for details, refer to the vertex and fragment coloring tool section in the Unity holy code component reference manual.
3. cg programs are followed by CGPROGRAM, and mul functions are cg standard library functions.
P.s. It is recommended that you take a look at the cg language a little before shader, and there will be fewer steps around