現實世界的物體各種各樣,不同物體會對光產生不同的反應。陶瓷,鐵片之類的物體會比牆壁,木櫃的反射更強。想要模擬現實世界的光照效果就要了解物體對光線的反應效果。在我們的着色器代碼中,我們定義一個結構體:Material,來表示材質。在上一節中,我們指定了一個物體和光的顏色,以及結合環境光和鏡面強度分量,來定義物體的視覺輸出。當描述一個物體的時候,我們可以用這三個分量來定義一個材質顏色(Material Color):環境光照(Ambient Lighting)、漫反射光照(Diffuse Lighting)和鏡面光照(Specular Lighting),再加上反光度(Shininess)來表示物體對光線的反應。
// 定義材料結構體
struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
uniform Material material;
我們就可以自定義這些值來顯示不同的效果了,當然計算時也不是用光線顏色了,而是使用我們傳入的值,例如,
// 環境光照
vec3 ambient = lightColor * material.ambient;
傳入我們定義的值的方法,
int materialAmbientPosHandle = GLES20.glGetUniformLocation(shaderProgram, "material.ambient");
GLES20.glUniform3f(materialAmbientPosHandle, 1.0f, 0.5f, 0.31f);
我們看到查找索引時的參數是:對象名.屬性名。
下一步我們定義光源。光源的顏色不同照射到物體上,物體反射的光線也是不同的;物體反射的光線強弱也和光源的強弱有關。這裏我們同樣定義一個光源的結構體:Light。光源我們同樣定義三個:光源的環境光強度,光源的漫反射強度和鏡面光,再加上光源位置。代碼如下,
// 定義光源結構體
struct Light {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
這樣計算時不再使用光源的顏色而使用光源的屬性,
// 環境光照
vec3 ambient = material.ambient * light.ambient;
最後結合起來的效果就是光源顏色在不斷變化,物體的顏色也在不斷變化。
此章參考文檔https://learnopengl-cn.github.io/02%20Lighting/03%20Materials/,內容不難懂,主要學習動態傳入參數,不再貼代碼。源碼地址https://github.com/jklwan/OpenGLProject/blob/master/sample/src/main/java/com/chends/opengl/renderer/light/MaterialsRenderer.java