着色器程序中光照模型的计算是如何进行的?
我正在尝试阅读本教程:
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);
}
具体来说,我不明白的一行是:
float dProd = max(0.0, dot(vNormal, light));
How does dot product of vNormal of a vertex and light create a orienting light.谁能给我用图表解释一下。我无法得到它。这对我来说看起来有点神奇。我知道在这个顶点着色器中,每个顶点都作为输入传递,称为正常,因为它以“1”表示,然后在上面的片段着色器代码中使用该共享变量。但除此之外我不明白它是如何工作的。
PS:我本可以询问博客作者,但据我所知,他正在休假两周。所以我想有一些物理或 Three.js 经验的人也许可以告诉我。
I am trying to read up this tutorial:
https://aerotwist.com/tutorials/an-introduction-to-shaders-part-2/
but I am not able to follow up. Basically the code creates a directional light by using shaders that run directly on the GPU. This is the code:
// 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);
}
Specifically, the line that I don't understand is this one:
float dProd = max(0.0, dot(vNormal, light));
How does dot product of vNormal of a vertex and light create a directional light. Can anybody explain me diagrammatically. I am not able to get it . This looks bit of magic to me. I know in this vertex shader each vertex is being passed as an input which is called normal because it is represent in terms of "1" and that shared variable is then used in the above fragment shader code. But apart from this I didn't understand how it works.
P.S: I could have asked to the blog writer but he is on 2 weeks holiday as I know. So I thought someone with some physics or three.js experience might be able to tell me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
朗伯反射模型
为了对计算机图形学中的光反射进行建模,使用了双向反射分布函数 (BRDF)。
BRDF 是给出沿出射方向反射的光与从入射方向入射的光之间关系的函数。
完美的漫反射表面的 BRDF 对于所有入射和出射方向都具有相同的值。这大大减少了计算量,因此通常用于对漫反射表面进行建模,因为它在物理上是合理的,即使现实世界中不存在纯漫反射材料。这个 BRDF 被称为朗伯反射,因为它遵循朗伯余弦定律。
朗伯反射通常用作漫反射的模型。此技术使所有闭合多边形(例如 3D 网格内的三角形)在渲染时在所有方向上均匀地反射光线。漫射系数是根据法线矢量和光矢量之间的角度计算的。
其中
N
是表面的法线向量,L
是朝向光源的向量。工作原理
一般来说,2 个向量的点积等于 2 个向量之间的角度的余弦乘以两个向量的大小(长度)。
由此可见,2 个单位向量的点积等于 2 个向量之间角度的余弦,因为单位向量的长度为 1。
如果我们看一下角度 -90° 和 90° 之间的 cos(x) 函数,我们可以看到它在 0° 角度处的最大值为 1,并且它下降到0 在 90° 和 -90° 的角度。
这种行为正是我们想要的反射模型。当表面的正常矢量和光源的方向处于同一方向(之间的角度为 0°)时,我们需要最大的反射。
相反,如果向量正交化(之间的角度为 90°),那么我们想要最小的反射,并且我们想要在 0° 和 90° 的两个边界之间平滑且连续的函数运行。
如果在顶点着色器中计算光照模型,则会计算图元的每个角的反射。在基元之间,反射根据其重心坐标进行插值。
查看球面上的反射结果:
另请参阅:
WebGL 示例:球体上的朗伯漫反射
Lambertian reflectance model
To model the reflection of light in computer graphics is used a Bidirectional reflectance distribution function (BRDF).
BRDF is a function that gives the relation between the light reflected along an outgoing direction and the light incident from an incoming direction.
A perfect diffuse surface has a BRDF that has the same value for all incident and outgoing directions. This substantially reduces the computations and thus it is commonly used to model diffuse surfaces as it is physically plausible, even though there are no pure diffuse materials in the real world. This BRDF is called Lambertian reflection because it obeys Lambert's cosine law.
Lambertian reflection is often used as a model for diffuse reflection. This technique causes all closed polygons (such as a triangle within a 3D mesh) to reflect light equally in all directions when rendered The diffusion coefficient is calculated from the angle between the normal vector and the light vector.
where
N
is the normal vector of the surface, andL
is the vector towards to the light source.How it works
In general The dot product of 2 vectors is equal the cosine of the angle between the 2 vectors multiplied by the magnitude (lenght) of both vectors.
This follows, that the dot product of 2 unit vectors is equal the cosine of the angle between the 2 vectors, because the length of a unit vector is 1.
If we take a look at the cos(x) function between the angles -90° and 90° then we can see that it has a maximum of 1 at an angle of 0° and It goes down to 0 at the angles of 90° and -90°.
This behavior is exactly that what we want for the reflection model. When the nromal vetor of the surface and the diretion to the light source are in the same direction (the angle between is 0°) then we want a maximium of reflection.
In contrast, if the vectors a orthonormalized (the angle in between is 90°) then we want a minimum of reflection and we want a smooth and continuous functional running between the two borders of 0° and 90°.
If the light model is calculated in the vertex shader, the reflection is calculated for each corner of the primitive. In between the primitives the reflections are interpolate according to its barycentric coordinates.
See the resulting reflections on a spherical surface:
See also:
WebGL example: Lambertian diffuse reflection on a sphere