《Unity Shader 入门精要》Chapter 6 — Reading Note
Standard Lighting Model
Standard lighting model only cares about direct light, emitted from the light source, reflected by the object’s surface and then enters the camera.
These light can be considered into 4 part:
- Emissive: Irradiance emitted from a surface to a given direction.
- Specular: Irradiance of the completely specular reflection of a surface.
- Diffuse: Irradiance of diffusion of a surface.
- Ambient: All other indirect light.
Ambient
In standard lighting model, we use a global variable to simulate all indirect light.
cambient = gambient
Emissive
In standard light model, we directly use the emissive color of the material.
cemissive = memissive
Diffuse
The direction of the diffuse light is random, meaning the reflection light’s direction is not important. However, the direction of the incident light matters.
Lambert’s Law: The intensity of the reflection light is proportional to the cosine value of the degree between the surface normal and the source light.
cdiffuse = (clight · mdiffuse) · max(0, n · l);
- clight: Color of the source light.
- mdiffuse: Color of the diffuse of the material.
- n: Surface normal.
- l: Direction of the source light.
Specular
Here specular is an experienced model, which not totally suit the real world.
We need to know 4 information: surface normal, view direction, source light, reflection direction. However we can calculate one using the other three.
r = 2(n · l) · n - l
Phone Model
cspecular = (clight * mspecular) · max(0, v · r)mgloss
- mgloss: gloss of the material(shininess). The greater it is, the smaller of the light point.
- mspecular: Color of the specular of the material.
Blinn Model
A faster model if the distance between camera and light source is enough long.
We introduce a new variable h to help calculation.
h = (v + l) / |v + l|
cspecular = (clight · mspecular) · max(0, n · h)mgloss
Per-pixel Lighting VS Per-vertex Lighting
These are two ways to calculate lighting model.
Per-pixel Lighting (In fragment shader)
Based on each fragment(pixel), retrieve its normal(by interpolation of vertex normal or sample from normal texture), then start the calculation of the lighting model. This is called Phone Shading.
Per-vertex Lighting (In vertex shader)
Based on each vertex, calculate the lighting, then use linear interpolation to render the pixel’s color. This is called Gouraud Shading.
Comparison
Per-vertex lighting is faster than per-pixel lighting because the number of vertexs is much less than the number of pixels. However, because per-vertex lighting relies on linear interpolation, it will make troubles when there exists non-linear calculation (like specular reflection) in the lighting model.
For a high-detailed model, per-vertex lighting is good. But for a low-detailed mode, per-vertex lighting will cause some visual problems. For example, there exists some sawtooth between the frontlight surface and the backlight surface.
Half-Lambert Lighting Model
Even if we are using per-pixel lighting, there exists a problem. In the region that lights cannot reach, usually the appearance of the model is totally dark, without any change in brightness. This makes the backlight region look like a surface, then loses the detials of the model. That’s why we use Half-Lambert Lighting Model.
cdiffuse = (clight · mdiffuse) · (a · (n · l) + b)
- a: Scale, usually set to 0.5
- b: Offset, usually set to 0.5
This model maps the result of n · l from [-1, 1] to [0, 1], which gives the backlight side the change of brightness. It can be seen as a visual enhanced technology.
Code
Here we only show the code of Blinn-Phong Lighting Model.
1 | Shader "Unity Shaders Book/Chapter 6/Blinn-Phong"{ |