Interpretation of the Shader Series 7 written by CG in Unity -- diffuse reflection and unityshader
If the content of the previous series of articles is too long and interesting, I am sorry. Due to the time, the mixed content has not been completed yet. I will try again later. Now I am beginning to discuss reflection content.
Refraction and reflection
In the physical world, the reflection and refraction of light often exist at the same time. The light source is injected into a material in a vacuum or air, and the light enters this material while it is refraction, the degree of refraction is related to the refractive index of each media, so that the optical transmission line deviates from the original line;
Then, if the light passes through the surface of different transmission media, it will bounce back like a table tennis ball. Our human eyes can see things because things reflect the light source. If a substance cannot reflect light, or we can't see anything without a light source. For different materials, the higher the passing property of light, the less obvious the reflection, such as glass (but glass also has a certain amount of reflection, otherwise we will not see the glass, in fact, we can see); the lower the light passing rate, the more obvious the reflection. For example, on the water surface, we can see the fish in the water (from the water to the skin of the fish, the fish's skin has a diffuse reflection), you can also see your reflection (the water surface has a mirror reflection ).
The difference between the mirror reflection and the diffuse reflection is that, when the surface of an object is bounce back, the smoother the plane is, the closer the plane is to the mirror reflection, and the rougher it is, the more diffuse reflection. The vast majority of things we see in real life are superficial, so they are diffuse reflection.
Before discussing the diffuse reflection, you must go back and review the mirror reflection and refraction in our physical science, because the diffuse reflection can be split into countless tiny mirror reflections (just like a circle can be seen as a regular polygon with numerous sides), after all, the game world is also designed to simulate the physical world, the game engine must comply with physical rules. Draw a picture to recall:
The picture above is not very good. The angle between the incident light and the normal plane is the incident angle, the angle between the reflected light and the normal plane is the reflection angle, and the incident angle is always equal to the reflection angle.
Similarly, for uneven media intersections, we can be infinitely subdivided into countless legal planes, for the reflection of each surface point, we can create a plane along the current point and tangent to the surface of the object at this point to obtain a normal plane. Therefore, the law of mirror reflection can be applied directly to diffuse reflection. Let's see:
When we analyze the reflection of a certain point on the surface of Medium B, we will make a plane at this point and the surface is tangent to this point, the normal plane, normal, angle of incidence, and angle of reflection at this position are also obtained.
Now let's review it here. In the previous series, we have removed the normal and normal planes. We will see Medium B for our 3D object, so the black curve part is its surface, the normal orientation of each point on the surface is different, because the cut of each point is not necessarily parallel to the plane on the surface, therefore, each vertex transmitted in the mesh information in CG has a normal value, that is, the normal vector.
The normal vector is the unit vector of the tangent point in our normal to the direction of Medium.
The reflection process is good. Next we will replace the incident light and normal as the incident vector L (the direction from the surface to the light source is positive) and the normal vector N. In this case, the amount of diffuse reflection is determined by the incident vector I and the normal vector N at each vertex position: diffuse = L · N this process is a point multiplication between vector I and N. The process is diffuse = | L | * | N | * cos variance (L, N)
Because we directly discuss the incident vector and the unit vector of the normal vector, so the two absolute values are 1, then the diffuse reflection duuse = cos attention (L, N)
From this, we can obtain the diffuse reflection intensity diffuse value of the incident light of the unit vector: [-] From the cosine curve, diffuse is 0 ~ At the angle ~ 90 ° is positive, 90 ° ~ 270 ° is negative, 270 ~ 360 ° positive
For cos degrees (L, N) over 90 °, we think that the incident light is already on the other side of the media surface. In this case, we do not consider that generally, the diffuse reflection is performed on the outer surface.
Therefore, when the angle of diffuse is greater than 90 °, the reflection volume is considered to be 0, so we modify this formula:
Diffuse = max (0, cos variance (L, N ))
That is, the cosine of the angle between the incident vector and the normal vector is set to the maximum value of 0, which ensures that there is no negative number in the reflection volume.
Next, let's go back to the CG world from the physical and mathematical worlds.
Write a diffuse Shader Using CG. before writing our first single-source diffuse shader, first describe the source of the parameters we need: 1. the position of the light source is given by the built-in uniform parameter _ WorldSpaceLightPos0 of unity. Therefore, we can calculate the incident vector of each vertex. 2. the color of the light source is provided by the uniform parameter _ LightColor0 3. the NORMAL semantics in the input parameters of the vertex coloring machine is used to obtain the color of the incident vector, NORMAL vector, and light source, we can calculate the amount of reflection at each vertex position in the vertex coloring tool, and multiply it with the color of the light source and the color of the material to obtain the actual color of the final surface coloring. User-Defined parameters: 1. Material color, defined by shader's property
Shader "Custom/CustomDiffuse" {Properties {// The default Material Color is black. You can adjust _ Color ("Material Color", Color) = (,)} In inspector )} subShader {// LightMode we will continue to discuss Tags {"LightMode" = "ForwardBase"} Pass {CGPROGRAM // Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it does not contain a surface program or both vertex and fragment programs. // # pragma exclude_renderers gles // defines the vertex shader and fragment shader entry # pragma vertex vert # pragma fragment frag // gets the Material Color uniform float4 _ Color defined in property; // position or direction of the light source // uniform float4 _ WorldSpaceLightPos0; // The color of the light source (from "Lighting. cginc ") uniform float4 _ LightColor0; // defines the input parameter struct of the vertex shader. // We only need the POSITION of each vertex and the corresponding normal vector struct vertexInput {float4 vertex: POSITION; float3 normal: NORMAL;}; // defines the output struct of vertex coloring/the input struct of fragment coloring // The calculated color struct vertexOutput {float4 pos: SV_POSITION; float4 col: COLOR ;}; // vertexOutput vert (vertexInput input) {vertexOutput output; // transformation matrix from the object coordinate system to the world coordinate system // _ Object2World and _ World2Object are built-in uniform parameter float4x4 modelMatrix = _ Object2World provided by unity; // The transformation matrix float4x4 modelMatrixInverse = _ World2Object from the world coordinate system to the object coordinate system; // calculate the unit vector of the vertex normal vector in the object coordinate system // multiply the vertex normal vector transmitted from the mesh with the model --> the object coordinate system matrix to obtain the normal vector in the object coordinate system // then unitization float3 normalDirection = normalize (float3 (mul (float4 (input. normal, 0.0), modelMatrixInverse); // calculates the unit vector float3 lightDirection = normalize (float3 (_ WorldSpaceLightPos0) of the incident vector )); // calculate the color after reflection. // first multiply the color of the light source and the color vector of the material. // then multiply the max (0, cos cosine (N, L) mentioned above )) float3 diffuseReflection = float3 (_ LightColor0) * float3 (_ Color) * max (0.0, dot (normalDirection, lightDirection); // The above calculated is an RGB Color with A difference, after adding one dimension, you can pass it to the clip coloring tool output. col = float4 (diffuseReflection, 1.0); // International Convention, three-step curve of vertex change. In this example, output can be written or not. pos = mul (UNITY_MATRIX_MVP, input. vertex); return output;} // fragment shader, which uses the output parameter of the vertex shader as the input parameter float4 frag (vertexOutput input) of the fragment shader ): COLOR {return input. col;} ENDCG }}}
Now we create a material, select the shader we created, select a color in inspector, and then assign a unique light source in the scenario to give the material to an object.
I gave this material to the hood of the Audi A6L. the light source is on the front and you can see it intuitively. The shader used in the hood is the diffuse reflection shader we just compiled, the remaining parts of the body are mirror reflection shader:
What SHADER is used for ao pasters in unity3d?
If you have done a good job of AO, you can use diffuse to check the effect.
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