gl_LightSource[n].position

如果你还是想使用固定功能管线的glLight*来设置光源的位置的话,需要改一下shader代码。GLSL提供了一个内置的变量gl_LightSource[n].position 其中n为第几个光源。改一下上面的shader.

#define FIX_FUNCTION 1
char vsChar[] = {  "#version 120\n"
  "uniform vec3 lightPos;\n"
  "void main(void)"
  "{"
  "  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
  "  vec3 N = normalize(gl_NormalMatrix * gl_Normal);"
  "  vec4 V = gl_ModelViewMatrix * gl_Vertex;"
  #if FIX_FUNCTION  
  " vec3 L = normalize(gl_LightSource[0].position.xyz - V.xyz);"
  #else
  "  vec3 L = normalize(lightPos - V.xyz);"
  #endif
  "  float NdotL = dot(N, L);"
  "  gl_FrontColor = gl_Color * vec4(max(0.0, NdotL));"
  "}"};
  
  void SetupRC()
{
...
#if FIX_FUNCTION
  glLightfv(GL_LIGHT0, GL_POSITION, g_lightPos);
  #else
  lightPosLocation = glGetUniformLocation(program, "lightPos");
    if (lightPosLocation != -1)
  {
    glUniform3fv(lightPosLocation, 1, g_lightPos);
  }
  #endif
  }

这样效果是等价的。你会发现我并没有调用

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

来开启光照。这就是shader的好处,不需要这一堆的开关指令。需要用到的就拿去用吧,没用到就相当于关闭了。shader 可编程管线更加灵活。

镜面光照

镜面光照要考虑光的入射方向,以及眼睛所在的位置。由顶点指向光源的向量,顶点的法线,顶点指向照相机的向量就可以决定镜面光在该顶点的强度。简单起见默认默认照相机在z的正方向上,假设顶点到照相机的单位向量为(0.0, 0.0, 1.0)。根据镜面光的公式:

Cspec = max{N • H, 0}Sexp * Cmat * Cli

image

H是光线向量与视角向量之间夹角正中方向的单位向量。Sexp代表镜面指数,用于控制镜面光照的紧聚程度。Cmat是材料的颜色,Cli是光的颜色。Cspec 是最终求得的镜面颜色。在下面简单的例子中,假设光是白光(1.0, 1.0, 1.0, 1.0),镜面材料的镜面光属性也为(1.0, 1.0, 1.0, 1.0),所以我们可以忽略掉这一项乘的操作。其中N,L,Cmat 和 Cli 和散射光是一样的。这里镜面指数固定为128.

编写如下的specular.vs:

#version 120
uniform vec3 lightPos;
void main(void)
{
//MVP transform
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
  //caculate diffuse
  //normal
  vec3 N = normalize(gl_NormalMatrix * gl_Normal);
  //transform to view coordinate
  vec4 V = (gl_ModelViewMatrix * gl_Vertex);
  //light vector
  vec3 L = normalize(lightPos - V.xyz);
  float NdotL = dot(N,L);
  vec4 diffuse = vec4(max(NdotL, 0.0)) * gl_Color;
  //specular
  vec3 H = normalize(vec3(0.00.01.0) + L);
  float NdotH = max(0.0, dot(N,H));
  const float expose = 128.0;
  vec4 specular = vec4(0.0);
  if (NdotL > 0.0)
  specular = vec4(pow(NdotH, expose));

  gl_FrontColor = diffuse + specular;
}

效果图:

image

提升镜面光照
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值