OpenGL ES 简单光照学习

参考书籍 OpenGL ES 2.0 游戏开发 上卷

材质的放射系数,在这里既是物体原本的颜色

环境光 P158
    环境光照射结果 = 材质的反射系数 * 环境光强度

散射光 p160
    散射光照结果 = 材质的反射系数 * 散射光强度 * Max(cos(入射角),0)    注意: 入射角 a*b = |a||b| * cos(入射角) 因为 |a| |b| 为单位向量,实际上,Max(a*b,0)
    实际开发中往往分两步进行计算,此时公式被拆解为如下情况
    散射光最终强度 = 散射光强度 * Max(cos(入射角),0)
    散射光照射结果 = 材质的反射 * 散射光最终强度

镜面光 p163
    镜面光与散射光不同,镜面光的最终强度还依赖于观察者的位置。
    镜面光照射结果 = 材质的反射系数 * 镜面光强度 * max(0,(cos(半向量与法向量的夹角)))

光照 可以在 顶点着色器中 进行计算,也可以在片元着色器中进行计算,由于片元着色器调用的次数更多,所以如果性能许可,在片元中计算光照,效果更佳细腻。

定位光与定向光
   1.定位光可以理解为光的方向不一,取决于光源的位置与照射点。
    2.定向光的方位唯一。

如果是定向光的话,应该是固定的唯一的。
   
   
vec3 vp= normalize(lightDirection); //lightDirection 由外部输入
vp=normalize(vp);//格式化vp

下面的代码即为 定位光,因为光源的方向不唯一,
   
   
vec3 vp= normalize(lightLocation-(uMMatrix*vec4(aPosition,1)).xyz);
vp=normalize(vp);//格式化vp


法向量的计算 点面法向量,面法向量

1.点面法向量 更适合 曲面物体
    法向量 为 面法向量的平均法向量
2.面法向量 适合菱角分明的 的物体
    认为该顶点属于某个面,该面的法向量,即是该顶点的法向量
疑惑:
    计算顶点法向量 为何是 aPosition + normal 然后再进行矩阵变换呢? aPosition+normal 代表了什么
    
  
  
uniform mat4 uMVPMatrix; //总变换矩阵
uniform mat4 uMMatrix; //变换矩阵
uniform vec3 uLightLocation;//光源位置
uniform vec3 uCamera; //摄像机位置
attribute vec3 aPosition; //顶点位置
attribute vec3 aNormal; //法向量
varying vec3 vPosition;//用于传递给片元着色器的顶点位置
varying vec4 vAmbient;//用于传递给片元着色器的环境光分量
varying vec4 vDiffuse;//用于传递给片元着色器的散射光分量
varying vec4 vSpecular;//用于传递给片元着色器的镜面反射光分量
//定位光光照计算的方法
void pointLight( //定位光光照计算的方法
in vec3 normal, //法向量
inout vec4 ambient, //环境光最终强度
inout vec4 diffuse, //散射光最终强度
inout vec4 specular, //镜面光最终强度
in vec3 lightLocation, //光源位置
in vec4 lightAmbient, //环境光强度
in vec4 lightDiffuse, //散射光强度
in vec4 lightSpecular //镜面光强度
){
ambient=lightAmbient; //直接得出环境光的最终强度
vec3 normalTarget=aPosition+normal; //计算变换后的法向量
vec3 newNormal=(uMMatrix*vec4(normalTarget,1)).xyz-(uMMatrix*vec4(aPosition,1)).xyz;
newNormal=normalize(newNormal); //对法向量规格化
//计算从表面点到摄像机的向量
vec3 eye= normalize(uCamera-(uMMatrix*vec4(aPosition,1)).xyz);
//计算从表面点到光源位置的向量vp
vec3 vp= normalize(lightLocation-(uMMatrix*vec4(aPosition,1)).xyz);
vp=normalize(vp);//格式化vp
vec3 halfVector=normalize(vp+eye); //求视线与光线的半向量
float shininess=50.0; //粗糙度,越小越光滑
float nDotViewPosition=max(0.0,dot(newNormal,vp)); //求法向量与vp的点积与0的最大值
diffuse=lightDiffuse*nDotViewPosition; //计算散射光的最终强度
float nDotViewHalfVector=dot(newNormal,halfVector); //法线与半向量的点积
float powerFactor=max(0.0,pow(nDotViewHalfVector,shininess)); //镜面反射光强度因子
specular=lightSpecular*powerFactor; //计算镜面光的最终强度
}
 
void main()
{
//根据总变换矩阵计算此次绘制此顶点位置
gl_Position = uMVPMatrix * vec4(aPosition,1);
vec4 ambientTemp=vec4(0.0,0.0,0.0,0.0);
vec4 diffuseTemp=vec4(0.0,0.0,0.0,0.0);
vec4 specularTemp=vec4(0.0,0.0,0.0,0.0);
pointLight(normalize(aNormal),ambientTemp,diffuseTemp,specularTemp,uLightLocation,vec4(0.15,0.15,0.15,1.0),vec4(0.8,0.8,0.8,1.0),vec4(0.7,0.7,0.7,1.0));
vAmbient=ambientTemp;
vDiffuse=diffuseTemp;
vSpecular=specularTemp;
//将顶点的位置传给片元着色器
vPosition = aPosition;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值