This series mainly references the book "Unity shaders and effects cookbook" (thanks to the author of the original book) and adds a bit of personal understanding or expansion.
Here are all the illustrations in this book. Here is the code and resources required for this book (you can also download them from the official website ).
========================================================== ===================================================== =====
Preface
La la ~ I came back to read books. The article begins to talk about other things. Because I write blogs and are more active in the group (why QQ gave me the title of "spam "... I am so cool ...), Recently, some friends have sent me emails or private messages. Many people have encouraged me. I am very happy and some people have given me good learning suggestions, these experiences make me feel that it is the right way to stick to blogging ~ Thank you for your encouragement, support, and attention! I will stick to it.
Okay, let's get down to the truth ~ At the beginning of this article, I decided to start a new chapter, vertex magic. As the name suggests, it is the content related to learning vertices. Since reading a figure in Unity gems below, I have a better understanding of the entire surface shader workflow. I will repeat it here.
We can see that there are four stages that we can participate in. Most of our previous studies were in the second and third stages, namely writing the surf and lightingxxx functions to influence the surface coloring and illumination functions. In the cartoon style shader, we also made a preliminary attempt on the finalcolor command, the last chance to change the pixel color. Now, we will use a chapter to learn how to use the first stage-vertex function to influence the pixel color.
Vertex functions are called once before each vertex is transferred to the GPU. It is used to obtain three-dimensional coordinates from the model coordinate system, and then convert them to the two-dimensional position in the screen coordinate system when rendering them to the screen. Therefore, through the vertex function, we can modify the vertex position, color, and UV coordinates. Once the vertex is modified, the surf function is executed. Unlike vertex functions, the surf function is executed pixel by pixel.
Through the vertex function, we can create dynamic effects like waves at sea, banners floating, or use shader to color the vertex. In this article, we will learn how to create the simplest vertex function in a surface Shader!
Preparations
Before learning about vertex functions, you must first understand how to obtain and store vertex-related information through vertex functions.
- First, we need to prepare a model that has colored the vertex so that we can view the vertex color in the vertex function. For convenience, we use the model resource vertexcolorobject. fbx in chapter 7 of the book's built-in resources (see the beginning of the article. We import vertexcolorobject. fbx into unity and drag it into a new scenario. Add a parallel light.
- Create a new shader and material, which can be named simplevertexcolor respectively, and assign the shader to material, and then assign the material to the model.
Your scenario should look like this:
Implementation
Next, let's start writing shader.
- Add the new properties in the properties block:
Properties {_MainTint("Global Color Tint", Color) = (1,1,1,1)}
- Next, tell unity that we will use our vertex functions:
CGPROGRAM#pragma surface surf Lambert vertex:vert
- Add a reference for the newly added property in properties:
float4 _MainTint;
- The following is an important input structure. We added a new variable vertcolor so that the surf function can access the data transmitted in the vert function:
struct Input {float2 uv_MainTex;float4 vertColor;};
- Below is a very simple vert function. We access the vertex color of the model and store it in the input structure:
void vert(inout appdata_full v, out Input o){o.vertColor = v.color;}
- Finally, we use the data obtained from the input to fill the albedo parameter of the surfaceoutput struct:
void surf (Input IN, inout SurfaceOutput o) {o.Albedo = IN.vertColor.rgb * _MainTint.rgb;}
The complete code is as follows:
Shader "Custom/SimpleVertexColor" {Properties {_MainTint("Global Color Tint", Color) = (1,1,1,1)}SubShader {Tags { "RenderType"="Opaque" }LOD 200CGPROGRAM#pragma surface surf Lambert vertex:vertfloat4 _MainTint;struct Input {float2 uv_MainTex;float4 vertColor;};void vert(inout appdata_full v, out Input o){o.vertColor = v.color;}void surf (Input IN, inout SurfaceOutput o) {o.Albedo = IN.vertColor.rgb * _MainTint.rgb;}ENDCG} FallBack "Diffuse"}
The effect is as follows:
Explanation
Through the vertex function, we can modify the vertex location, color, UV coordinate equivalent. In this section, we use a model that has colored vertices imported from Maya, but we can find that these colors are not displayed in unity when the default material is used. We need to write a shader to extract these colors and then display them on the model.
We first add the vertex: vert statement in the # pragma declaration. This actually tells unity, hey, don't use your own built-in vertex function to access the model vertex information. Go to the shader I wrote and find a guy named vert to use it to process the information! If unity cannot be found, a compilation error is reported.
In the vert function, apart from the input struct we are familiar with, there is also a very special parameter-appdata_full. This parameter is also a built-in variable of unity. It contains all information about the model vertex, including position, tangent, normal, two texture coordinates, and color information. Others include appdata_base and appdata_tan. For details, see the official website.
You can also find that vertcolor is a float4 variable, which means we can also access its transparent channel. As shown below:
void surf (Input IN, inout SurfaceOutput o) {o.Albedo = IN.vertColor.rgb * _MainTint.rgb;o.Alpha = IN.vertColor.a;}