But we will find that the back surface of the object is an all-black color, the real life of the object's back surface is not all black, but can see the approximate shape of the object, not all black, before the use of the method is Lambert lighting model. To achieve this, it is necessary to use the semi-Lambert illumination model to achieve
semi-Lambert illumination model
Diffuse = Direct light color * (cosθ*0.5+0.5)
Lambert Lighting Model
Diffuse = Direct light color * MAX (0,cosθ) θ refers to the angle between the light direction and the normal direction
Semi-Lambert light effect as shown:
High Light reflection calculation (Blinn illumination model) specular = Direct light *pow (max (cosθ,0), highlight parameter)
Explanations for the above formula:
Θ refers to the angle between the reflected light direction and the reflection point to the camera direction.
The second side of the POW means cosθ 's high-light parameters.
Max (cosθ,0) is to prevent the surface of the object, if the highlight parameter is even, then the last value will be changed from negative to positive
The sample code used is as follows
properties{_diffuse ("Diffuse color", color) = (1,1,1,1) _gloss ("Gloss", Range (8,200)) = ten} Su
bshader{pass{tags{"Lightmode" = "forwardbase"} Cgprogram #include "lighting.cginc"//unity system-defined classes can use some built-in variables to simplify calculation operations//_lightcolor0 The variable represents the color of the first direct light//_WORLDSPACELIGHTPOS0 the variable represents the position of the First direct light (world coordinates)//UNITY_LIGHTMODEL_AMB Ient this variable represents the ambient light of the system #pragma vertex vert #pragma fragment Frag fixed4 _diff
Use
Half _gloss; struct A2V {float4 vertex:position;//The system automatically passes vertex coordinates to vertex float3 normal:normal;
The system automatically passes the normals into the variable normal};
struct V2F {float4 position:sv_position;
Fixed3 Color:color;
}; v2f Vert (a2vx) {v2f F;
UNITY_MATRIX_MVP This matrix is used to convert a coordinate from model space to clipping space f.position = Mul (UNITY_MATRIX_MVP, X.vertex);
Fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);
Fixed3 ambient = Unity_lightmodel_ambient.rgb;
Fixed3 Normaldir = Normalize (Mul (X.normal, (float3x3) unity_worldtoobject)); For the time being, the alpha attribute is not considered fixed3 diffuse = _lightcolor0.rgb*max (dot (Lightdir, Normaldir), 0) *_diffuse.rgb;//get diffuse The color of the shot//Calculate high light//Calculate reflection light angle fixed3 Reflectdir = Normalize (refle
CT (-lightdir,normaldir));
Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). xyz);
Fixed3 specular = _lightcolor0.rgb*pow (max (dot (Reflectdir, Viewdir), 0), _gloss);
F.color = Diffuse +ambient+ specular;return F; } fixed4 Frag (v2f f): sv_target{//output computed color values to objects in the field of view return fix
Ed4 (F.color, 1); } ENDCG}}
The code has a reflect method, which is used to calculate the angle between the reflected light and the normal of the incident light.
The first parameter in the function reflect is the incident light vector, the second one is the normal vector, and the angle between the reflected light vector and normal is calculated by the angle between the incident light vector and the normal, so the incoming light needs to be flipped, otherwise the incident light and the normal angle is (180-( The angle of the incident light vector and the normal vector) °. the angle of the vertex to the field of view is then obtained by the variable defined by the macro. Finally, just use the formula to calculate.
High-gloss effect as shown:
The area range of the highlight is determined by the specular reflectance factor, which defines a parameter for controlling the highlight range
_gloss ("Gloss", Range (8,200)) = 10
and used in the formula, and finally can be free to control the size of the high-light range.
blinn-phone Illumination Model : Improvement of Blinn illumination model
Calculation formula modified to: specular = Direct light *pow (max (cosθ,0), highlight parameter)
Θ here refers to the angle between the normal and x x is the direction of the light and the angle of the camera's viewing direction (middle line)
As shown in figure
So in the end as long as the vert inside the code to make the following changes.
v2f Vert (a2v x) {v2f F;
UNITY_MATRIX_MVP This matrix is used to convert a coordinate from model space to clipping space f.position = Mul (UNITY_MATRIX_MVP, X.vertex);
Fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);
Fixed3 ambient = Unity_lightmodel_ambient.rgb;
Fixed3 Normaldir = Normalize (Mul (X.normal, (float3x3) unity_worldtoobject)); For the time being, the alpha attribute is not considered fixed3 diffuse = _lightcolor0.rgb*max (dot (Lightdir, Normaldir), 0) *_diffuse.rgb;//get diffuse The color of the shot//Calculate high light//calculate the angle of reflection light//fixed3 Reflectdir = normalize (ref
Lect (-lightdir,normaldir));
Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). xyz);
Split Line Fixed3 Halfdir = normalize (Viewdir + lightdir); Control the highlight color fixed3 specular = _specUlar * _LIGHTCOLOR0.RGB*POW (max (dot (Normaldir, Halfdir), 0), _gloss);
F.color = Diffuse +ambient+ specular;
return F; } fixed4 Frag (v2f f): sv_target{//output computed color values to objects in the field of view return fix
Ed4 (F.color, 1); } ENDCG}
This b-p model is optimized compared to the previous Blinn illumination model, where we will see a highlight point on the back surface, but not in b-p
Some common functions and macro definition variables in Unitycg.cginc
_lightcolor0 the variable represents the color of the first direct light
_worldspacelightpos0 The variable represents the position of the First direct light (world coordinates)
Unity_lightmodel_ AMBIENT the variable represents the system's ambient light
_world2object This matrix is used to convert a direction from world space to model space
unity_lightmodel_ambient to obtain ambient light
// Camera orientation (angle of view)
float3 Worldspaceviewdir (float4 v) gets (World space) from this point to the camera's viewing direction based on the vertex coordinates in the model space
FLOAT3 Unityworldspaceviewdir (float4 v) vertex coordinates in world space = = "World space from this point to the camera's viewing direction
float3 Objspaceviewdir (float4 v) Vertex coordinates in model space = = "model space from this point to the camera's viewing direction
//light source Direction
Float3 Worldspacelightdir (float4 v) the vertex coordinates in the model space = =" In world space from this point to the direction of the light source
float3 Unityworldspacelightdir (float4 v) vertex coordinates in world space = = "From this point to the direction of the light source in world space
FLOAT3 Objspacelightdir (Float4 v) the vertex coordinates in model space = = "In model space from this point to the direction
//direction of the light source
float3 Unityobjecttoworldnormal ( FLOAT3 norm) The normal direction model space = = "World Space
float3 Unityobjecttoworlddir (float3 dir) to the direction model space =" World Space
FLOAT3 Unityworldtoobjectdir (FLOAT3 dir) take the direction world space = "model space"
Use the built-in function method to make the code easier to write
The code in the program needs to be
Fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);
Replaced by
Fixed3 Lightdir = Normalize (Worldspacelightdir (Mul (X.vertex, Unity_worldtoobject)). xyz);
Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). xyz);
Replaced by
Fixed3 Viewdir = Normalize (Unityworldspaceviewdir (Mul (X.vertex, (float3x3) unity_worldtoobject). xyz));
The calculation of normals is replaced directly by the
Direct use of a method to convert from model space to world space
Fixed3 Normaldir = Normalize (Unityobjecttoworldnormal (x.normal));
Replace the modified code as follows
v2f Vert (a2v x) {v2f F;
UNITY_MATRIX_MVP This matrix is used to convert a coordinate from model space to clipping space f.position = Mul (UNITY_MATRIX_MVP, X.vertex);
A point of light source//fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);
Fixed3 Lightdir = Normalize (Worldspacelightdir (Mul (X.vertex, Unity_worldtoobject)). xyz);
Fixed3 ambient = Unity_lightmodel_ambient.rgb;
The direct use method transforms from model space to world space fixed3 Normaldir = normalize (Unityobjecttoworldnormal (x.normal)); For the time being, the alpha attribute is not considered fixed3 diffuse = _lightcolor0.rgb*max (dot (Lightdir, Normaldir), 0) *_diffuse.rgb; Get diffuse color//Calculate high light//calculate reflected light angle//fixed3 Reflectdir = Normali
Ze (Reflect (-lightdir,normaldir)); Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). XYZ);
Fixed3 Viewdir = Normalize (Unityworldspaceviewdir (Mul (X.vertex, (float3x3) unity_worldtoobject). xyz));
Split Line Fixed3 Halfdir = normalize (Viewdir + lightdir);
Control the highlight color fixed3 specular = _specular * _LIGHTCOLOR0.RGB*POW (max (dot (Normaldir, Halfdir), 0), _gloss);
F.color = Diffuse +ambient+ specular;
return F; }