玩转WebGL(六)漫反射光照

现实世界的光照是极其复杂的,因此WebGL的光照仅仅使用了简化的模型并基于对现实的估计来进行模拟,光照模型都是基于我们对光的物理特性的理解。

颜色

根据物理知识,不透明物体的颜色是根据其反射的色光决定的。比如树叶反射绿光,就显示绿色。如果物体反射所有的色光,就显示白色。所以光源色和物体颜色的反射运算:

vec3 lightColor = vec3(0.3, 0.4, 0.5);
vec3 thingColor = vec3(0.5, 0.4, 0.5);
vec3 resultColor = lightColor * thingColor; // = (0.15, 0.16, 0.25)

光照

环境光照

环境反射光的颜色定义公式为:

反射光的颜色 = 入射光的颜色 x 物理的颜色
玩转WebGL(六)漫反射光照

漫反射光照(Diffuse Lighting)

测量这个光线与它所接触片段之间的角度。如果光线垂直于物体表面,这束光对物体的影响会最大化。为了测量光线和片段的角度,我们使用一个叫做法向量(Normal Vector)的东西,法向量(Normal Vector)是垂直于顶点表面的(单位)向量。由于顶点自身并没有表面(它只是空间中一个独立的点),我们利用顶点周围的顶点计算出这个顶点的表面。
玩转WebGL(六)漫反射光照
漫反射光最后的颜色定义公式为:

漫反射光的颜色= 入射光的颜色 x 物理的颜色 x 入射角的余弦

向量a,b的点乘 = |a||b|cos<a,b>,a,b都是归一化后的向量,归一化后向量的模为1,所以向量的点乘就等于两个向量的余弦值

一个物体在光照下既发生了漫反射,又发生了环境反射,那么它最后反射光的颜色为:

反射光的颜色 = 漫反射光的颜色 + 环境反射光的颜色

顶点着色器

attribute vec4 a_position;
uniform mat4 u_worldViewProjection;
attribute vec4 aVertexColor;
//法向量的变量
attribute vec3 a_normal;

uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;


varying lowp vec4 vColor;
//将法向量从顶点着色器传递到片元着色器的变量
varying lowp vec3 v_normal;

void main() {
    gl_Position =uProjectionMatrix * uModelViewMatrix *  a_position;
    vColor = aVertexColor;
    v_normal = mat3(uModelViewMatrix) * a_normal;
}

在计算矩阵变换时需要按照规定的顺序,它是不满足乘法交换律的

clip=Mprojection⋅Mview⋅Mmodel⋅Vlocal

注意每个矩阵被运算的顺序是相反的(记住我们需要从右往左乘上每个矩阵)。

片段着色器

precision mediump float;
varying lowp vec4 vColor;
varying lowp vec3 v_normal;

//方向光的方向
uniform lowp vec3 u_light;

//方向光的颜色
uniform lowp vec3 u_lightColor;

void main() {
    vec3 normal = normalize(v_normal);
   
    gl_FragColor = vColor;
    // 环境光照
    vec3 ambientLight = gl_FragColor.rgb * u_lightColor;
    // 漫反射光照
    float light = max(dot(normal, u_light), 0.0);
    vec3 diffuseLight = gl_FragColor.rgb * light;

    gl_FragColor.rgb = ambientLight + diffuseLight;
}

玩转WebGL(六)漫反射光照

上一篇:BZOJ 1002: [FJOI2007]轮状病毒【生成树的计数与基尔霍夫矩阵简单讲解+高精度】


下一篇:【BZOJ】1002: [FJOI2007]轮状病毒(DP+规律+高精度)