diff --git a/docs/02 Lighting/03 Materials.md b/docs/02 Lighting/03 Materials.md index d9a6642..9422cba 100644 --- a/docs/02 Lighting/03 Materials.md +++ b/docs/02 Lighting/03 Materials.md @@ -40,7 +40,7 @@ uniform Material material; # 设置材质 -我们在片段着色器中创建了一个材质结构体的uniform,所以下面我们希望修改一下光照的计算来顺应新的材质属性。由于所有材质变量都储存在结构体中,我们可以从uniform变量material中访问它们: +我们在片段着色器中创建了一个材质结构体的uniform,所以下面我们希望修改一下光照的计算来遵从新的材质属性。由于所有材质变量都储存在一个结构体中,我们可以从uniform变量material中访问它们: ```c++ void main() @@ -65,9 +65,9 @@ void main() } ``` -可以看到,我们现在在需要的地方访问了材质结构体中的所有属性,并且这次是根据材质的颜色来计算最终的输出颜色的。物体的每个材质属性都乘上了它们对应的光照分量。 +可以看到,我们现在在需要的地方访问了材质结构体中的所有属性,并且这次是根据材质的颜色来计算最终的输出颜色的。物体的每个材质属性都乘上了它们各自对应的光照分量。 -我们现在可以在程序中设置适当的uniform,对物体设置材质了。GLSL中的结构体在设置uniform时并没有什么特别之处。结构体只是作为uniform变量的一个封装,所以如果想填充这个结构体的话,我们仍需要对每个单独的uniform进行设置,但这次要带上结构体名的前缀: +我们现在可以通过设置适当的uniform来设置应用中物体的材质了。GLSL中一个结构体在设置uniform时并无任何区别,结构体只是充当uniform变量们的一个命名空间。所以如果想填充这个结构体的话,我们必须设置每个单独的uniform,但要以结构体名为前缀: ```c++ lightingShader.setVec3("material.ambient", 1.0f, 0.5f, 0.31f); @@ -76,18 +76,18 @@ lightingShader.setVec3("material.specular", 0.5f, 0.5f, 0.5f); lightingShader.setFloat("material.shininess", 32.0f); ``` -我们将环境光和漫反射分量设置成我们想要让物体所拥有的颜色,而将镜面分量设置为一个中等亮度的颜色,我们不希望镜面分量在这个物体上过于强烈。我们将反光度保持为32。现在我们能够程序中非常容易地修改物体的材质了。 +我们将环境光和漫反射分量设置成我们想要让物体所拥有的颜色,而将镜面分量设置为一个中等亮度的颜色,我们不希望镜面分量过于强烈。我们仍将反光度保持为32。 -运行程序,你应该会得到下面这样的结果: +现在我们能够轻松地在应用中影响物体的材质了。运行程序,你会得到像这样的结果: ![](../img/02/03/materials_with_material.png) -但它看起来很奇怪不是吗? +不过看起来真的不太对劲? ## 光的属性 -这个物体太亮了。物体过亮的原因是环境光、漫反射和镜面光这三个颜色对任何一个光源都会去全力反射。光源对环境光、漫反射和镜面光分量也具有着不同的强度。前面的教程,我们通过使用一个强度值改变环境光和镜面光强度的方式解决了这个问题。我们想做一个类似的系统,但是这次是要为每个光照分量都指定一个强度向量。如果我们假设lightColor是`vec3(1.0)`,代码会看起来像这样: +这个物体太亮了。物体过亮的原因是环境光、漫反射和镜面光这三个颜色对任何一个光源都全力反射。光源对环境光、漫反射和镜面光分量也分别具有不同的强度。前面的章节中,我们通过使用一个强度值改变环境光和镜面光强度的方式解决了这个问题。我们想做类似的事情,但是这次是要为每个光照分量分别指定一个强度向量。如果我们假设lightColor是`vec3(1.0)`,代码会看起来像这样: ```c++ vec3 ambient = vec3(1.0) * material.ambient; @@ -95,13 +95,13 @@ vec3 diffuse = vec3(1.0) * (diff * material.diffuse); vec3 specular = vec3(1.0) * (spec * material.specular); ``` -所以物体的每个材质属性对每一个光照分量都返回了最大的强度。对单个光源来说,这些`vec3(1.0)`值同样可以分别改变,而这通常就是我们想要的。现在,物体的环境光分量完全地影响了立方体的颜色,可是环境光分量实际上不应该对最终的颜色有这么大的影响,所以我们会将光源的环境光强度设置为一个小一点的值,从而限制环境光颜色: +所以物体的每个材质属性对每一个光照分量都返回了最大的强度。对单个光源来说,这些`vec3(1.0)`值同样可以对每种光源分别改变,而这通常就是我们想要的。现在,物体的环境光分量完全地影响了立方体的颜色,可是环境光分量实际上不应该对最终的颜色有这么大的影响,所以我们会将光源的环境光强度设置为一个小一点的值,从而限制环境光颜色: ```c++ vec3 ambient = vec3(0.1) * material.ambient; ``` -我们可以用同样的方式修改光源的漫反射和镜面光强度。这和我们在[上一节](02 Basic Lighting.md)中所做的极为相似,你可以说我们已经创建了一些光照属性来影响每个单独的光照分量。我们希望为光照属性创建一个与材质结构体类似的结构体: +我们可以用同样的方式影响光源的漫反射和镜面光强度。这和我们在[上一节](02 Basic Lighting.md)中所做的极为相似,你可以认为我们已经创建了一些光照属性来影响各个光照分量。我们希望为光照属性创建类似材质结构体的东西: ```c++ struct Light { @@ -115,7 +115,7 @@ struct Light { uniform Light light; ``` -一个光源对它的ambientdiffusespecular光照有着不同的强度。环境光照通常会设置为一个比较低的强度,因为我们不希望环境光颜色太过显眼。光源的漫反射分量通常设置为光所具有的颜色,通常是一个比较明亮的白色。镜面光分量通常会保持为`vec3(1.0)`,以最大强度发光。注意我们也将光源的位置添加到了结构体中。 +一个光源对它的ambientdiffusespecular光照分量有着不同的强度。环境光照通常被设置为一个比较低的强度,因为我们不希望环境光颜色太过主导。光源的漫反射分量通常被设置为我们希望光所具有的那个颜色,通常是一个比较明亮的白色。镜面光分量通常会保持为`vec3(1.0)`,以最大强度发光。注意我们也将光源的位置向量加入了结构体。 和材质uniform一样,我们需要更新片段着色器: @@ -125,7 +125,7 @@ vec3 diffuse = light.diffuse * (diff * material.diffuse); vec3 specular = light.specular * (spec * material.specular); ``` -我们接下来在程序中设置光照强度: +我们接下来在应用中设置光照强度: ```c++ lightingShader.setVec3("light.ambient", 0.2f, 0.2f, 0.2f); @@ -133,7 +133,7 @@ lightingShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f); // 将光照调暗 lightingShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); ``` -现在我们调整了光照对物体材质的影响,我们应该能得到一个更类似于上一节的视觉效果。但这次我们有了对光照和物体材质的完全掌控: +现在我们已经调整了光照对物体材质的影响,我们得到了一个与上一节很相似的视觉效果。但这次我们有了对光照和物体材质的完全掌控: ![](../img/02/03/materials_light.png) @@ -141,7 +141,7 @@ lightingShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); ## 不同的光源颜色 -到目前为止,我们都只对光源设置了从白到灰到黑范围内的颜色,这样只会改变物体各个分量的强度,而不是它的真正颜色。由于现在能够非常容易地访问光照的属性了,我们可以随着时间改变它们的颜色,从而获得一些非常有意思的效果。由于所有的东西都在片段着色器中配置好了,修改光源的颜色非常简单,我们能够立刻创造一些很有趣的效果: +到目前为止,我们都只对光源设置了从白到灰到黑范围内的颜色,这样只会改变物体各个分量的强度,而不是它的真正颜色。由于现在能够非常容易地访问光照的属性了,我们可以随着时间改变它们的颜色,从而获得一些非常有意思的效果。由于所有的东西都在片段着色器中配置好了,修改光源的颜色非常简单,并立刻创造一些很有趣的效果: @@ -163,8 +163,9 @@ lightingShader.setVec3("light.ambient", ambientColor); lightingShader.setVec3("light.diffuse", diffuseColor); ``` -尝试并实验一些光照和材质值,看看它们是怎样影响视觉输出的。你可以在[这里](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/3.1.materials/materials.cpp)找到程序的源码。 +尝试并实验一些光照和材质值,看看它们是怎样影响视觉输出的。你可以在[这里](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/3.1.materials/materials.cpp)找到应用的源码。 ## 练习 -- 你能像教程一开始那样,定义相应的材质来模拟现实世界的物体吗?注意[材质表格](http://devernay.free.fr/cours/opengl/materials.html)中的环境光值可能与漫反射值不一样,它们没有考虑光照的强度。要想纠正这一问题,你需要将所有的光照强度都设置为`vec3(1.0)`,这样才能得到正确的输出:[参考解答](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/3.2.materials_exercise1/materials_exercise1.cpp),我做的是青色塑料(Cyan Plastic)的箱子。 +- 你能做到这件事吗,改变光照颜色导致改变光源立方体的颜色? +- 你能像教程一开始那样,通过定义相应的材质来模拟现实世界的物体吗?注意[材质表格](http://devernay.free.fr/cours/opengl/materials.html)中的环境光值与漫反射值不一样,它们没有考虑光照的强度。要想正确地设置它们的值,你需要将所有的光照强度都设置为`vec3(1.0)`,这样才能得到一致的输出:[参考解答](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/3.2.materials_exercise1/materials_exercise1.cpp):青色塑料(Cyan Plastic)容器。