1
0
mirror of https://github.com/LearnOpenGL-CN/LearnOpenGL-CN.git synced 2025-08-24 05:05:29 +08:00

Update 02-05

This commit is contained in:
BLumia
2016-03-21 10:53:46 +08:00
parent b1df8c3f75
commit 8bcca2e926

View File

@@ -4,7 +4,7 @@
---|---
作者 | JoeyDeVries
翻译 | [Django](http://bullteacher.com/)
校对 | [Geequlim](http://geequlim.com)
校对 | [Geequlim](http://geequlim.com), [BLumia](https://github.com/BLumia)
我们目前使用的所有光照都来自于一个单独的光源,这是空间中的一个点。它的效果不错,但是在真实世界,我们有多种类型的光,它们每个表现都不同。一个光源把光投射到物体上,叫做投光。这个教程里我们讨论几种不同的投光类型。学习模拟不同的光源是你未来丰富你的场景的另一个工具。
@@ -94,13 +94,13 @@ glUniform3f(lightDirPos, -0.2f, -1.0f, -0.3f);
![](http://www.learnopengl.com/img/lighting/light_casters_point.png)
之前的教程我们已经使用了(最简单的)点光。我们有一个有位置的光源,它从自身的位置向所有方向发光线。然而,这个我们定义的光源所模拟光线的从不会衰减,这使得看起来光源亮度极强。在大多数3D模拟中,我们喜欢模拟一个能照亮一个周围确定区域光源,但它不会照亮整个场景。
之前的教程我们已经使用了(最简单的)点光。我们指定了一个光源以及其所在的位置,它从这个位置向所有方向发光线。然而,我们定义的光源所模拟光线的强度却不会因为距离变远而衰减,这使得看起来像是光源亮度极强。在大多数3D仿真场景中,我们更希望去模拟一个仅仅能照亮靠近光源点附近场景的光源,而不是照亮整个场景的光源
如果你把10个箱子添加到之前教程的光照场景中你会注意到黑暗中的每个箱子都会有同样的亮度就像箱子在光照的前面没有公式定义光的距离衰减。我们想让黑暗中与光源比较近的箱子被轻微地照亮。
### 衰减(Attenuation)
随着光线穿越更远的距离相应地减少亮度,通常被称为衰减(Attenuation)。一种随着距离减少亮度的方式是使用线性等式。这样的一个随着距离减少亮度的线性方程,可以使远处的物体更暗。然而,这样的线性方程效果会有点假。在真实世界,通常光在近处时非常亮,但是一个光源的亮度,开始的时候减少的非常快,之后随着距离的增加,减少的速度会慢下来。我们需要一种不同的方程来减少光的亮度。
随着光线穿越距离的变远使得亮度也相应地减少的现象,通常称之为**衰减(Attenuation)**。一种随着距离减少亮度的方式是使用线性等式。这样的一个随着距离减少亮度的线性方程,可以使远处的物体更暗。然而,这样的线性方程效果会有点假。在真实世界,通常光在近处时非常亮,但是一个光源的亮度,开始的时候减少的非常快,之后随着距离的增加,减少的速度会慢下来。我们需要一种不同的方程来减少光的亮度。
幸运的是一些聪明人已经早就把它想到了。下面的方程把一个片段的光的亮度除以一个已经计算出来的衰减值,这个值根据光源的远近得到:
@@ -121,7 +121,7 @@ glUniform3f(lightDirPos, -0.2f, -1.0f, -0.3f);
#### 选择正确的值
但是,我们把这三个项设置为什么值呢?正确的值的设置由很多因素决定:环境、你希望光所覆盖的距离范围、光的类型等。大多数场合,这是经验的问题,也要适度调整。下面的表格展示一些各项的值,它们模拟现实(某种类型的)光源,覆盖特定的半径(距离)。第一定义一个光的距离它覆盖所给定的项。这些值是大多数光的良好开始它是来自Ogre3D的维基的礼物
但是,我们把这三个项设置为什么值呢?正确的值的设置由很多因素决定:环境、你希望光所覆盖的距离范围、光的类型等。大多数场合,这是经验的问题,也要适度调整。下面的表格展示一些各项的值,它们模拟现实(某种类型的)光源,覆盖特定的半径(距离)。第一定义一个光的距离它覆盖所给定的项。这些值是大多数光的良好开始它是来自Ogre3D的维基的礼物
Distance|Constant|Linear|Quadratic
-------|------|-----|------
@@ -167,7 +167,7 @@ glUniform1f(glGetUniformLocation(lightingShader.Program, "light.quadratic"), 0.0
在片段着色器中实现衰减很直接:我们根据公式简单的计算衰减值,在乘以`ambient`、`diffuse`和`specular`元素。
我们需要光源的距离提供给公式;记得我们能够计算向量的长度吗我们可以通过获取片段和光源之间的不同向量把向量的长度结果作为距离项。我们可以使用GLSL的内建`length`函数做这件事:
我们需要光源的距离提供给公式;记得我们是怎样计算向量的长度吗我们可以通过获取片段和光源之间的不同向量把向量的长度结果作为距离项。我们可以使用GLSL的内建`length`函数做这件事:
```c++
float distance = length(light.position - Position);
@@ -315,3 +315,7 @@ specular* = intensity;
看起来好多了。仔细看看内部和外部遮光角,尝试创建一个符合你求的聚光灯。可以在这里找到应用源码,以及片段的源代码。
这样的一个手电筒/聚光灯类型的灯光非常适合恐怖游戏,结合定向和点光,环境会真的开始被照亮了。[下一个教程](http://learnopengl-cn.readthedocs.org/zh/latest/02%20Lighting/06%20Multiple%20lights/),我们会结合所有我们目前讨论了的光和技巧。
## 练习
- 试着修改上面的各种不同种类的光源及其片段着色器。试着将部分矢量进行反向并尝试使用 < 来代替 > 。试着解释这些修改导致不同显示效果的原因。