Prepare for the convert
@@ -1,8 +1,10 @@
|
|||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>JoeyDeVries<EFBFBD><EFBFBD><EFBFBD><EFBFBD>[Django](http://bullteacher.com/14-materials.html)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[http://learnopengl.com](http://learnopengl.com/#!Lighting/Materials)
|
本文作者JoeyDeVries,由[Django](http://bullteacher.com/14-materials.html)翻译自[http://learnopengl.com](http://learnopengl.com/#!Lighting/Materials)
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Թ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD><EFBFBD>ֱ<EFBFBD><EFBFBD>մɻ<EFBFBD>ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⡣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ľͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>Թ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD>߹<EFBFBD>Ҳ<EFBFBD>в<EFBFBD>ͬ<EFBFBD>ķ<EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD>岻<EFBFBD><EFBFBD>ɢ<EFBFBD><EFBFBD><EFBFBD>ܶ<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>ᷴ<EFBFBD><EFBFBD><EFBFBD>ܶ<EFBFBD><EFBFBD>⣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ĸ߹<EFBFBD><EFBFBD>㣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɢ<EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD>࣬<EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>뾶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ߹⡣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>OpenGL<EFBFBD><EFBFBD>ģ<EFBFBD>⼸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>壬<EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD><EFBFBD><EFBFBD>Ϊÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嶨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD>
|
# 材质
|
||||||
|
|
||||||
<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>Ľ̳<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ء<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD>Ϊ3<EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>أ<EFBFBD>ambient<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>շֱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>Ϊÿ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˾<EFBFBD><EFBFBD>ܵĿ<EFBFBD><EFBFBD>ơ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>
|
在真实世界里,每个物体会对光产生不同的反作用。钢比陶瓷花瓶更闪闪发光。比如一块木头不会和钢一样对光做出相同反作用。每个物体对specular高光也有不同的反应。有些物体不会散射很多光却会反射很多光,结果看起来就有一个较小的高光点,其他物体散射的更多,就会产生一个半径更大的高光。如果我们想要在OpenGL中模拟几种类型的物体,我们必须为每个物体定义材质属性。
|
||||||
|
|
||||||
|
在前面的教程中,我们指定一个物体和一个光的颜色来定义物体的图像输出,并使之结合ambient和specular亮度元素。当描述物体的时候,我们可以为3种光照元素:ambient、diffuse、specular光照分别定义一个材质颜色。通过为每个元素指定一个颜色,我们已经对物体的颜色输出有了精密的控制。现在把一个发亮元素添加到这三个颜色里,这是我们需要的所有材质属性:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
#version 330 core
|
#version 330 core
|
||||||
@@ -15,22 +17,22 @@ struct Material
|
|||||||
};
|
};
|
||||||
uniform Material material;
|
uniform Material material;
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD>壬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniformֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊһ<EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ը<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD>֣<EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD>
|
在像素着色器中,我们创建一个结构体,来储存物体的材质属性。我们也可以把它们储存为独立的uniform值,但是作为一个结构体来储存可以更有条理。我们首先定义结构体的布局,然后简单声明一个uniform变量,以新近创建的结构体作为它的类型。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊÿ<EFBFBD><EFBFBD>Phong<EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>Ԫ<EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>巴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲô<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD>߹<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>shininessӰ<EFBFBD><EFBFBD>specular<EFBFBD>߹<EFBFBD><EFBFBD><EFBFBD>ɢ<EFBFBD><EFBFBD>/<2F>뾶<EFBFBD><EBBEB6>
|
就像你所看到的,我们为每个Phong光照的元素都定义一个颜色向量。ambient材质向量定义了在ambient光照下这个物体反射的是什么颜色;通常这是和物体颜色相同的颜色。diffuse材质向量定义了在diffuse光照下物体的颜色。diffuse颜色被设置为(和ambient光照一样)物体要求的颜色。specular材质向量设置的是物体受到的specular光的影响的颜色(或者可能是反射一个物体特定的specular高光颜色)。最后,shininess影响specular高光的散射/半径。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>Ԫ<EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD>ʣ<EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>ܶ<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD>ʡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>devernay.free.frչʾ<D5B9>˼<EFBFBD><CBBC>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD>Щ<EFBFBD><D0A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>ʡ<EFBFBD><CAA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬչʾ<D5B9>˼<EFBFBD><CBBC><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD>죺
|
这四个元素定义了一个物体的材质,通过它们我们能够模拟很多真实世界的材质。这里有一个列表devernay.free.fr展示了几种材质属性,这些材质属性模拟外部世界的真实材质。下面的图片展示了几种真实世界材质对我们的立方体的影响:
|
||||||

|

|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD>ƺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Եı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>עĿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵЧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD>״<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>塣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳̲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>۸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD>״<EFBFBD><EFBFBD>
|
就像你所看到的,正确的指定一个物体的材质属性,似乎就是改变我们物体的相关属性的比例。效果显然很引人注目,但是对于大多数真实效果,我们最终需要更加复杂的形状,而不单单是一个立方体。在下面教程部分里,我们会讨论更复杂的形状。
|
||||||
|
|
||||||
Ϊһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>帳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>գ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>ͷḻ<EFBFBD>ľ<EFBFBD><EFBFBD>飬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD>ʶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD>
|
为一个物体赋予正确的材质是一件高难的手艺,这需要大量实验和丰富的经验,所以由于错误的设置材质而毁了物体的画面质量是件经常发生的事。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD>
|
让我们试试在着色器中实现这样的一个材质系统。
|
||||||
|
|
||||||
|
|
||||||
##14.1 <20><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
|
## 设置材质
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD>ʽṹ<EFBFBD>壬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳Ӧ<EFBFBD>µIJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڽṹ<EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD>Դ<EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD><EFBFBD>materialȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD>
|
我们在像素着色器中创建了一个uniform材质结构体,所以下面我们希望改变光照计算来顺应新的材质属性。由于所有材质变量都是储存在结构体中,我们可以从uniform变量material取得它们:
|
||||||
```c++
|
```c++
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@@ -53,9 +55,9 @@ void main()
|
|||||||
color = vec4(result, 1.0f);
|
color = vec4(result, 1.0f);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD>ʽṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>İ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD>Ӧ<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ء<EFBFBD>
|
就像你所看到的,我么现在获得所有材质结构体的属性,无论在哪儿我们都需要它们,这次通过材质颜色的帮助,计算结果输出的颜色。物体的每个材质属性都乘以它们对应的光照元素。
|
||||||
|
|
||||||
ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD>ʡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniformʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>GLSL<EFBFBD>е<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD>岻<EFBFBD>ᱻ<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>ʲô<EFBFBD>ر<EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD>װ<EFBFBD>壬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD>壬<EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD>нṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊǰ<EFBFBD><EFBFBD>
|
通过设置适当的uniform,我们可以在应用中设置物体的材质。当设置uniform时,在GLSL中的一个结构体不会被认为有什么特别之处。一个结构体值扮演uniform变量的封装体,所以如果我们希望填充这个结构体,我们就仍然必须设置单独的uniform,但是这次带有结构体名字作为前缀:
|
||||||
```c++
|
```c++
|
||||||
GLint matAmbientLoc = glGetUniformLocation(lightingShader.Program, "material.ambient");
|
GLint matAmbientLoc = glGetUniformLocation(lightingShader.Program, "material.ambient");
|
||||||
GLint matDiffuseLoc = glGetUniformLocation(lightingShader.Program, "material.diffuse");
|
GLint matDiffuseLoc = glGetUniformLocation(lightingShader.Program, "material.diffuse");
|
||||||
@@ -67,26 +69,26 @@ glUniform3f(matDiffuseLoc, 1.0f, 0.5f, 0.31f);
|
|||||||
glUniform3f(matSpecularLoc, 0.5f, 0.5f, 0.5f);
|
glUniform3f(matSpecularLoc, 0.5f, 0.5f, 0.5f);
|
||||||
glUniform1f(matShineLoc, 32.0f);
|
glUniform1f(matShineLoc, 32.0f);
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>diffuseԪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specularԪ<EFBFBD><EFBFBD>Ϊ<EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD>ϣ<EFBFBD><EFBFBD>specularԪ<EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ҵ<EFBFBD>Ӱ<EFBFBD>졣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD>Ϊ32<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD>ʡ<EFBFBD>
|
我们设置ambient和diffuse元素我们喜欢物体所呈现的颜色,设置物体的specular元素为中等亮度颜色;我们不希望specular元素对这个指定物体产生过于强烈的影响。我们同样保持光亮为32。我们现在可以简单的在应用中影响物体的材质。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
运行程序,会得到下面这样的结果:
|
||||||

|

|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>治<EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
看起来真不怎么样对吗?
|
||||||
|
|
||||||
|
|
||||||
##14.2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
## 光的属性
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̫<EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դȫ<EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD><EFBFBD>䡣<EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>specularԪ<EFBFBD><EFBFBD>ͬʱ<EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>Ľ̳̣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD>ֵ<EFBFBD>ı<EFBFBD>ambient<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ȵķ<EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>lightColor<EFBFBD><EFBFBD>vec3(1.0)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뿴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
这个物体太亮了。物体过亮的原因是ambient、diffuse和specular颜色被从任何一个光源全力地反射。光源对ambient、diffuse和specular元素同时有着不同的亮度。前面的教程,我们通过使用一个强度值改变ambient和specular亮度的方式,解决了这个问题,但是这次为每个光照元素指定了亮度向量。如果我们想象lightColor是vec3(1.0),代码看起来像是这样:
|
||||||
```c++
|
```c++
|
||||||
vec3 ambient = vec3(1.0f) * material.ambient;
|
vec3 ambient = vec3(1.0f) * material.ambient;
|
||||||
vec3 diffuse = vec3(1.0f) * (diff * material.diffuse);
|
vec3 diffuse = vec3(1.0f) * (diff * material.diffuse);
|
||||||
vec3 specular = vec3(1.0f) * (spec * material.specular);
|
vec3 specular = vec3(1.0f) * (spec * material.specular);
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>Щvec3(1.0)ֵ<><D6B5><EFBFBD>Ը<EFBFBD><D4B8>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambientԪ<74><D4AA><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambientԪ<EFBFBD><EFBFBD>uyinggai<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD>죬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊһ<EFBFBD><EFBFBD>Сһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ķ<EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>
|
所以物体的每个材质属性返回了每个光照元素的全亮度。这些vec3(1.0)值可以各自独立的影响每个光源,这通常就是我们想要的。现在物体的ambient元素完全地影响了立方体的颜色,可视ambient元素uyinggai对最终颜色有这么大的影响,所以我们要通过设置光的ambient亮度为一个小一点的值的方式,限制ambient颜色:
|
||||||
```c++
|
```c++
|
||||||
vec3 result = vec3(0.1f) * material.ambient;
|
vec3 result = vec3(0.1f) * material.ambient;
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD>ʽӰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ը<EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ء<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>һЩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƵĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
我们可以用同样的方式影响光源的diffuse和specular亮度。这和我们前面教程所做的极为相似;你可以说我们已经创建了一些光的属性各自独立地来影响每个光照元素。我们希望为光的属性创建一些与材质结构体相似的东西:
|
||||||
```c++
|
```c++
|
||||||
struct Light
|
struct Light
|
||||||
{
|
{
|
||||||
@@ -97,15 +99,15 @@ struct Light
|
|||||||
};
|
};
|
||||||
uniform Light light;
|
uniform Light light;
|
||||||
```
|
```
|
||||||
һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>specular<EFBFBD>ⶼ<EFBFBD>в<EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ambient<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊһ<EFBFBD><EFBFBD><EFBFBD>Ƚϵ͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>Ŷ<EFBFBD>Dz<EFBFBD>ϣ<EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>diffuseԪ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>ɫ<EFBFBD><EFBFBD>specularԪ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊvec3(1.0f)<29><>ȫ<EFBFBD><C8AB><EFBFBD>ȵķ<C8B5><C4B7><EFBFBD><EFBFBD>ȡ<EFBFBD>Ҫ<EFBFBD><D2AA>ס<EFBFBD><D7A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5>ṹ<EFBFBD><E1B9B9><EFBFBD>С<EFBFBD>
|
一个光源的ambient、diffuse和specular光都有不同的亮度。ambient光通常设置为一个比较低的亮度,因为饿哦们不希望ambient颜色成为主导。光源的diffuse元素通常设置为我们希望光所具有的颜色;经常是一个明亮的白色。specular元素通常设置为vec3(1.0f)的全亮度的发光度。要记住的是我们同样把光的位置添加到结构体中。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniformһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
就像材质uniform一样,我么你需要更新像素着色器:
|
||||||
```c++
|
```c++
|
||||||
vec3 ambient = light.ambient * material.ambient;
|
vec3 ambient = light.ambient * material.ambient;
|
||||||
vec3 diffuse = light.diffuse * (diff * material.diffuse);
|
vec3 diffuse = light.diffuse * (diff * material.diffuse);
|
||||||
vec3 specular = light.specular * (spec * material.specular);
|
vec3 specular = light.specular * (spec * material.specular);
|
||||||
```
|
```
|
||||||
Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD>
|
然后我们要在应用里设置光的亮度:
|
||||||
```c++
|
```c++
|
||||||
GLint lightAmbientLoc = glGetUniformLocation(lightingShader.Program, "light.ambient");
|
GLint lightAmbientLoc = glGetUniformLocation(lightingShader.Program, "light.ambient");
|
||||||
GLint lightDiffuseLoc = glGetUniformLocation(lightingShader.Program, "light.diffuse");
|
GLint lightDiffuseLoc = glGetUniformLocation(lightingShader.Program, "light.diffuse");
|
||||||
@@ -115,20 +117,21 @@ glUniform3f(lightAmbientLoc, 0.2f, 0.2f, 0.2f);
|
|||||||
glUniform3f(lightDiffuseLoc, 0.5f, 0.5f, 0.5f); // Let's darken the light a bit to fit the scene
|
glUniform3f(lightDiffuseLoc, 0.5f, 0.5f, 0.5f); // Let's darken the light a bit to fit the scene
|
||||||
glUniform3f(lightSpecularLoc, 1.0f, 1.0f, 1.0f);
|
glUniform3f(lightSpecularLoc, 1.0f, 1.0f, 1.0f);
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еIJ<EFBFBD><EFBFBD>ʵģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵõ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>̵̳<EFBFBD><EFBFBD>Ӿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>պͲ<EFBFBD><EFBFBD>ʣ<EFBFBD>
|
现在,我们调整了光如何影响物体所有的材质的,我们得到一个更像前面教程的视觉输出。这次我们完全控制了物体光照和材质:
|
||||||

|

|
||||||
<EFBFBD><EFBFBD><EFBFBD>ڸı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
|
现在改变物体的外观相对简单了些。我们做点更有趣的事!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##14.3 <20><>ͬ<EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ɫ
|
## 不同的光的颜色
|
||||||
|
|
||||||
ĿǰΪֹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD>ʹ<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫȥ<EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵĶ<EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>أ<EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǴӰ<EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>˹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD>к<EFBFBD><EFBFBD><EFBFBD>˼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ʶ<EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>ܼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
目前为止,我们只是使用光的颜色去改变它们的独立元素,选择的是从白到灰到黑范围的颜色,不是动感的物体的真实颜色(只是亮度)。由于我们现在简单的取得了光的属性,我们可以随着时间改变它们的颜色,获得的效果有很意思。由于没见识都已经在像素着色器做好了,改变光的颜色很简单,可以立即创建出一些有趣的效果:
|
||||||
<video src="http://www.learnopengl.com/video/lighting/materials.mp4" controls="controls">
|
<video src="http://www.learnopengl.com/video/lighting/materials.mp4" controls="controls">
|
||||||
</video>
|
</video>
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫֱ<EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>巴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>̳̣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD>졣
|
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>sin<EFBFBD><EFBFBD>glfwGetTime<EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>żĸı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>
|
就像你所看见的,不同的光的颜色极大地影响了物体的颜色输出。由于光的颜色直接影响物体反射的颜色(你可能想起颜色教程),它对视觉输出有显著的影响。
|
||||||
|
|
||||||
|
利用sin和glfwGetTime,改变光的ambient和diffuse颜色,我们可以随着时间流逝简单的改变光的颜色:
|
||||||
```c++
|
```c++
|
||||||
glm::vec3 lightColor; lightColor.x = sin(glfwGetTime() * 2.0f);
|
glm::vec3 lightColor; lightColor.x = sin(glfwGetTime() * 2.0f);
|
||||||
lightColor.y = sin(glfwGetTime() * 0.7f);
|
lightColor.y = sin(glfwGetTime() * 0.7f);
|
||||||
@@ -140,4 +143,4 @@ glm::vec3 ambientColor = diffuseColor * glm::vec3(0.2f); // Low influence
|
|||||||
glUniform3f(lightAmbientLoc, ambientColor.x, ambientColor.y, ambientColor.z);
|
glUniform3f(lightAmbientLoc, ambientColor.x, ambientColor.y, ambientColor.z);
|
||||||
glUniform3f(lightDiffuseLoc, diffuseColor.x, diffuseColor.y, diffuseColor.z);
|
glUniform3f(lightDiffuseLoc, diffuseColor.x, diffuseColor.y, diffuseColor.z);
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD>ʵ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD>պͲ<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD>Ӧ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>롣
|
尝试和实验使用这些光照和材质值,看看它们怎样影响图像输出的。你可以从这里找到应用,和像素着色器的源码。
|
||||||
|
@@ -1,27 +1,29 @@
|
|||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>JoeyDeVries<EFBFBD><EFBFBD><EFBFBD><EFBFBD>[Django](http://bullteacher.com/15-lighting-maps.html)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[http://learnopengl.com](http://www.learnopengl.com/#!Lighting/Lighting-maps)
|
本文作者JoeyDeVries,由[Django](http://bullteacher.com/15-lighting-maps.html)翻译自[http://learnopengl.com](http://www.learnopengl.com/#!Lighting/Lighting-maps)
|
||||||
|
|
||||||
ǰ<EFBFBD><EFBFBD><EFBFBD>Ľ̳̣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嶼ӵ<EFBFBD>и<EFBFBD><EFBFBD>Բ<EFBFBD>ͬ<EFBFBD>IJ<EFBFBD><EFBFBD>ʣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Թ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD>ķ<EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>岻ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۺܰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD>ܶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD>
|
# 光照贴图
|
||||||
|
|
||||||
ǰ<EFBFBD><EFBFBD><EFBFBD>Ľ̳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嶨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ôһ<EFBFBD>ֲ<EFBFBD><EFBFBD>ʣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ჿ<EFBFBD>ַ<EFBFBD><EFBFBD>价<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̥û<EFBFBD><EFBFBD>specular<EFBFBD>߹⣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>dz<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>˶<EFBFBD><EFBFBD>ֲ<EFBFBD>ͬ<EFBFBD><EFBFBD>ambient/diffuse<73><65>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6>ж<EFBFBD><D0B6>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD>
|
前面的教程,我们讨论了每个物体都拥有各自不同的材质,因而会对光做出不同的反应。在一个光照场景中,给每个物体和其他物体不同的外观很棒,但是这仍然不会对一个物体的图像输出提供很多的伸缩性。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ⶼ<EFBFBD>Dz<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>չǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD>ɷ<EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD>ɷ<EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD>и<EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>Ӱ<EFBFBD>졣
|
前面的教程我们为一个物体的作为一个整体定义了一个材质,但是现实世界的物体通常不会只有这么一种材质,而是由多种材质组成。想象一辆车:它的外表质地光亮,车窗会部分反射环境,它的轮胎没有specular高光,轮彀却非常闪亮(在洗过之后)。汽车同样有diffuse和ambient颜色,它们在整个车上都不相同;一辆车显示了多种不同的ambient/diffuse颜色。总之,这样一个物体每个部分都有多种材质属性。
|
||||||
|
|
||||||
|
所以,前面的材质系统对于除了最简单的模型以外都是不够的,所以我们需要扩展前面的系统,我们要介绍diffuse和specular贴图。它们允许你对一个物体的diffuse(对于简洁的ambient成分来说,它们几乎总是是一样的)和specular成分能够有更精确的影响。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##15.1 diffuse<73><65>ͼ
|
## 漫反射贴图
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>ij<EFBFBD>ַ<EFBFBD>ʽ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD>ԭʼ<EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭʼ<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫֵ<EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
我们希望通过某种方式对每个原始像素独立设置diffuse颜色。有可以让我们基于物体原始像素的位置来获取颜色值的系统吗?
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>̹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ̳<EFBFBD><EFBFBD><EFBFBD≯<EFBFBD>۵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>ͬһ<EFBFBD><EFBFBD>DZ<EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD>µIJ<EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>ʹ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ס<EFBFBD><EFBFBD><EFBFBD>壬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊÿ<EFBFBD><EFBFBD>ԭʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>3D<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵĽз<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>
|
这可能听起来极其相似,坦白来讲我们我们使用这样的系统已经有一会儿了。听起来很像在一个较早的教程中谈论的纹理,它基本就是一个纹理。我们其实是使用同一个潜在原则下的不同名称:使用一张图片包裹住物体,我们为每个原始像素索引独立颜色值。在有光的场景里,通常叫做diffuse贴图(这通常是3D艺术家的叫法),因为这个纹理图像表现了所有物体的diffuse颜色。
|
||||||
|
|
||||||
Ϊ<EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һȦ<EFBFBD>ֱߵ<EFBFBD>ľ<EFBFBD>䣺
|
为了强调diffuse贴图,我们将会使用下面的图片,它是一个有一圈钢边的木箱:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳̽<EFBFBD><EFBFBD>ܵ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊsampler2D<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Material<EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vec3<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>diffuse<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>
|
在着色器中使用diffuse贴图和纹理教程介绍的一样。这次我们把纹理储存为sampler2D,它在Material结构体中。我们使用diffuse贴图替代早期定义的vec3类型的diffuse颜色。
|
||||||
|
|
||||||
Ҫ<EFBFBD><EFBFBD>ס<EFBFBD><EFBFBD><EFBFBD><EFBFBD>sampler2DҲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ýṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniformʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GLSL<EFBFBD><EFBFBD><EFBFBD>׳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD>
|
要记住的是sampler2D也叫做模糊类型,这意味着我们不能以某种类型对它实例化,只能用uniform定义它们。如果我们用结构体而不是uniform实例化(就像函数的参数那样),GLSL会抛出奇怪的错误;这同样也适用于其他模糊类型。
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҲҪ<EFBFBD>Ƴ<EFBFBD>amibient<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊambient<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ֱ<EFBFBD>ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
我们也要移除amibient材质颜色向量,因为ambient颜色绝大多数情况等于diffuse颜色,所以不需要分别去储存它:
|
||||||
```c++
|
```c++
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
@@ -32,18 +34,18 @@ struct Material
|
|||||||
...
|
...
|
||||||
in vec2 TexCoords;
|
in vec2 TexCoords;
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ambient<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD>diffuseֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>vec3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ambient<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><EFBFBD>䡣Ϊ<EFBFBD><EFBFBD>ʹÿ<EFBFBD><EFBFBD>ԭʼ<EFBFBD><EFBFBD><EFBFBD>صõ<EFBFBD><EFBFBD><EFBFBD>ͬambientֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>ambientֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
如果你非把ambient颜色设置为不同的值不可(不同于diffuse值),你可以继续保持ambient的vec3,但是整个物体的ambient颜色会继续保持不变。为了使每个原始像素得到不同ambient值,你需要对ambient值单独使用另一个纹理。
|
||||||
ע<EFBFBD>⣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٴ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>꣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǽش<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭʼ<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>diffuse<EFBFBD><EFBFBD>ɫֵ<EFBFBD><EFBFBD>
|
注意,在像素着色器中我们将会再次需要纹理坐标,所以我们声明一个额外输入变量。然后我们简单地从纹理采样,来获得原始像素的diffuse颜色值:
|
||||||
```c++
|
```c++
|
||||||
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
|
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
|
||||||
```
|
```
|
||||||
ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ambient<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊdiffuse<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>
|
同样,不要忘记把ambient材质的颜色设置为diffuse材质的颜色:
|
||||||
```c++
|
```c++
|
||||||
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
|
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㿴<EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>ⲻ<EFBFBD><EFBFBD>ʲô<EFBFBD>µĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD>Ʒ<EFBFBD>ʡ<EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>
|
这就是diffuse贴图的全部内容了。就像你看到的,这不是什么新的东西,但是它却极大提升了视觉品质。为了让它工作,我们需要用到纹理坐标更新顶点数据,把它们作为顶点属性传递到像素着色器,把纹理加载,把纹理绑定到合适的纹理单元。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD>µĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˶<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>꣬ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD>㶼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><EFBFBD>¶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
更新的顶点数据可以从这里找到。顶点数据现在包括了顶点位置,法线向量和纹理坐标,每个立方体的顶点都有这些属性。让我们更新顶点着色器来接受纹理坐标作为顶点属性,然后发送到像素着色器:
|
||||||
```c++
|
```c++
|
||||||
#version 330 core
|
#version 330 core
|
||||||
layout (location = 0) in vec3 position;
|
layout (location = 0) in vec3 position;
|
||||||
@@ -58,48 +60,48 @@ void main()
|
|||||||
TexCoords = texCoords;
|
TexCoords = texCoords;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Ҫ<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD>µĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>룬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>VAOƥ<EFBFBD><EFBFBD><EFBFBD>µĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ҲҪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊmaterial.diffuse<EFBFBD><EFBFBD><EFBFBD><EFBFBD>uniform<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>
|
要保证更新的顶点属性指针,不仅是VAO匹配新的顶点数据,也要把箱子图片加载为纹理。在绘制箱子之前,我们希望首选纹理单元被赋为material.diffuse这个uniform采样器,并绑定箱子的纹理到这个纹理单元:
|
||||||
```c++
|
```c++
|
||||||
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.diffuse"), 0);
|
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.diffuse"), 0);
|
||||||
...
|
...
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, diffuseMap);
|
glBindTexture(GL_TEXTURE_2D, diffuseMap);
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>ʹ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٴλ<EFBFBD><EFBFBD>þ<EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵĹ<EFBFBD><EFBFBD>տ<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><EFBFBD>ܿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
现在,使用一个diffuse贴图,我们在细节上再次获得惊人的提升,这次添加到箱子上的光照开始闪光了(名符其实)。你的箱子现在可能看起来像这样:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>Ӧ<EFBFBD>õ<EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>롣
|
你可以在这里得到应用的全部代码。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##15.2 specular<61><72>ͼ
|
## 镜面贴图
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD>߹⿴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪<EFBFBD><EFBFBD>ľͷ<EFBFBD>Dz<EFBFBD><EFBFBD><EFBFBD><EFBFBD>о<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߹<EFBFBD><EFBFBD>ġ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊvec3(0.0f)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD><EFBFBD><EFBFBD><DFBB><E1B2BB><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>߹⣬<DFB9><E2A3AC><EFBFBD><EFBFBD>֪<EFBFBD><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD>ʾһЩ<D2BB><D0A9><EFBFBD><EFBFBD><EFBFBD>߹<EFBFBD><DFB9>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>岿<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>߹⣬<DFB9><E2A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB8>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⿴<EFBFBD><E2BFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<73><65>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>벻<EFBFBD>ǡ<EFBFBD>
|
你可能注意到,specular高光看起来不怎么样,由于我们的物体是个箱子,大部分是木头,我们知道木头是不会有镜面高光的。我们通过把物体设置specular材质设置为vec3(0.0f)来修正它。但是这样意味着铁边会不再显示镜面高光,我们知道钢铁是会显示一些镜面高光的。我们会想要控制物体部分地显示镜面高光,它带有修改了的亮度。这个问题看起来和diffuse贴图的讨论一样。是巧合吗?我想不是。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>þ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߹⡣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ڰף<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>
|
我们同样适用一个纹理贴图,来获得镜面高光。这意味着我们需要生成一个黑白(或者你喜欢的颜色)纹理来定义specular亮度,把它应用到物体的每个部分。下面是一个specular贴图的例子:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
һ<EFBFBD><EFBFBD>specular<EFBFBD>߹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȿ<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾΪһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>磺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>vec3(0.0f)<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>vec3(0.5f)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Թ<EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><EFBFBD><EFBFBD>ס<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specualr<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
一个specular高光的亮度可以通过图片中每个纹理的亮度来获得。specular贴图的每个像素可以显示为一个颜色向量,比如:在那里黑色代表颜色向量vec3(0.0f),灰色是vec3(0.5f)。在像素着色器中,我们采样相应的颜色值,把它乘以光的specular亮度。像素越“白”,乘积的结果越大,物体的specualr部分越亮。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľͷ<EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>ľͷ<EFBFBD><EFBFBD>Ϊһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>о<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߹⣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>diffuse<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD>specular<EFBFBD>߹⡣<EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߹<EFBFBD>Ӱ<EFBFBD>죬ľ<EFBFBD>Ʋ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ᡣ
|
由于箱子几乎是由木头组成,木头作为一个材质不会有镜面高光,整个不透部分的diffuse纹理被用黑色覆盖:黑色部分不会包含任何specular高光。箱子的铁边有一个修改的specular亮度,它自身更容易受到镜面高光影响,木纹部分则不会。
|
||||||
|
|
||||||
<EFBFBD>Ӽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľͷҲ<EFBFBD>о<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߹⣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺⱻɢ<EFBFBD>䣩<EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>ѧϰĿ<EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD>Լ<EFBFBD>װľͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD>specular<EFBFBD>ⷴ<EFBFBD>䡣
|
从技术上来讲,木头也有镜面高光,尽管这个闪亮值很小(更多的光被散射),影响很小,但是为了学习目的,我们可以假装木头不会有任何specular光反射。
|
||||||
ʹ<EFBFBD><EFBFBD>Photoshop<EFBFBD><EFBFBD>Gimp֮<EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD>ߣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><EFBFBD>dz<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ױ任һ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪspecularͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>Աȶȵķ<C8B5>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ任Ϊ<E4BBBB><CEAA>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
|
使用Photoshop或Gimp之类的工具,剪切一些部分,非常容易变换一个diffuse纹理,为specular图片,以增加亮度/对比度的方式,可以把这个部分变换为黑色或白色。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###15.2.1 specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
###15.2.1 specular贴图采样
|
||||||
|
|
||||||
һ<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD><EFBFBD><EFBFBD>Ϊspecular<EFBFBD><EFBFBD>ͼʹ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD>鿴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ
|
一个specular贴图和其他纹理一样,所以代码和diffuse贴图的代码也相似。确保合理的加载了图片,生成一个纹理对象。由于我们在同样的像素着色器中使用另一个纹理采样器,我们必须为specular贴图使用一个不同的纹理单元(查看纹理),所以在渲染前让我们把它绑定到合适的纹理单元
|
||||||
```c++
|
```c++
|
||||||
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.specular"), 1);
|
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.specular"), 1);
|
||||||
...
|
...
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, specularMap);
|
glBindTexture(GL_TEXTURE_2D, specularMap);
|
||||||
```
|
```
|
||||||
Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>sampler2D<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vec3<EFBFBD><EFBFBD>
|
然后更新像素着色器材质属性,接受一个sampler2D作为这个specular部分的类型,而不是vec3:
|
||||||
```c++
|
```c++
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
@@ -108,20 +110,20 @@ struct Material
|
|||||||
float shininess;
|
float shininess;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡԭʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD>
|
最后我们希望采样这个specular贴图,来获取原始像素相应的specular亮度:
|
||||||
```c++
|
```c++
|
||||||
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
|
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
|
||||||
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
|
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
|
||||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
||||||
color = vec4(ambient + diffuse + specular, 1.0f);
|
color = vec4(ambient + diffuse + specular, 1.0f);
|
||||||
```
|
```
|
||||||
ͨ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD>弫Ϊ<EFBFBD><EFBFBD>ϸ<EFBFBD><EFBFBD>ϸ<EFBFBD>ڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵĸ<EFBFBD><EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>ͼ<EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD>ޡ<EFBFBD>
|
通过使用一个specular贴图我们可以定义极为精细的细节,物体的这个部分会获得闪亮的属性,我们可以设置它们相应的亮度。specular贴图给我们一个附加的高于diffuse贴图的控制权限。
|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㲻<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊÿ<EFBFBD><EFBFBD>ԭʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD>ͬʱҲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>specular<EFBFBD>߹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>Ƕ<EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪʲôͼƬͨ<EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>Ͱ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD>
|
如果你不想成为主流,你可以在specular贴图里使用颜色,不单单为每个原始像素设置specular亮度,同时也设置specular高光的颜色。从真实角度来说,specular的颜色基本是由光源自身决定的,所以它不会生成真实的图像(这就是为什么图片通常是黑色和白色的:我们只关心亮度)。
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵIJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷdz<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ľͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD>
|
如果你现在运行应用,你可以清晰地看到箱子的材质现在非常类似真实的铁边的木头箱子了:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD>ȫ<EFBFBD><EFBFBD>Դ<EFBFBD>롣Ҳ<EFBFBD>Ա<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
你可以在这里找到全部源码。也对比一下你的顶点着色器和像素着色器。
|
||||||
|
|
||||||
ʹ<EFBFBD><EFBFBD>diffuse<EFBFBD><EFBFBD>specular<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD>Ը<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>ϸ<EFBFBD>ڡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>編<EFBFBD><EFBFBD>/bump<6D><70>ͼ<EFBFBD><CDBC><EFBFBD>߷<EFBFBD><DFB7><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>ڡ<EFBFBD><DAA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD>ں<EFBFBD><DABA><EFBFBD><EFBFBD>̳̲Ż<CCB2><C5BB>漰<EFBFBD><E6BCB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>Ѻͼ<D1BA><CDBC>˿<EFBFBD><CBBF><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬<EFBFBD><E3A3AC><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD>ӻ<EFBFBD><D3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD>Ư<EFBFBD><C6AF><EFBFBD><EFBFBD>
|
使用diffuse和specular贴图,我们可以给相关但简单物体添加一个极为明显的细节。我们可以使用其他纹理贴图,比如法线/bump贴图或者反射贴图,给物体添加更多的细节。但是这些在后面教程才会涉及。把你的箱子给你所有的朋友和家人看,有一天你会很满足,我们的箱子会比现在更漂亮!
|
@@ -1,12 +1,14 @@
|
|||||||
本文作者JoeyDeVries,由[Django](http://bullteacher.com/16-light-casters.html)翻译自[http://learnopengl.com](http://www.learnopengl.com/#!Lighting/Light-casters)
|
本文作者JoeyDeVries,由[Django](http://bullteacher.com/16-light-casters.html)翻译自[http://learnopengl.com](http://www.learnopengl.com/#!Lighting/Light-casters)
|
||||||
|
|
||||||
|
#投光物
|
||||||
|
|
||||||
我们目前使用的所有光照都来自于一个单独的光源,这是空间中的一个点。它的效果不错,但是在真实世界,我们有多种类型的光,它们每个表现都不同。一个光源把光投射到物体上,叫做投光。这个教程里我们讨论几种不同的投光类型。学习模拟不同的光源是你未来丰富你的场景的另一个工具。
|
我们目前使用的所有光照都来自于一个单独的光源,这是空间中的一个点。它的效果不错,但是在真实世界,我们有多种类型的光,它们每个表现都不同。一个光源把光投射到物体上,叫做投光。这个教程里我们讨论几种不同的投光类型。学习模拟不同的光源是你未来丰富你的场景的另一个工具。
|
||||||
|
|
||||||
我们首先讨论定向光(directional light),接着是作为之前学到知识的扩展的点光(point light),最后我们讨论聚光灯(spot light)。下面的教程我们会把这几种不同的光类型整合到一个场景中。
|
我们首先讨论定向光(directional light),接着是作为之前学到知识的扩展的点光(point light),最后我们讨论聚光灯(spot light)。下面的教程我们会把这几种不同的光类型整合到一个场景中。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##16.1 定向光
|
## 定向光
|
||||||
|
|
||||||
当一个光源很远的时候,来自光源的每条光线接近于平行。这看起来就像所有的光线来自于同一个方向,无论物体和观察者在哪儿。当一个光源被设置为无限远时,它被称为定向光,因为所有的光线都有着同一个方向;它会独立于光源的位置。
|
当一个光源很远的时候,来自光源的每条光线接近于平行。这看起来就像所有的光线来自于同一个方向,无论物体和观察者在哪儿。当一个光源被设置为无限远时,它被称为定向光,因为所有的光线都有着同一个方向;它会独立于光源的位置。
|
||||||
|
|
||||||
@@ -94,7 +96,7 @@ else if(lightVector.w == 1.0)
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
在这里I是当前片段的光的亮度,d代表片段到光源的距离。为了计算衰减值,我们定义3个项:常数项Kc,一次项Kl和二次项Kq。
|
在这里是当前片段的光的亮度,代表片段到光源的距离。为了计算衰减值,我们定义3个项:常数项,一次项和二次项。
|
||||||
|
|
||||||
常数项通常是1.0,它的作用是保证坟墓永远不会比1小,因为它可以利用一定的距离增加亮度,这个结果不会影响到我们所寻找的。
|
常数项通常是1.0,它的作用是保证坟墓永远不会比1小,因为它可以利用一定的距离增加亮度,这个结果不会影响到我们所寻找的。
|
||||||
一次项用于与距离值相称,这回以线性的方式减少亮度。
|
一次项用于与距离值相称,这回以线性的方式减少亮度。
|
||||||
@@ -110,89 +112,22 @@ else if(lightVector.w == 1.0)
|
|||||||
###16.3.1 选择正确的值
|
###16.3.1 选择正确的值
|
||||||
|
|
||||||
但是,我们把这三个项设置为什么值呢?正确的值的设置由很多因素决定:环境、你希望光所覆盖的距离范围、光的类型等。大多数场合,这是经验的问题,也要适度调整。下面的表格展示一些各项的值,它们模拟现实(某种类型的)光源,覆盖特定的半径(距离)。第一蓝定义一个光的距离,它覆盖所给定的项。这些值是大多数光的良好开始,它是来自Ogre3D的维基的礼物:
|
但是,我们把这三个项设置为什么值呢?正确的值的设置由很多因素决定:环境、你希望光所覆盖的距离范围、光的类型等。大多数场合,这是经验的问题,也要适度调整。下面的表格展示一些各项的值,它们模拟现实(某种类型的)光源,覆盖特定的半径(距离)。第一蓝定义一个光的距离,它覆盖所给定的项。这些值是大多数光的良好开始,它是来自Ogre3D的维基的礼物:
|
||||||
<table>
|
|
||||||
<tbody>
|
Distance|Constant|Linear|Quadratic
|
||||||
<tr>
|
-------|------|-----|------
|
||||||
<td width="50"><b>Distance</b></td>
|
7|1.0|0.7|1.8
|
||||||
<td width="52"><b>Constant</b></td>
|
13|1.0|0.35|0.44
|
||||||
<td width="40"><b>Linear</b></td>
|
20|1.0|0.22|0.20
|
||||||
<td width="56"><b>Quadratic</b></td>
|
32|1.0|0.14|0.07
|
||||||
</tr>
|
50|1.0|0.09|0.032
|
||||||
<tr>
|
65|1.0|0.07|0.017
|
||||||
<td width="50">7</td>
|
100|1.0|0.045|0.0075
|
||||||
<td width="52">1.0</td>
|
160|1.0|0.027|0.0028
|
||||||
<td width="40">0.7</td>
|
200|1.0|0.022|0.0019
|
||||||
<td width="56">1.8</td>
|
325|1.0|0.014|0.0007
|
||||||
</tr>
|
600|1.0|0.007|0.0002
|
||||||
<tr>
|
3250|1.0|0.0014|0.000007
|
||||||
<td width="50">13</td>
|
就像你所看到的,常数项一直都是1.0。一次项为了覆盖更远的距离通常很小,二次项就更小了。尝试用这些值进行实验,看看它们在你的实现中各自的效果。我们的环境中,32到100的距离对大多数光通常就足够了。
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.35</td>
|
|
||||||
<td width="56">0.44</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">20</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.22</td>
|
|
||||||
<td width="56">0.20</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">32</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.14</td>
|
|
||||||
<td width="56">0.07</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">50</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.09</td>
|
|
||||||
<td width="56">0.032</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">65</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.07</td>
|
|
||||||
<td width="56">0.017</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">100</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.045</td>
|
|
||||||
<td width="56">0.0075</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">160</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.027</td>
|
|
||||||
<td width="56">0.0028</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">200</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.022</td>
|
|
||||||
<td width="56">0.0019</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">325</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.014</td>
|
|
||||||
<td width="56">0.0007</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">600</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.007</td>
|
|
||||||
<td width="56">0.0002</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="50">3250</td>
|
|
||||||
<td width="52">1.0</td>
|
|
||||||
<td width="40">0.0014</td>
|
|
||||||
<td width="56">0.000007</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
就像你所看到的,常数项Kc一直都是1.0。一次项Kl为了覆盖更远的距离通常很小,二次项Kq就更小了。尝试用这些值进行实验,看看它们在你的实现中各自的效果。我们的环境中,32到100的距离对大多数光通常就足够了。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -316,94 +251,21 @@ color = vec4(light.ambient*vec3(texture(material.diffuse,TexCoords)), 1.0f);
|
|||||||
为创建外圆锥,我们简单定义另一个余弦值,它代表聚光灯的方向向量和外圆锥的向量(等于它的半径)的角度。然后,如果片段在内圆锥和外圆锥之间,就会给它计算出一个0.0到1.0之间的亮度。如果片段在内圆锥以内这个亮度就等于1.0,如果在外面就是0.0。
|
为创建外圆锥,我们简单定义另一个余弦值,它代表聚光灯的方向向量和外圆锥的向量(等于它的半径)的角度。然后,如果片段在内圆锥和外圆锥之间,就会给它计算出一个0.0到1.0之间的亮度。如果片段在内圆锥以内这个亮度就等于1.0,如果在外面就是0.0。
|
||||||
|
|
||||||
我们可以使用下面的公式计算这样的值:
|
我们可以使用下面的公式计算这样的值:
|
||||||
[math]
|

|
||||||
这里ε是内部(φ)和外部圆锥[math]的差。结果I的值是聚光灯在当前片段的亮度。
|
这里是内部()和外部圆锥()的差。结果I的值是聚光灯在当前片段的亮度。
|
||||||
|
|
||||||
很难用图画描述出这个公式是怎样工作的,所以我们尝试使用一个例子:
|
很难用图画描述出这个公式是怎样工作的,所以我们尝试使用一个例子:
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
θ|θ in degrees|φ (inner cutoff)|φ in degrees|γ (outer cutoff)|γ in degrees|ε|l
|
||||||
<td width="36">θ</td>
|
--|---|---|---|---|---|---|---
|
||||||
<td width="60">θ<b>in </b><b>degrees</b></td>
|
0.87|30|0.91|25|0.82|35|0.91 - 0.82 = 0.09|0.87 - 0.82 / 0.09 = 0.56
|
||||||
<td width="68">φ<b>(inner </b><b>cutoff)</b></td>
|
0.9|26|0.91|25|0.82|35|0.91 - 0.82 = 0.09|0.9 - 0.82 / 0.09 = 0.89
|
||||||
<td width="61">φ<b>in </b><b>degrees</b></td>
|
0.97|14|0.91|25|0.82|35|0.91 - 0.82 = 0.09|0.97 - 0.82 / 0.09 = 1.67
|
||||||
<td width="67">γ<b>(outer </b><b>cutoff)</b></td>
|
0.97|14|0.91|25|0.82|35|0.91 - 0.82 = 0.09|0.97 - 0.82 / 0.09 = 1.67
|
||||||
<td width="60">γ<b>in </b><b>degrees</b></td>
|
0.83|34|0.91|25|0.82|35|0.91 - 0.82 = 0.09|0.83 - 0.82 / 0.09 = 0.11
|
||||||
<td width="94">ε</td>
|
0.64|50|0.91|25|0.82|35|0.91 - 0.82 = 0.09|0.64 - 0.82 / 0.09 = -2.0
|
||||||
<td width="115"><i>I</i></td>
|
0.966|15|0.9978|12.5|0.953|17.5|0.966 - 0.953 = 0.0448|0.966 - 0.953 / 0.0448 = 0.29
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="36">0.87</td>
|
|
||||||
<td width="60">30</td>
|
|
||||||
<td width="68">0.91</td>
|
|
||||||
<td width="61">25</td>
|
|
||||||
<td width="67">0.82</td>
|
|
||||||
<td width="60">35</td>
|
|
||||||
<td width="94">0.91 – 0.82 = 0.09</td>
|
|
||||||
<td width="115">0.87 – 0.82 / 0.09 = 0.56</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="36">0.9</td>
|
|
||||||
<td width="60">26</td>
|
|
||||||
<td width="68">0.91</td>
|
|
||||||
<td width="61">25</td>
|
|
||||||
<td width="67">0.82</td>
|
|
||||||
<td width="60">35</td>
|
|
||||||
<td width="94">0.91 – 0.82 = 0.09</td>
|
|
||||||
<td width="115">0.9 – 0.82 / 0.09 = 0.89</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="36">0.97</td>
|
|
||||||
<td width="60">14</td>
|
|
||||||
<td width="68">0.91</td>
|
|
||||||
<td width="61">25</td>
|
|
||||||
<td width="67">0.82</td>
|
|
||||||
<td width="60">35</td>
|
|
||||||
<td width="94">0.91 – 0.82 = 0.09</td>
|
|
||||||
<td width="115">0.97 – 0.82 / 0.09 = 1.67</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="36">0.97</td>
|
|
||||||
<td width="60">14</td>
|
|
||||||
<td width="68">0.91</td>
|
|
||||||
<td width="61">25</td>
|
|
||||||
<td width="67">0.82</td>
|
|
||||||
<td width="60">35</td>
|
|
||||||
<td width="94">0.91 – 0.82 = 0.09</td>
|
|
||||||
<td width="115">0.97 – 0.82 / 0.09 = 1.67</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="36">0.83</td>
|
|
||||||
<td width="60">34</td>
|
|
||||||
<td width="68">0.91</td>
|
|
||||||
<td width="61">25</td>
|
|
||||||
<td width="67">0.82</td>
|
|
||||||
<td width="60">35</td>
|
|
||||||
<td width="94">0.91 – 0.82 = 0.09</td>
|
|
||||||
<td width="115">0.83 – 0.82 / 0.09 = 0.11</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="36">0.64</td>
|
|
||||||
<td width="60">50</td>
|
|
||||||
<td width="68">0.91</td>
|
|
||||||
<td width="61">25</td>
|
|
||||||
<td width="67">0.82</td>
|
|
||||||
<td width="60">35</td>
|
|
||||||
<td width="94">0.91 – 0.82 = 0.09</td>
|
|
||||||
<td width="115">0.64 – 0.82 / 0.09 = -2.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="36">0.966</td>
|
|
||||||
<td width="60">15</td>
|
|
||||||
<td width="68">0.9978</td>
|
|
||||||
<td width="61">12.5</td>
|
|
||||||
<td width="67">0.953</td>
|
|
||||||
<td width="60">17.5</td>
|
|
||||||
<td width="94">0.966 – 0.953 = 0.0448</td>
|
|
||||||
<td width="115">0.966 – 0.953 / 0.0448 = 0.29</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
就像你看到的那样我们基本是根据θ在外余弦和内余弦之间插值。如果你仍然不明白怎么继续,不要担心。你可以简单的使用这个公式计算,当你更加老道和明白的时候再来看。
|
就像你看到的那样我们基本是根据θ在外余弦和内余弦之间插值。如果你仍然不明白怎么继续,不要担心。你可以简单的使用这个公式计算,当你更加老道和明白的时候再来看。
|
||||||
|
|
||||||
由于我们现在有了一个亮度值,当在聚光灯外的时候是个负的,当在内部圆锥以内大于1。如果我们适当地把这个值固定,我们在像素着色器中就再不需要if-else了,我们可以简单地用计算出的亮度值乘以光的元素:
|
由于我们现在有了一个亮度值,当在聚光灯外的时候是个负的,当在内部圆锥以内大于1。如果我们适当地把这个值固定,我们在像素着色器中就再不需要if-else了,我们可以简单地用计算出的亮度值乘以光的元素:
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
本文作者JoeyDeVries,由Meow J翻译自[http://learnopengl.com](http://learnopengl.com/#!Getting-started/Shaders)
|
本文作者JoeyDeVries,由Meow J翻译自[http://learnopengl.com](http://learnopengl.com/#!Advanced-Lighting/HDR)
|
||||||
|
|
||||||
## HDR
|
## HDR
|
||||||
|
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
本文作者JoeyDeVries,由Meow J翻译自[http://learnopengl.com](http://learnopengl.com/#!Getting-started/Shaders)
|
|
||||||
|
|
||||||
## 泛光(Bloom)
|
|
||||||
|
|
||||||
#WIP
|
|
BIN
img/Kc.png
Normal file
After Width: | Height: | Size: 576 B |
BIN
img/Kl.png
Normal file
After Width: | Height: | Size: 574 B |
BIN
img/Kq.png
Normal file
After Width: | Height: | Size: 612 B |
BIN
img/Light_casters2.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
img/Light_casters3.png
Normal file
After Width: | Height: | Size: 887 B |
BIN
img/epsilon.png
Normal file
After Width: | Height: | Size: 461 B |
BIN
img/gamma.png
Normal file
After Width: | Height: | Size: 460 B |
BIN
img/phi.png
Normal file
After Width: | Height: | Size: 502 B |
BIN
img/theta.png
Normal file
After Width: | Height: | Size: 487 B |
@@ -11,26 +11,31 @@ GLSL是写法类似C语言,GLSL是专门针对图形以及向量和矩阵变
|
|||||||
|
|
||||||
|
|
||||||
着色器通常具有以下结构:
|
着色器通常具有以下结构:
|
||||||
|
```c++
|
||||||
|
#version version_number
|
||||||
|
|
||||||
|
in type in_variable_name;
|
||||||
|
in type in_variable_name;
|
||||||
|
|
||||||
#version version_number
|
out type out_variable_name;
|
||||||
in type in_variable_name;
|
|
||||||
in type in_variable_name;
|
uniform type uniform_name;
|
||||||
6.2 Types 52
|
|
||||||
out type out_variable_name;
|
int main()
|
||||||
uniform type uniform_name;
|
{
|
||||||
int main()
|
// Process input(s) and do some weird graphics stuff
|
||||||
{
|
...
|
||||||
// Process input(s) and do some weird graphics stuff
|
// Output processed stuff to output variable
|
||||||
...
|
out_variable_name = weird_stuff_we_processed;
|
||||||
// Output processed stuff to output variable
|
}
|
||||||
out_variable_name = weird_stuff_we_processed;
|
```
|
||||||
}
|
|
||||||
|
|
||||||
所谓的顶点着色器就讲顶点属性作为输入的着色器,顶点属性的个数主要受限于硬件实现,OpenGL的保证总有至少16个四分量的顶点可以使用,但是硬件可能个多些,可以通过查询:**GL_MAX_VERTEX_ATTRIBS**
|
所谓的顶点着色器就讲顶点属性作为输入的着色器,顶点属性的个数主要受限于硬件实现,OpenGL的保证总有至少16个四分量的顶点可以使用,但是硬件可能个多些,可以通过查询:**GL_MAX_VERTEX_ATTRIBS**
|
||||||
|
```c++
|
||||||
GLint nrAttributes;
|
GLint nrAttributes;
|
||||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
|
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
|
||||||
std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;
|
std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;
|
||||||
|
```
|
||||||
|
|
||||||
这个结果最小返回16,一般情况下使用。
|
这个结果最小返回16,一般情况下使用。
|
||||||
|
|
||||||
@@ -52,49 +57,58 @@ GLSL跟一般的编程语言一样,定义了一些常用的数据类型,基
|
|||||||
大多数情况下我们使用vecn,因为浮点型足够满足我们大多数需求。
|
大多数情况下我们使用vecn,因为浮点型足够满足我们大多数需求。
|
||||||
向量的分量可以通过vec.x来访问第一个分量,同时可以使用.x,.y,.z,.w来访问一个向量的四个成员,同样可以使用rgba来访问颜色值对应的向量,纹理坐标则可以使用stpq来访问分量的值。
|
向量的分量可以通过vec.x来访问第一个分量,同时可以使用.x,.y,.z,.w来访问一个向量的四个成员,同样可以使用rgba来访问颜色值对应的向量,纹理坐标则可以使用stpq来访问分量的值。
|
||||||
向量的访问方式支持趣味性和扩展性,被称为交叉混合性,实例如下:
|
向量的访问方式支持趣味性和扩展性,被称为交叉混合性,实例如下:
|
||||||
|
```c++
|
||||||
vec2 someVec;
|
vec2 someVec;
|
||||||
vec4 differentVec = someVec.xyxx;
|
vec4 differentVec = someVec.xyxx;
|
||||||
vec3 anotherVec = differentVec.zyw;
|
vec3 anotherVec = differentVec.zyw;
|
||||||
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
|
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
|
||||||
|
```
|
||||||
可以使用任意组合来组成新向量,同时也可以把维度小的向量放在高纬度向量的构造函数里来构成新的向量。如下代码:
|
可以使用任意组合来组成新向量,同时也可以把维度小的向量放在高纬度向量的构造函数里来构成新的向量。如下代码:
|
||||||
|
```c++
|
||||||
vec2 vect = vec2(0.5f, 0.7f);
|
vec2 vect = vec2(0.5f, 0.7f);
|
||||||
vec4 result = vec4(vect, 0.0f, 0.0f);
|
vec4 result = vec4(vect, 0.0f, 0.0f);
|
||||||
vec4 otherResult = vec4(result.xyz, 1.0f);
|
vec4 otherResult = vec4(result.xyz, 1.0f);
|
||||||
|
```
|
||||||
###输入和输出
|
###输入和输出
|
||||||
着色器是运行在GPU上的小程序,但是麻雀虽小五脏俱全,也会有输入和输出来构成完整的程序,GLSL使用in和out关键字来定义输入和输出。每个着色器可以是这些关键字来指定输入和输出,输入变量经过处理以后会得到适合下个处理阶段可以使用的输出变量,顶点着色器和片段着色器有点小却别。
|
着色器是运行在GPU上的小程序,但是麻雀虽小五脏俱全,也会有输入和输出来构成完整的程序,GLSL使用in和out关键字来定义输入和输出。每个着色器可以是这些关键字来指定输入和输出,输入变量经过处理以后会得到适合下个处理阶段可以使用的输出变量,顶点着色器和片段着色器有点小却别。
|
||||||
|
|
||||||
顶点着色器接受特定格式的输入,否则不能正确使用。顶点着色器直接接受输入的顶点数据,但是需要在CPU一边指定数据的对应的位置,前面的教程可以到对位置0的输入(location=0),所以顶点着色器需要一个特定的声明来确定CPU和GPU数据对应关联关系,
|
顶点着色器接受特定格式的输入,否则不能正确使用。顶点着色器直接接受输入的顶点数据,但是需要在CPU一边指定数据的对应的位置,前面的教程可以到对位置0的输入(location=0),所以顶点着色器需要一个特定的声明来确定CPU和GPU数据对应关联关系,
|
||||||
|
|
||||||
也可以使用*glGetAttribLocation*来查询对应的位置,这样可以省略layout的声明,但是我觉得可以是用layout声明比较好,这也可以减少GPU的一些工作
|
<div style="border:solid #AFDFAF;border-radius:5px;background-color:#D8F5D8;margin:20px 20px 20px 0px;padding:15px">
|
||||||
|
也可以使用*glGetAttribLocation*来查询对应的位置,这样可以省略layout的声明,但是我觉得可以是用layout声明比较好,这也可以减少GPU的一些工作
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
对于片段着色器有个vec4的颜色作为特定的输出,因为片段处理后最终是要生产一个颜色来显示的。否则将输出黑色或白色颜色作为输出。
|
对于片段着色器有个vec4的颜色作为特定的输出,因为片段处理后最终是要生产一个颜色来显示的。否则将输出黑色或白色颜色作为输出。
|
||||||
|
|
||||||
如果我们想从一个着色器向另外一个发送数据,我们需要在发送方定义一个输出,然后再接收方顶一个输入,同时保证这两个变量类型和名字是相同的。
|
如果我们想从一个着色器向另外一个发送数据,我们需要在发送方定义一个输出,然后再接收方顶一个输入,同时保证这两个变量类型和名字是相同的。
|
||||||
下面是一个实例来展示如何从顶点着色器传递一个颜色值跟片段着色器使用:
|
下面是一个实例来展示如何从顶点着色器传递一个颜色值跟片段着色器使用:
|
||||||
|
|
||||||
***顶点着色器***
|
***顶点着色器***
|
||||||
|
```c++
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 position; // The position variable has attribute position 0
|
||||||
|
|
||||||
|
out vec4 vertexColor; // Specify a color output to the fragment shader
|
||||||
|
|
||||||
#version 330 core
|
void main()
|
||||||
layout (location = 0) in vec3 position; // The position variable has attribute position 0
|
{
|
||||||
out vec4 vertexColor; // Specify a color output to the fragment shader
|
gl_Position = vec4(position, 1.0); // See how we directly give a vec3 to vec4's constructor
|
||||||
void main()
|
vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f); // Set the output variable to a dark-red color
|
||||||
{
|
}
|
||||||
gl_Position = vec4(position, 1.0);
|
```
|
||||||
vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
***片段着色器***
|
***片段着色器***
|
||||||
|
```c++
|
||||||
|
#version 330 core
|
||||||
|
in vec4 vertexColor; // The input variable from the vertex shader (same name and same type)
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
#version 330 core
|
void main()
|
||||||
in vec4 vertexColor; // 从顶点着色器获得输入 (名字和类型都是一样的)
|
{
|
||||||
out vec4 color;
|
color = vertexColor;
|
||||||
void main()
|
}
|
||||||
{
|
```
|
||||||
color = vertexColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
可以看到在顶点着色器生命了一个向量:*vertexColor* 有out修饰,同时在片段着色器声明了一个*vertexColor* 使用in来修饰,这样片段着色器就可以获取顶点着色器处理的*vertexColor*的结果了。
|
可以看到在顶点着色器生命了一个向量:*vertexColor* 有out修饰,同时在片段着色器声明了一个*vertexColor* 使用in来修饰,这样片段着色器就可以获取顶点着色器处理的*vertexColor*的结果了。
|
||||||
根据上面shader,可以得出下图的效果:
|
根据上面shader,可以得出下图的效果:
|
||||||
|
|
||||||
@@ -109,26 +123,30 @@ GLSL跟一般的编程语言一样,定义了一些常用的数据类型,基
|
|||||||
2.不变性,一旦设置了值,在渲染过程中就不能被改变,只有从新设置才能改变。
|
2.不变性,一旦设置了值,在渲染过程中就不能被改变,只有从新设置才能改变。
|
||||||
|
|
||||||
声明常量非常简单使用uniform 放在类型和变量名前面即可。下面看一个例子:
|
声明常量非常简单使用uniform 放在类型和变量名前面即可。下面看一个例子:
|
||||||
|
```c++
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform vec4 ourColor; // We set this variable in the OpenGL code.
|
||||||
|
|
||||||
#version 330 core
|
void main()
|
||||||
out vec4 color;
|
{
|
||||||
uniform vec4 ourColor; //
|
color = ourColor;
|
||||||
code.
|
}
|
||||||
void main()
|
```
|
||||||
{
|
|
||||||
color = ourColor;
|
|
||||||
}
|
|
||||||
声明了一个ourColor为常量类型,然后把它的值付给了输出变量color。
|
声明了一个ourColor为常量类型,然后把它的值付给了输出变量color。
|
||||||
|
<div style="border:solid #E1B3B3;border-radius:10px;background-color:#FFD2D2;margin:10px 10px 10px 0px;padding:10px">
|
||||||
注意:如果声明了一个从来没用到常量,GLSL的编译器会默认删除这个常量,由此可能导致一些莫名的问题。
|
注意:如果声明了一个从来没用到常量,GLSL的编译器会默认删除这个常量,由此可能导致一些莫名的问题。
|
||||||
|
</div>
|
||||||
现在这个常量还是个空值,接下来给ourColor在CPU端传递数据给它。思路:获取ourColor在索引位置,然后传递数据给这个位置。另外做一些小动作,不传递固定的这个,传递一个随时间变化的值,如下:
|
现在这个常量还是个空值,接下来给ourColor在CPU端传递数据给它。思路:获取ourColor在索引位置,然后传递数据给这个位置。另外做一些小动作,不传递固定的这个,传递一个随时间变化的值,如下:
|
||||||
|
```c++
|
||||||
GLfloat timeValue = glfwGetTime();
|
GLfloat timeValue = glfwGetTime();
|
||||||
GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
|
GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
|
||||||
GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
|
GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
|
||||||
glUseProgram(shaderProgram);
|
glUseProgram(shaderProgram);
|
||||||
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
|
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
|
||||||
|
```
|
||||||
首先通过glfwGetTime函数获取程序运行时间(秒数)。然后使用sin函数将greenValue的值控制在0-1。
|
首先通过glfwGetTime函数获取程序运行时间(秒数)。然后使用sin函数将greenValue的值控制在0-1。
|
||||||
|
|
||||||
然后使用glGetUniformLocation函数查询ourColor的索引位置。是一个参数是要查询的着色器程序,第二个参数是常量在着色器中声明的变量名。如果glGetUniformLocation函数返回-1,表明没找到对应的常量的索引位置。
|
然后使用glGetUniformLocation函数查询ourColor的索引位置。是一个参数是要查询的着色器程序,第二个参数是常量在着色器中声明的变量名。如果glGetUniformLocation函数返回-1,表明没找到对应的常量的索引位置。
|
||||||
@@ -137,29 +155,32 @@ GLSL跟一般的编程语言一样,定义了一些常用的数据类型,基
|
|||||||
|
|
||||||
注意:使用glGetUniformLocation 不需要在glUseProgram之后,但是glUniform4f一定要在lUseProgram之后,因为我们也只能对当前激活的着色器程序传递数据。
|
注意:使用glGetUniformLocation 不需要在glUseProgram之后,但是glUniform4f一定要在lUseProgram之后,因为我们也只能对当前激活的着色器程序传递数据。
|
||||||
到目前为止已经学会了这么给常量传递数据和渲染使用这些数据,如果我们想每帧改变常量的值,我们需要在主循环的不停的计算和更新常量的值。
|
到目前为止已经学会了这么给常量传递数据和渲染使用这些数据,如果我们想每帧改变常量的值,我们需要在主循环的不停的计算和更新常量的值。
|
||||||
|
```c++
|
||||||
|
while(!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
// Check and call events
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
while(!glfwWindowShouldClose(window))
|
// Render
|
||||||
{
|
// Clear the colorbuffer
|
||||||
// Check and call events
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
glfwPollEvents();
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
// Render
|
|
||||||
// Clear the colorbuffer
|
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
// Be sure to activate the shader
|
|
||||||
glUseProgram(shaderProgram);
|
|
||||||
// Update the uniform color
|
|
||||||
GLfloat timeValue = glfwGetTime();
|
|
||||||
GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
|
|
||||||
GLint vertexColorLocation = glGetUniformLocation(
|
|
||||||
shaderProgram, "ourColor");
|
|
||||||
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f,1.0f);
|
|
||||||
// Now draw the triangle
|
|
||||||
glBindVertexArray(VAO);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Be sure to activate the shader
|
||||||
|
glUseProgram(shaderProgram);
|
||||||
|
|
||||||
|
// Update the uniform color
|
||||||
|
GLfloat timeValue = glfwGetTime();
|
||||||
|
GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
|
||||||
|
GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
|
||||||
|
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Now draw the triangle
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
```
|
||||||
如果运行正常的话我们能看到一个绿色到黑色,黑色到绿色变化的三角形,
|
如果运行正常的话我们能看到一个绿色到黑色,黑色到绿色变化的三角形,
|
||||||
可以查看完整的代码[实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-interpolated)
|
可以查看完整的代码[实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-interpolated)
|
||||||
|
|
||||||
@@ -169,114 +190,124 @@ GLSL跟一般的编程语言一样,定义了一些常用的数据类型,基
|
|||||||
编写、编译和管理着色器程序是非常繁重的工作,为了减轻这个工作量我们自己定义一个着色器程序管理器,负责读取着色器程序文件,然后编译他们,链接并检查着色器程序有无错误发生。这也可以让我们把已经学到的知识封装到抽象的对象里。
|
编写、编译和管理着色器程序是非常繁重的工作,为了减轻这个工作量我们自己定义一个着色器程序管理器,负责读取着色器程序文件,然后编译他们,链接并检查着色器程序有无错误发生。这也可以让我们把已经学到的知识封装到抽象的对象里。
|
||||||
|
|
||||||
我们首先顶一个着色器程序的头文件,如下:
|
我们首先顶一个着色器程序的头文件,如下:
|
||||||
|
```c++
|
||||||
|
#ifndef SHADER_H
|
||||||
|
#define SHADER_H
|
||||||
|
|
||||||
#ifndef SHADER_H
|
#include <string>
|
||||||
#define SHADER_H
|
#include <fstream>
|
||||||
#include <string>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <iostream>
|
||||||
#include <sstream>
|
using namespace std;
|
||||||
#include <iostream>
|
|
||||||
using namespace std;
|
#include <GL/glew.h>; // Include glew to get all the required OpenGL headers
|
||||||
#include <GL/glew.h>; // Include glew to get all the required
|
|
||||||
OpenGL headers
|
class Shader
|
||||||
class Shader
|
{
|
||||||
{
|
public:
|
||||||
public:
|
// The program ID
|
||||||
// The program ID
|
|
||||||
GLuint Program;
|
GLuint Program;
|
||||||
// Constructor reads and builds the shader
|
// Constructor reads and builds the shader
|
||||||
Shader(const GLchar* vertexSourcePath, const GLchar*fragmentSourcePath);
|
Shader(const GLchar* vertexSourcePath, const GLchar* fragmentSourcePath);
|
||||||
// Use the program
|
// Use the program
|
||||||
void Use();
|
void Use();
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
#endif
|
||||||
|
```
|
||||||
着色器程序类包含一个着色器程序ID,有一个接受顶点和片段程序的接口,这个两个路径就是普通的文本文件就可以了。
|
着色器程序类包含一个着色器程序ID,有一个接受顶点和片段程序的接口,这个两个路径就是普通的文本文件就可以了。
|
||||||
Use函数是一个工具属性的函数,主要是控制当前着色器程序是否激活。
|
Use函数是一个工具属性的函数,主要是控制当前着色器程序是否激活。
|
||||||
|
|
||||||
读取着色器程序文件
|
读取着色器程序文件
|
||||||
|
```c++
|
||||||
Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
|
Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
|
||||||
{
|
{
|
||||||
// 1. Retrieve the vertex/fragment source code from
|
// 1. Retrieve the vertex/fragment source code from filePath
|
||||||
filePath
|
std::string vertexCode;
|
||||||
std::string vertexCode;
|
std::string fragmentCode;
|
||||||
std::string fragmentCode;
|
std::ifstream vShaderFile;
|
||||||
try
|
std::ifstream fShaderFile;
|
||||||
{
|
// ensures ifstream objects can throw exceptions:
|
||||||
// Open files
|
vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||||
std::ifstream vShaderFile(vertexPath);
|
fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||||
std::ifstream fShaderFile(fragmentPath);
|
try
|
||||||
std::stringstream vShaderStream, fShaderStream;
|
{
|
||||||
// Read file’s buffer contents into streams
|
// Open files
|
||||||
vShaderStream << vShaderFile.rdbuf();
|
vShaderFile.open(vertexPath);
|
||||||
fShaderStream << fShaderFile.rdbuf();
|
fShaderFile.open(fragmentPath);
|
||||||
// close file handlers
|
std::stringstream vShaderStream, fShaderStream;
|
||||||
vShaderFile.close();
|
// Read file's buffer contents into streams
|
||||||
fShaderFile.close();
|
vShaderStream << vShaderFile.rdbuf();
|
||||||
// Convert stream into GLchar array
|
fShaderStream << fShaderFile.rdbuf();
|
||||||
vertexCode = vShaderStream.str();
|
// close file handlers
|
||||||
fragmentCode = fShaderStream.str();
|
vShaderFile.close();
|
||||||
}
|
fShaderFile.close();
|
||||||
catch(std::exception e)
|
// Convert stream into GLchar array
|
||||||
{
|
vertexCode = vShaderStream.str();
|
||||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" <<
|
fragmentCode = fShaderStream.str();
|
||||||
std::endl;
|
}
|
||||||
}
|
catch(std::ifstream::failure e)
|
||||||
|
{
|
||||||
|
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
||||||
|
}
|
||||||
|
const GLchar* vShaderCode = vertexCode.c_str();
|
||||||
|
const GLchar* fShaderCode = fragmentCode.c_str();
|
||||||
|
[...]
|
||||||
|
```
|
||||||
|
|
||||||
接下来编译和链接这些程序,同时收集一些编译和链接的错误,来帮助我们调试。
|
接下来编译和链接这些程序,同时收集一些编译和链接的错误,来帮助我们调试。
|
||||||
|
```c++
|
||||||
// 2. Compile shaders
|
// 2. Compile shaders
|
||||||
GLuint vertex, fragment;
|
GLuint vertex, fragment;
|
||||||
GLint success;
|
GLint success;
|
||||||
GLchar infoLog[512];
|
GLchar infoLog[512];
|
||||||
// Vertex Shader
|
|
||||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
// Vertex Shader
|
||||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glCompileShader(vertex);
|
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||||
// Print compile errors if any
|
glCompileShader(vertex);
|
||||||
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
// Print compile errors if any
|
||||||
if(!success)
|
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
||||||
{
|
if(!success)
|
||||||
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
|
{
|
||||||
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
|
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
|
||||||
<< infoLog << std::endl;
|
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||||
};
|
};
|
||||||
// Similiar for Fragment Shader
|
|
||||||
[...]
|
// Similiar for Fragment Shader
|
||||||
// Shader Program
|
[...]
|
||||||
this->Program = glCreateProgram();
|
|
||||||
glAttachShader(this->Program, vertex);
|
// Shader Program
|
||||||
glAttachShader(this->Program, fragment);
|
this->Program = glCreateProgram();
|
||||||
glLinkProgram(this->Program);
|
glAttachShader(this->Program, vertex);
|
||||||
// Print linking errors if any
|
glAttachShader(this->Program, fragment);
|
||||||
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
|
glLinkProgram(this->Program);
|
||||||
if(!success)
|
// Print linking errors if any
|
||||||
{
|
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
|
||||||
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
|
if(!success)
|
||||||
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" <<
|
{
|
||||||
infoLog << std::endl;
|
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
|
||||||
}
|
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
|
||||||
// Delete the shaders as they’re linked into our program now
|
}
|
||||||
and no longer necessery
|
|
||||||
glDeleteShader(vertex);
|
// Delete the shaders as they're linked into our program now and no longer necessery
|
||||||
glDeleteShader(fragment);
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
```
|
||||||
最后来实现一个use函数
|
最后来实现一个use函数
|
||||||
|
|
||||||
void Use() { glUseProgram(this->Program); }
|
void Use() { glUseProgram(this->Program); }
|
||||||
接下来是一个使用这个简单实例:
|
接下来是一个使用这个简单实例:
|
||||||
|
```c++
|
||||||
Shader ourShader("path/to/shaders/shader.vs", "path/to/shaders/shader.frag");
|
Shader ourShader("path/to/shaders/shader.vs", "path/to/shaders/shader.frag");
|
||||||
...
|
...
|
||||||
while(...)
|
while(...)
|
||||||
{
|
{
|
||||||
ourShader.Use();
|
ourShader.Use();
|
||||||
glUniform1f(glGetUniformLocation(ourShader.Program, "
|
glUniform1f(glGetUniformLocation(ourShader.Program, "someUniform"), 1.0f);
|
||||||
someUniform"), 1.0f);
|
DrawStuff();
|
||||||
DrawStuff();
|
}
|
||||||
}
|
```
|
||||||
上面我们已经把顶点着色器和片段着色器代码分别放在shader.vs和shader.frag里面了,这些文件的名字和后缀名都可以随意命名的,只要符合文件名规范就好。
|
上面我们已经把顶点着色器和片段着色器代码分别放在shader.vs和shader.frag里面了,这些文件的名字和后缀名都可以随意命名的,只要符合文件名规范就好。
|
||||||
完整的代码实例:
|
完整的代码实例:
|
||||||
|
|
11
old/05/07 Bloom.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
本文作者JoeyDeVries,由Meow J翻译自[http://learnopengl.com](http://learnopengl.com/#!Advanced-Lighting/Bloom)
|
||||||
|
|
||||||
|
## 泛光(Bloom)
|
||||||
|
|
||||||
|
亮光源与被光照区域常常很难传达给观众,因为显示器的光强度范围是受限制的. 其中一个解决方案是让这些光源泛光(Glow)从而区分亮光源: 让光漏(bleed)出光源. 这有效让观众感觉到光源和光照区域非常的亮.
|
||||||
|
|
||||||
|
光的是通过一个后期处理效果叫做泛光(Bloom)来完成的. 泛光让所有光照地区一种在发光的效果.下面两个场景就是有泛光(右)与无泛光(左)的区别(图像来自于虚幻引擎(Unreal)):
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
泛光提供了对于物体亮度显眼的视觉暗示,因为泛光能给我们物体真的是很亮的视觉效果. 如果我们能够很好的完成它(有一些游戏实现的很糟糕),泛光将能很大程度的加强我们场景的光照效果,并且也能给我们很多特效.
|