暗黑模式
光照(Lighting)
教程3DWebGL
光(Lights)、法线(Normals)、材质(Materials)
位置(Positional)和方向(Directional)光
位置光也称为点光(Point Lights)
法线(Normals)
法线是垂直于面(Surface)的向量(Vector),法线表示表面的方向,因此对于建模光源和物体之间的相互作用至关重要。
通过交叉乘积(Cross-Product)来计算法线:
P0, P1, P1
:三角形的 3 个顶点;- V1 = P1 - P0
- V2 = P2 - P0
- N = V1 × V2
多个三角形共享的顶点,如何计算法线?
材质(Materials)
材质包含:
- 物体的颜色(Color)
- 决定了光照射到物体上后的反射光颜色
- 物体的纹理(Texture)
- 物体所映射到的纹理图片,类似于皮肤
光、法线、材质→渲染管道
并行处理,Attributes Uniforms
Uniforms 类似于 global 变量,在一个Pipe内是不变的(每一次drawArray/drawElements)(光、材质) Attributes 类似于 local 变量,每个顶点对应不同的 attributes(顶点坐标、顶点法向量)
GPU 硬件决定了并行的线程数
着色方法(Shading Methods)和光发射模型(Light-Reflection Modes)
Shading refers to the type of interpolation that is performed to obtain the final color for every fragment in the scene.
Once the shading model is established, the lighting model determines how the normals, materials, and lights need to be combined to produce the final color.
Shading/Interpolation Methods
Gouraud Interpolation
The Gouraud interpolation method calculates the final color in the vertex shader.
Then, using a varying variable, the final color for the vertex is passed to the fragment shader.
Due to the automatic interpolation of varyings provided by the rendering pipeline, each fragment will have a color that is the result of interpolating the colors of the enclosing triangle for each fragment.
TIP
Varying Interpolation The interpolation of varyings is automatic in the rendering pipeline. No programming is required.
Phong Interpolation
The Phong method calculates the final color in the fragment shader. To do so, each vertex normal is passed from the vertex shader to the fragment shader using a varying. Because of the interpolation mechanism of varyings included in the pipeline, each fragment will have its own normal. Fragment normals are then used to calculate the final color in the fragment shader.
VS
Gouraud阴影被认为更快,因为执行的计算是按顶点计算的,而Phong阴影是按片段计算的。性能上的速度确实是以精确或更现实的插值为代价的。这在光的强度在两个顶点之间不线性下降的情况下是最明显的。在本章的后面,我们将更详细地介绍这两种技术。
TIP
着色方法不指定如何计算每个片段的最终颜色。它只指定要使用的位置(顶点或片段着色器) 和 插值类型(顶点颜色或顶点法线)。
Light-Reflection Models
着色模型决定了在哪里(VS,FS)计算最终颜色,而光反射模型决定具体如何计算。
The Lambertian Reflection Model
Lambertian reflections are diffuse reflections漫反射. 入射能量在所有方向均匀反射,即入射能量以入射点为中心,在整个半球空间内向四周各向同性地反射能量的现象,称为漫反射,也称各向同性反射
漫反射:无论观察者在哪个方向,反射结果都是一样的,也就是与观察者的位置无关; 镜面反射:观察者正处在反射光时,光最亮;如果与反射光反方向,则没有光照值。
计算公式:
我们假设
Phong Reflection Model
冯氏光反射模型
Ambient(环境光)
Diffuse(漫反射)
使用 郎伯模型
Specular(镜面高光)
计算公式:
我们假设
OpenGL ES Shading Language (ESSL)
TIP
GLSL 是 OpenGL 的着色器语言,ESSL 是 OpenGL ES 的着色器语言。
ESSL 是 GLSL 的子集。
因为 WebGL2 基于 OpenGL ES 3.0,所以着色器使用的是 ESSL,而不是 GLSL。
Storage Qualifier(存储限定符)
存储限定符 | 含义 | 示例 |
---|---|---|
attribute | 仅在 Vettex Shader 中有效。 连接 WebGL 和 Vertex Shader,从 VBO 中拉取 per-vertex 数据 | |
uniform | 连接 WebGL 和 Shaders,通过 WebGL API 设置值,在图形对象渲染过程中保持不变 | |
varing | 连接 VertexShader 和 Fragment Shader,Vertex Shader 输出值给到 Fragment Shader | |
const | Shader 编译时常量,或只读的函数参数 |
数据类型
常用数据类型:
类型 | 含义 | 示例 |
---|---|---|
void | For functions that do not return a value or for an empty parameter list | |
bool | A conditional type, taking on values of true or false | |
int | A signed integer | |
float | A single floating-point scalar | |
vec2 | A two-component floating-point vector | |
vec3 | A three-component floating-point vector | |
vec4 | A four-component floating-point vector | |
bvec2 | A two-component Boolean vector | |
bvec3 | A three-component Boolean vector | |
bvec4 | A four-component Boolean vector | |
ivec2 | A two-component integer vector | |
ivec3 | A three-component integer vector | |
ivec4 | A four-component integer vector | |
mat2 | A 2×2 floating-point matrix | |
mat3 | A 3×3 floating-point matrix | |
mat4 | A 4×4 floating-point matrix | |
sampler2D | A handle for accessing a 2D texture | |
sampler3D | A handle for accessing a 3D texture | |
samplerCube | A handle for accessing a cube-mapped texture | |
struct | Used to declare custom data structures based on standard types |
glsl
uniform vec4 uLightColor;
1
The GLSL and ESSL Naming Convention
Convention dictates that we prefix shader variables with their type. This makes for clear and readable shader code. For example, for a given color uniform, you would name the variable uLightColor
. For a position varying, vNormal
. For a normal attribute, aVertexNormal
.
向量分量
分量 | 使用场景 | 示例 |
---|---|---|
[1-4] | 通用场景 | uLightColor[0] = 1.0; |
{ x, y, z, w } | Useful when accessing vectors that represent points or vectors. | aVertexPosition.x = 1.0; |
{ r, g, b, a } | Useful when accessing vectors that represent colors. | uLightColor.r = 1.0; |
{ s, t, p, q } | Useful when accessing vectors that represent texture coordinates. | vSamplerCoord.s = 1.0; |
glsl
vec4 v4;
1
分量子集 | 含义 |
---|---|
v4.rgba | is a vec4 and the same as just using v4 |
v4.rgb | is a vec3 |
v4.b | is a float |
v4.xy | is a vec2 |
is illegal - the component names do not come from the same set |