这种伪造的灯光如何作用于气动扭力?

TCM*_*TCM 2 lighting glsl light webgl three.js

我正在尝试阅读本教程:

https://aerotwist.com/tutorials/an-introduction-to-shaders-part-2/

但我无法跟进。基本上,代码使用直接在GPU上运行的着色器创建定向光。这是代码:

// same name and type as VS
varying vec3 vNormal;

void main() {

    // calc the dot product and clamp
    // 0 -> 1 rather than -1 -> 1
    vec3 light = vec3(0.5,0.2,1.0);

    // ensure it's normalized
    light = normalize(light);

    // calculate the dot product of
    // the light to the vertex normal
    float dProd = max(0.0, dot(vNormal, light));

    // feed into our frag colour
    gl_FragColor = vec4(dProd, dProd, dProd, 1.0);

} 
Run Code Online (Sandbox Code Playgroud)

具体来说,我不明白的这一行是:

float dProd = max(0.0, dot(vNormal, light));
Run Code Online (Sandbox Code Playgroud)

顶点的vNormal与光的点积如何创建定向光。谁能以图解方式向我解释。我无法得到它。在我看来,这有点神奇。我知道在此顶点着色器中,每个顶点都作为输入传递,这称为正常,因为它以“ 1”表示,然后在上面的片段着色器代码中使用了共享变量。但是除此之外,我不知道它是如何工作的。

PS:我本来可以问博客作者的,但据我所知,他正休假2周。因此,我认为具有一定物理或Three.js经验的人可能会告诉我。

Rab*_*d76 5

朗伯反射模型

为了模拟计算机图形中的光反射,使用了双向反射率分布函数(BRDF)。BRDF是一种功能,可提供沿出射方向反射的光与从出射方向入射的光之间的关系。

理想的漫反射表面具有BRDF,该BRDF对于所有入射和出射方向都具有相同的值。这大大减少了计算量,因此,即使在现实世界中没有纯粹的漫反射材料,由于它在物理上是合理的,因此通常用于对漫反射表面进行建模。此BRDF被称为Lambertian反射,因为它遵守Lambert的余弦定律。

朗伯反射通常用作漫反射的模型。此技术使所有闭合的多边形(例如3D网格中的三角形)在渲染时均能在所有方向上均等地反射光。扩散系数是根据法向矢量和光矢量之间的角度计算的。

f_Lambertian = max( 0.0, dot( N, L )
Run Code Online (Sandbox Code Playgroud)

其中,N是表面的法线向量,并且L是朝向光源的向量。

怎么运行的

通常,两个向量的积等于两个向量之间的角度的余弦值乘以两个向量的大小(长度)。

dot( A, B ) == length( A ) * length( B ) * cos( angle_A_B ) 
Run Code Online (Sandbox Code Playgroud)

因此,由于一个单位矢量的长度为1,所以两个单位矢量的积等于两个矢量之间的角度的余弦

uA = normalize( A )
uB = normalize( B )
cos( angle_A_B ) == dot( uA, uB )
Run Code Online (Sandbox Code Playgroud)

点B

如果我们看一下-90°和90°角之间的cos(x)函数,那么我们可以看到它在0°角处最大为1,而在90°角处下降为0和-90°。

余弦在[-90°,90°]

这种行为正是我们对反射模型所要的。当表面的矢量和光源的方向相同(方向之间的夹角为0°)时,我们需要最大的反射率。相反,如果向量经过正交归一化(它们之间的角度为90°),则我们需要最小的反射,并且我们希望在0°和90°的两个边界之间具有平稳连续的功能。

N点L

如果在顶点着色器中计算光源模型,则将为图元的每个角计算反射。在图元之间,根据其重心坐标对反射进行插值。查看球面上的反射结果:

在此处输入图片说明

也可以看看:


WebGL示例:球上的朗伯散射

f_Lambertian = max( 0.0, dot( N, L )
Run Code Online (Sandbox Code Playgroud)
dot( A, B ) == length( A ) * length( B ) * cos( angle_A_B ) 
Run Code Online (Sandbox Code Playgroud)
uA = normalize( A )
uB = normalize( B )
cos( angle_A_B ) == dot( uA, uB )
Run Code Online (Sandbox Code Playgroud)