The Complete Effect and HLSL Guide(十二)
本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。
翻译:clayman
Blog:http://blog.csdn.net/soilwork
clayman_joe@yahoo.com.cn
我们已经有了个一个漫反射点光源着色器,现在应该考虑光照方程中的高光部分了。和漫反射相比,镜面高光最大的区别就是光照亮度不但与光线到表面的角度有关,还和观察者的角度有关。
为了计算高光,我们需要一个称为中间(half)矢量的值。这个矢量其实是观察矢量和灯光矢量的中间值。为了计算观察矢量需要把观察点变换到模型空间。我们假设观察点的位置位于( 0,0,10)。把它变换到模型空间之后,加上顶点位置,就是最终的观察矢量:
EyeVector = -normal(mul ( inv_view_matrix, float4(0,0,10,1) + inPos);
把EyeVector与光源矢量混合到一起,然后进行标准化,就是中间矢量。由于EyeVector和LightDir都是标准矢量,所以中间矢量相当于二者的均值(A + B)/ 2。
HalfVect = normalize ( LightDir – EyeVetor);
(译注:更直观的做法是在世界坐标下计算EyeVector,然后用LightDir + EyeVetor计算HalfVect)
有了中间矢量,把它和表面法线的点积进行m次幂运算,就能算出光源基于角度的光线强度。幂运算时的指数相当于物体的镜面指数,值越大,高光区域就越小也越明亮。下面的代码假设镜面指数为32。
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
float2 Color: COLOR;
};
float4 Light_PointSpecular( float3 VertPos, float3 VertNorm,float3 LightPos,
float4 LightColor, float4 Lightattenuation, float3 EyeDir)
{
//Determine the Distance from the light to the vertex and the direction
float3 LightDir = LightPos - VertPos;
float Dis = length(lightDir);
LightDir = Light