一、简单介绍
我们在着色器中使用光照来进行对物体颜色值的影响可以是逐个顶点进行的,当然也可以是逐个像素进行的,这样的操作基本都是直接将物体的基本的颜色值和光线的颜色和强度进行相乘,然后得到最终的颜色。这里就像简单的介绍下,如果我们物体有纹理了,怎么办?难道还是直接将纹理颜色和光线的颜色和强度直接相乘吗?
二、实战演练
我们在堆纹理表面进行光照的时候一定要考虑到的就是,我们这边使用的是ADS光照模型因为ADS光照模型的总强度是Ambient、Diffuse、和Specular的光照强度总和,所以这样就可以导致就很有可能造成每个颜色的通道的值经常是稍微大于1.0的。这样的话其实就好比我本来就有个纹理的颜色值,然后乘以1.0或者乘以比1.0稍微大点的,其实对这个纹理来说只是会得到和原来一样的纹理颜色。而不会有镜面的高光效果。
这里附上片元着色器中计算的代码,下面是在计算完所以光的影响之后,再去乘纹理的颜色。
vec4 vFragColor;
//环境光颜色
uniform vec4 ambientColor;
//镜面光颜色
uniform vec4 specularColor;
//漫反射的颜色
uniform vec4 diffuseColor;
//纹理采样器
uniform sampler2D colorMap;
//传递过来的视觉坐标下的法线
varying vec3 vVaryingNormal;
//传递过来的光源向量
varying vec3 vVaryingLightDir;
//传递过来的纹理坐标
varying vec2 vTexCoords;
void main()
{
//获取漫反射的光强度
float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
//将光照强度乘漫反射的颜色然后赋值给vFragColor,由vFragColor来计算最终的影响
vFragColor = diff * diffuseColor;
//添加环境光的颜色
vFragColor += ambientColor;
//vFragColor *= texture2D(colorMap,vTexCoords);
//我们基于观察方向vVaryingLightDir向量和物体的法线向量N计算出反射向量R
vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal)));
//下面都是计算镜面光的影响
float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));
if(diff != 0.0) {
float fSpec = pow(spec, 128.0);
//这里不需要让fSpec乘上镜面光的颜色是因为,这里就把镜面光的颜色看成是(1.0,1.0,1.0)
vFragColor.rgb += vec3(fSpec, fSpec, fSpec);
}
//在计算完镜面光的总和的时候,再去乘纹理的颜色
vFragColor *= texture2D(colorMap,vTexCoords);
gl_FragColor = vFragColor;
}
得到的效果如下所示,可以看到基本没有什么效果
但是如果我们把下面这行代码放在计算完漫反射光之后进行设置的话,那么就会得到了有镜面光的效果了
vFragColor *= texture2D(colorMap,vTexCoords);