跳转至

3 Shading

文本统计:约 915 个字 • 11 行代码

Definition: the process of applying a material to an object

3.1 Blinn-Phong Reflectance Model

我们主要来处理高光部分,漫反射部分以及环境光像。

Shading is local【着色的局部性】: we do not need to care about other objects, so no shadows will be generated.

(\(n\) and \(I\) are both Unit Vector)

3.1.1 Diffuse Term

Diffuse Reflection: Light is scattered uniformly in all directions. 漫反射的结果就是光被均匀地反射到各个方向

Lambert’s cosine law: calculate how much light is received by the surface. 以不同的角度接受光,吸收得到的光强也不同

Light Falloff : Suppose the light intensity at distance 1 is \(I\), then at distance \(r\) the light intensity is \(I/r^2\).

Lambertian (Diffuse) Shading :

\[ L_d = k_d(I/r^2)\max(0,n\cdot I) \]

与 0 取max的原因是当 \(n\cdot I\) 为负数时,也就是光从下面打上来,这个时没有意义的,这时候就取0,意为没有光照到。

\(k_d\) means diffuse coefficient.

Note

引入 \(k_d\) 的原因是材料可能有对光的吸收,同时我们可以将光定义为一个RGB表示的三维向量,这样我们可以通过 \(k_d\) 来表示物体的颜色了

因为我们考虑的是漫反射,光在四周是均匀的,所以与我们观察的方向无关。

3.1.2 Specular Term

It means bright near reflection direction. 在这种情况下,光强就与观察角度有关了

\(\bf v\) close to mirror direction \(\Leftrightarrow\) half vector near normal

\[ \pmb{h} = \text{bisector}(\pmb v, \pmb l) = \frac{\pmb v +\pmb l}{\|\pmb v +\pmb l \|} \]

这样我们得到 Specular term 的光强的值

\[ \begin{aligned} L_s &= k_s(I/r^2)\max(0,\cos \alpha)^p \\ &= k_s(I/r^2)\max(0,\pmb {n}\cdot \pmb {h}) ^p \end{aligned} \]

\(k_s\) means specular coefficient.

Why we need to \(()^p\)?

Increasing p narrows the refelction lobe. 增加p让我仅在很小的部分才能看到高光

Usually p is above 100.

\(k_s\) 越大,物体亮度越高。 \(p\) 越大,高光的区域越小

3.1.3 Ambient Term

我们假设来自任何方向的光都是相同的,阴影不依赖于任何东西。

\[ L_a = k_a I_a \]

\(k_a\) means ambient coefficient. \(I_a\) 是来自环境的光。

Summary

\[ \begin{aligned} L&=L_a+L_d+L_s\\ &=k_aI_a+k_d(I/r^2)max(0,\bold n\cdot \bold l)+k_s(I/r^2)max(0,\bold n\cdot\bold h)^p \end{aligned} \]

3.2 Shading Frequencies

Three Methods of Shading

我们有三种不同的 shading 思路

Shade each triangle——Flat shading

三角形面是平的只有一个法向量,对于一些光滑平面来说效果不佳。

Shade each vertex——Gouraud shading

对每个顶点进行shading,然后根据顶点的颜色对三角形进行插值,每一个点都有一个法向量(如何定义?)

Shade each pixel——Phong shading

对法向量进行插值,然后对每个像素进行 shading

从上面我们可以看出,当面比较少的时候,我们发现 Flat shading 比 Phong Shading 要差很多,但是在面较多的时候,会发现其实差距不大。

How to define per-vertex Normal vectors?

One way (BEST) is to get vertex normals from the underlying geometry, like consider a sphere 直接根据原本的几何形体得到法向量,这肯定是最准的。

Otherwise have to infer vertex normals from triangle faces, we can average (or weighted) surrounding face normals 根据相邻法线的加权平均,得到点的平均。

\[ N_v=\frac{\sum_i N_i}{\|\sum_i N_i\|} \]

How to define per-pixel normal vectors?

Barycentric interpolation of vertex normals.

3.3 Graphics(Real-time Rendering) Pipeline

Graphics Pipeline

我们一开始定义模型的时候,可以先定义点,然后定义相应的连接关系。我们将三维空间中的点映射到二维空间上,然后再连线。

Shader programs

对 vertex and fragment processing 阶段进行编程,我们只需要描述对某一个点/像素的操作

Example GLSL fragment shader program

uniform sampler2D myTexture; // program parameter
uniform vec3 lightDir; // program parameter 
varying vec2 uv; // per fragment value (interp. by rasterizer) 
varying vec3 norm; // per fragment value (interp. by rasterizer)
void diffuseShader() 
{ 
    vec3 kd; 
    kd = texture2d(myTexture, uv); // material color from texture
    kd *= clamp(dot(lightDir, norm), 0.0, 1.0); // Lambertian shading model
    gl_FragColor = vec4(kd, 1.0); // output fragment color
}

评论区

对你有帮助的话请给我个赞和 star => GitHub stars
欢迎跟我探讨!!!