Explanation of the Shader Series 9 Written by CG in Unity-mirror reflection and unityshader
After the discussion, the next step will be the mirror reflection.
Before starting the coding of the shader, you need to expand the previous knowledge to better understand the differences between the mirror reflection and the diffuse reflection.
Note: The mirror reflection implemented in this article is colored by vertex (per-vertex lighting), and The highlighted area is not smooth, for more smooth coloring methods, see Series 10-pixel-by-pixel coloring (per-pixcel lighting), also known as Feng's coloring.
Refer to some of the basic concepts in a previous blog post, especially about the Feng's reflection model:
Direal Al light (direlight Al light) is a type of object that is injected from a specific direction and only illuminating the face of the incident direction. It is called directional light ).
Ambient light is another light that comes from all directions and illuminates all objects. Whatever the orientation of these objects, we call it ambient light ). Of course, in the real world, this is just the scattering from parallel light to other objects, such as air and dust. But here, we need to list it as a single illumination model.
Diffuse)
Regardless of the incident angle, the light is reflected in all directions. The brightness of the reflected light is only related to the incident angle of the light, not to the observed angle. If the light is flattened on the surface of an object, the weaker the reflection light, the darker the surface. The more perpendicular the light is to the surface, the stronger the reflection light and the brighter the surface. Diffuse Reflection is the first thing we need to think of when an object is illuminated.
Specular)
Like a mirror, the reflected light is reflected at the same angle as the incident angle. In this case, the brightness of the light reflected by the object depends on whether the direction of your eyes and light reflection is in the same line. That is to say, the brightness of the reflected light depends not only on the incident angle of the light, but also on the angle between your sight and the surface of the object. Mirror reflection usually results in "blinking" and "high-gloss" on the surface of the object. The intensity of the mirror reflection is also related to the material of the object. However, there is very little mirror reflection in the glossy wood, the shiny metal has a lot of mirror reflection.
P.S.: we can see that apart from the virtual phenomena abstracted in computer graphics, the environment is actually present.
The Phong Rlection Model extends the four-step illumination system. First, all light has the following two attributes:
The RBG value of the diffuse light.
The RGB value of the reflected light.
Secondly, all materials have the following four attributes:
Reflected ambient light RGB values
RGB value of the reflected diffuse reflection light
RGB value of reflected mirror light
The reflection of an object determines the details of the mirror reflection.
We need to know two attributes for each Ray, and four attributes for each point on the surface of each object.
So when we discuss the mirror reflection, we need to understand that the rendering effect of the mirror reflection light is directly related to the observer's viewing angle. In Unity, environment light can be enabled in the menu Edit> Render Settings, while the Cg function in untiy has built-in environment light uniform parameter UNITY_LIGHTMODEL_AMBIENT.
In series 6 of the relationship between the mirror reflection and the viewing angle, I have explained that the smoothness of the material surface determines whether the mirror reflection is obvious or not. In real life, the surface of an object cannot be absolutely flat, therefore, we introduce a concept that the surface leveling degree of each material is Nshininess. The larger the n is, the more smooth the n is. The smaller the n is, the more rough the n is. In an ideal condition, the n is an absolute mirror reflection, that is to say, if you want to see the light source in the text referenced above, you must see it from the completely overlapping reflection angle of the light.
In combination, that is to say, the more smooth the surface of our materials, when the coefficient n approaches infinity, to see the light source, you must look at the direction of the ray R. When the surface of the material is more rough, we can see some light sources even near R. In the real world, the material is often like this, that is, when we observe this object near R, we can see the image of the light source. The size of the nearby range depends on the smoothness of the material. The mathematical relationship between the reflection vector R and the normal vector N and the incident vector L is as follows:
R = 2N (N · L)-L (ps: the relationship between N and L is a point multiplication)
In Unity, Cg has two built-in functions to calculate this relationship: float3 reflect (float3 I, float3 N) float4 reflect (float4 I, float4 N)
Where I is the incident Vector
I 've talked a lot of nonsense before. Here I can finally say what I want to say: the closer the observed vector V is to R, the more obvious the mirror reflection is. The closer the observed vector V is to R, the less obvious the mirror reflection, the reason is that there is no absolutely smooth material in the world. So we finally give the Feng's reflection model using mathematical formulas:
Among them, I specular is the intensity of the mirror reflection, And I incoming is the color vector of the incident light k specular is the color of the mirror reflection of the material, usually white
As for max (0, R · V), the same is true for the diffuse reflection in the series. When the angle between R and V exceeds 90 °, the cosine value is negative, the physical meaning is that the observer looks at the outer surface from the inner surface of the object, so we still take the maximum value from 0 and then we can see the n power. In this mathematical formula, the intensity of the mirror reflection is exponentially related to the angle between the reflection vector and the observation vector.
Write Shader
The environment light parameter has been provided in Cg, so we only need to multiply this parameter with the color vector of the light source to obtain the color vector of the Environment light:
float3 ambientLighting = float3(UNITY_LIGHTMODEL_AMBIENT) * float3(_Color);
The diffuse reflection light diffuseReflection has been calculated in the previous section.
Next we need to calculate V. Without V, our shader will not be able to change the mirror reflection effect from the perspective of the observer:
The calculation process of the unit vector of the observed vector is that the three-dimensional coordinates of MainCamer in the world coordinate system (the coordinates in the world coordinate system with the built-in uniform parameter _ WorldSpaceCameraPos) are subtracted from those in the world coordinate system of the vertex, and finally unitized. Step 1: Convert the vertex coordinates from the object coordinate system to the world coordinate system:
Float 4 vertexPos = mul (_ Object2World, input. vertex );
Step 2: Subtract two coordinate vectors (ps, _ Object2World is a 4x4 matrix, so the transformed vertex coordinates are 4 dimensions, and the mianCamera coordinates must be supplemented by one dimension, remove the meaningless dimension after the subtraction)
Float4 direction = float4 (_ WorldCameraPos, 1.0)-vertexPos;
Stpe3: subtract the meaningless four-dimensional, and the Unit is extended:
Float3 viewDirection = normalize (float3 (direction ));
Then there is the incident vector L and the normal vector N: // The _ WorldSpaceLightPos0 parameter passed by the parallel optical source is the direct direction, while the point light source is the position. We will go further to the point light source.
Float3 lightDirection = normalize (float3 (_ WorldSpaceLightPos0 ));
// Convert the normal vector to the object coordinate system to obtain N
Float3 normalDirection = normalize (float3 (mul (float4 (input. normal, 0.0), _ World2Object )));
Now we have calculated the observed vector V, the incident vector L, and the normal vector N. According to the above formula I = I * k * max (0, R · V) ^ n, R is calculated by the built-in function reflect (-L, N). We can calculate the mirror reflection intensity (exponent n _ Shininess, which is defined by the shader property, in order to adjust the gloss of different materials in the inspector, there is also a mirror reflected light color _ SpecColor ):
Float3 specularReflection = float3 (_ LightColor0) * float3 (_ SpecColor) * pow (max (0.0, dot (reflect (-lightDirection, normalDirection), viewDirection), _ Shininess );
With three color vectors: ambient light, diffuse reflection light, and mirror reflection light, add them based on the Feng's mirror reflection model to obtain the surface reflection color of an object that is close to the real one: // alpha or set to 1 opacity output. col = float4 (ambientLighting + diffuseReflection + specularReflection, 1.0 );
The final code is:
Shader "Custom/CustomSpecular" {Properties {_ Color ("Diffuse Material Color", Color) = (1, 1, 1) _ SpecColor ("Specular Material Color", Color) = (,) // The gloss degree of the material surface. According to the previous article, when this parameter is infinite, the material will not generate a mirror reflection _ Shininess ("Shininess", Float) = 10} SubShader {Pass {Tags {"LightMode" = "ForwardBase"} CGPROGRAM // defines the vertex shader and fragment iterator entry # pragma vertex vert # pragma fragment frag/get the material Color defined in property is uniform float4 _ Color; uniform float4 _ SpecColor; uniform float _ Shininess; // 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; // float4x4 modelMatrixInverse = _ World2Object transformation matrix from the world coordinate system to the object coordinate system; // The method vector N changes to the object coordinate system float3 normalDirection = normalize (float3 (mul (float4 (input. normal, 0.0), modelMatrixInverse); // The incident vector L of the parallel light source is directly given by uniform_WorldSpaceLightPos0 float3 lightDirection = normalize (float3 (_ WorldSpaceLightPos0 )); // The observation vector V is subtracted from the camera coordinate and the vertex coordinate vector float3 viewDirection = normalize (float3 (float4 (_ WorldSpaceCameraPos, 1.0)-mul (modelMatrix, input. vertex); // float3 specularReflection = float3 (_ LightColor0) * float3 (_ SpecColor) * pow (max (0.0, dot (reflect (-lightDirection, normalDirection), viewDirection), _ Shininess); // float3 diffuseReflection = float3 (_ LightColor0) * float3 (_ Color) * max (0.0, dot (normalDirection, lightDirection); // obtain the environmental light float3 ambientLighting = float3 (UNITY_LIGHTMODEL_AMBIENT) * float3 (_ Color ); // Add the above three RGB color vectors according to the Feng's reflection model, and then add A: output. col = float4 (ambientLighting + diffuseReflection + specularReflection, 1.0); // International Convention, three-step output of vertex change. 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} FallBack "Diffuse "}
Use the new shader to create another material ball, and then create another sphere to compare it with the previous two sphere. (In this example, the shader still has only one ForwardBase single-light source Shader, but I believe you should make this example a multi-light source)
It can be seen that our new shader will change according to the color of the observer's perspective surface.
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.
How to display glass and mirror materials in unity3D
Both transparent glass and mirror reflection materials require the combination of light and shade technology (Shader) and are special effects materials.
Transfer the shader to your car body and glass:
Shader "Reflective/Glass "{
Properties {
_ Color ("Main Color", Color) = (1, 1, 1)
_ SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
_ Shininess ("Shininess", Range (0.01, 1) = 0.078125
_ ReflectColor ("Reflect Strength", Color) = (0.5, 1)
_ MainTex ("Base (RGB) Gloss (A)", 2D) = "white "{}
_ Parallax ("Height", Range (0.005, 0.08) = 0.02
_ Cube ("Reflection Cubemap", Cube) = "_ Skybox" {TexGen CubeReflect}
}
SubShader
{
300
Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent "}
Blend one OneMinusDstColor
ZWrite Off
// First pass does reflection cubemap
Pass
{
Name "BASE"
Tags {"LightMode" = "Always "}
CGPROGRAM
# Pragma vertex vert
# Pragma fragment frag
# Pragma fragmentoption ARB_fog_exp2
# Pragma fragmentoption ARB_precision_hint_fastest
# Include "UnityCG. cginc"
Struct v2f {
V2F_POS_FOG;
Float2 uv: TEXCOORD0;
Float3 I: TEXCOORD1;
};
Uniform float4 _ MainTex_ST;
V2f vert (appdata_tan v)
{
... The remaining full text>