现代OpenGL+Qt学习笔记之十一:使用halfway向量提高光照计算效率

现代OpenGL+Qt学习笔记之十一:使用halfway向量提高光照计算效率

主要内容

  本文介绍另一种光照计算的方法,可以减少光照计算的效率,当需要计算光照的的顶点/片元的较多时,使用该方法可以提高着色器的运行效率,从而提高渲染效率。

halfway向量

  现代OpenGL+Qt学习笔记之七:Phong光照及在GLSL中使用函数一文中已经介绍了Phong光照模型的原理及计算方法。本文将对镜面反射光强(specular)成分的计算方法进行优化。从而达到提高光照计算效率的目的。

  在之前的介绍中,镜面反射光强的计算是通过下列公式实现的:

Is=LsKs(rv)f

  其中向量r 是光的反射方向,v 是反射点到观察点的方向。向量r 的计算公式为:

r=s+2(sn)n

  共需要进行一次点乘运算、一次加法运算和多次乘法运算。下面就引入halfway向量h 来简化镜面反射光强的计算。

  我们定义h 为如下向量:

h=v+s

  各向量之间的关系如下图(h 在使用前需要进行单位化):

h向量

  注意到n 是向量rs halfway向量,而hvs 的halfway向量,不难证明,vr 之间的夹角是hn 之间的夹角的两倍,因此rv 也是与hn 存在一定的正比例关系,因此在计算镜面反射光强时,可以用hn 代替rv ,虽然计算结果不一样,但是要表达的意义是一样的。即有:

Is=LsKs(hn)f

  这样做的好处很明显,就是不需要计算s 而只需要进行一次加法计算就能得到h ,计算量大大减小,计算效率自然会提高。

  当然,在参数f 一定时,镜面反射的效果会有所不同。

halfway向量的实现

  使用这种方式计算镜面反射光强的方式非常简单,只需要修改相关着色器程序中的部分代码即可。在现代OpenGL+Qt学习笔记之七:Phong光照及在GLSL中使用函数一文源码的顶点着色器中,修改部分代码,首先删除计算向量r 的行:

    vec3 r = reflect( -s, norm );

而增加计算向量 h 的代码如下:

    vec3 h = normalize( v + s );

再将计算镜面反射光强spec的语句改为:

        spec = Light.Ls * Material.Ks *
               pow( max( dot(h, norm), 0.0 ), Material.Shininess );

  保存并运行程序,结果如下:

这里写图片描述

  原始的未采用该方法计算的结果如下:

这里写图片描述

  这里因为顶点较少,并没有列出运行时间比较性能,不过从计算方式上看,肯定是在性能上有所优化的。从结果上看,当参数f 的值相同时,使用halfway向量的渲染结果的镜面区域更大。

源码地址:http://download.csdn.net/download/chaojiwudixiaofeixia/10014848

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章