OpenGL ES 光照(二)
阿新 • • 發佈:2018-12-12
散射光(Diffuse):
從物體表面向全方位360度均勻反射的光,反射後的散射光在各個方向是均勻的,但反射光的反射強度與入射光的強度以及入射角度密切相關。垂直地照射到物體表面時比斜照時要亮。
散射光具體計算公式:
其中設光照入射角為α.
散射光照射結果=材質的反射係數×散射光強度×max(cosα,0)
實際開發分兩步計算
散射光最終強度=散射光強度×max(cosα,0)
散射光照射結果=材質的反射係數×散射光最終強度
入射角越大,反射強度越弱,當入射角的餘弦值為負值時(即入射角大於90度),反射強度為0。由於入射角是光向量與法向量的夾角,cosα= 規格化(光向量)·規格化(法向量)
頂點著色器
#version 300 es
uniform mat4 uMVPMatrix; //總變換矩陣
uniform mat4 uMMatrix; //變換矩陣(包括平移、旋轉、縮放)
uniform vec3 uLightLocation; //光源位置
in vec3 aPosition; //頂點位置
in vec3 aNormal; //頂點法向量
out vec3 vPosition; //用於傳遞給片元著色器的頂點位置
out vec4 vDiffuse; //用於傳遞給片元著色器的散射光分量
void pointLight ( //散射光光照計算的方法
in vec3 normal, //法向量
inout vec4 diffuse, //散射光計算結果
in vec3 lightLocation, //光源位置
in vec4 lightDiffuse //散射光強度
){
vec3 normalTarget=aPosition+normal; //計算變換後的法向量
vec3 newNormal=(uMMatrix*vec4(normalTarget,1)).xyz-(uMMatrix*vec4(aPosition,1)).xyz;
newNormal=normalize(newNormal); //對法向量規格化
//計算從表面點到光源位置的向量vp
vec3 vp= normalize(lightLocation-(uMMatrix*vec4(aPosition,1)).xyz);
vp=normalize(vp); //規格化vp
float nDotViewPosition=max(0.0,dot(newNormal,vp)); //求法向量與vp向量的點積與0的最大值
diffuse=lightDiffuse*nDotViewPosition; //計算散射光的最終強度
}
void main(){
gl_Position = uMVPMatrix * vec4(aPosition,1); //根據總變換矩陣計算此次繪製此頂點的位置
vec4 diffuseTemp=vec4(0.0,0.0,0.0,0.0);
pointLight(normalize(aNormal), diffuseTemp, uLightLocation, vec4(0.8,0.8,0.8,1.0));
vDiffuse=diffuseTemp; //將散射光最終強度傳給片元著色器
vPosition = aPosition; //將頂點的位置傳給片元著色器
}
片段著色器
#version 300 es
precision mediump float;
in vec3 vPosition;//接收從頂點著色器過來的頂點位置
in vec4 vDiffuse;//接收從頂點著色器過來的散射光最終強度
out vec4 fragColor;
void main()
{
//最終顏色
vec4 finalColor=vec4(物體顏色);
//根據散射光最終強度計算片元的最終顏色值
fragColor=finalColor*vDiffuse;
}