博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Directx教程(28) 简单的光照模型(7)
阅读量:6123 次
发布时间:2019-06-21

本文共 3121 字,大约阅读时间需要 10 分钟。

       现实生活中的点光源都是随着距离衰减的,比如一个电灯泡在近处会照的很亮,远处光线就很弱。本节中我们在前面光公式的基础上,再给漫反射和高光加上一个衰减因子。

      光源随着距离衰减并不是纯线性的,常用的公式是:

133equ01.jpg

  • d 是光源到着色点的距离
  • kC, kL, 和 kQ 分别是常量、线性以及二次衰减系数

现在在light.ps中,计算光照的代码变成了:

  for ( i = 0; i < NUM_LIGHTS; i++)

  {
    //自发射颜色
    emissive = Ke[i];
   
   //计算环境光
    ambient = Ka[i] * globalAmbient[i];
   
    //计算漫反射光
    //用LightDirection就是纯平行光
    //光源位置减顶点位置
     L = normalize(lightPosition[i].xyz - P);
     d = distance(lightPosition[i].xyz, P);
     //衰减系数
     atte = 1 / (attenuation[i].x + attenuation[i].y * d +attenuation[i].z * d * d);
     diffuseLight = max(dot(N, L), 0);
     diffuse =   Kd[i] * lightColor[i] * diffuseLight * atte ;

     //计算高光

     V = normalize(cameraPosition.xyz - P);
     H = normalize(L + V);
     specularLight = pow(max(dot(N, H), 0), shininess[i]);
 
      if (diffuseLight <= 0)
          specularLight = 0;
      specular = Ks[i] * lightColor[i] * specularLight *  atte;

      finalcolor +=  emissive + ambient + diffuse + specular;

     }

   

     相应的,在lightShaderClass.h中的struct  LightMaterialBufferType,也要做一些变化,增加一个D3DXVECTOR4分量attenuation,它的x,y,z分别表示常量、线性以及二次衰减系数。之所以用D3DVECTOR4,是因为const buffer要求是4的倍数,我曾尝试用3个float,结果程序竟然有编译错误。

D3DXVECTOR4 attenuation[NUM_LIGHTS]; //衰减系数,x,y,z对应常量,线性和二次系数

    在light.ps中,const buffer  LightMaterialBuffer,也要增加衰减因子,它和LightMaterialBufferType中的attenuation是相对应的。

float4 attenuation[NUM_LIGHTS]; //衰减系数

 

程序执行后的效果如下:

完整的代码请参考:

工程文件myTutorialD3D11_21

代码下载:

    接下来我们再实现一个探照灯(spotlight)的效果,如下图所示,只有在圆锥内角(inner)的范围才是光照能够达到的范围。但是只考虑内角的话,我们的光照会比较生硬,内角圆锥内,有光,内角圆锥外,一片漆黑,所以我们又加了一个外角(outer),对于内角和外角之间的空间,我们使用hlsl的差值函数smoothstep来计算得到一个0-1之间的数值。

 

 

 

light.ps的主要代码:

    下面的函数通过smoothstep计算出spotlight的因子。其中cosInnerCone是内角的余弦值,cosOuterCone是外角的余弦值。如果计算出的cosDirection值大于内角余弦值,则smoothstep值为1,如果cosDirection值小于外角余弦值,则其值为0,对于在这两者之间的值,smoothstep会用多项式差值得到一个0-1之间的值。

//一个计算spot light系数的函数

float dualConeSpotlight(float3 P, float3 lightpos, float3 lightdir, float  cosInnerCone, float cosOuterCone)
{
 
  float3 V = normalize(P - lightpos);
 
  float cosDirection = dot(V, normalize(lightdir));
 
  return smoothstep(cosOuterCone,  cosInnerCone, cosDirection);
}

  for ( i = 0; i < NUM_LIGHTS; i++)

  {
       //自发射颜色
    emissive = Ke[i];
   
    //计算环境光
    ambient = Ka[i] * globalAmbient[i];
   
    //计算漫反射光
    //用LightDirection就是纯平行光,在spotlight情况下代表光的方向

    spotEffect = dualConeSpotlight(P,  lightPosition[i].xyz, lightDirection[i],spotattenuation[i].x, spotattenuation[i].y);

    //光源位置减顶点位置

     L = normalize(lightPosition[i].xyz - P);
     d = distance(lightPosition[i].xyz, P);
     //衰减系数
     atte = 1 / (attenuation[i].x + attenuation[i].y * d +attenuation[i].z * d * d);
     diffuseLight = max(dot(N, L), 0);
     diffuse =   Kd[i] * lightColor[i] * diffuseLight * atte * spotEffect;

     //计算高光

     V = normalize(cameraPosition.xyz - P);
     H = normalize(L + V);
     specularLight = pow(max(dot(N, H), 0), shininess[i]);
 
      if (diffuseLight <= 0)
          specularLight = 0;
      specular = Ks[i] * lightColor[i] * specularLight * spotEffect;

      finalcolor +=  emissive + ambient + diffuse + specular;

     }

     同样的,我们的const buffer LightMaterialBuffer中,增加了

         float4 spotattenuation[NUM_LIGHTS];

     它的x,y分别表示内角和外角余弦值。

     lightShaderClass.h中的材质光照结构中也增加了

        D3DXVECTOR4 spotattenuation[NUM_LIGHTS]; //对于spotlight,x,y分别存储内和外角cos值

程序最终执行效果如下:

 

完整的代码请参考:

工程文件myTutorialD3D11_22

代码下载:

转载于:https://www.cnblogs.com/mikewolf2002/archive/2012/04/04/2431790.html

你可能感兴趣的文章
写给对前途迷茫的朋友:五句话定会改变你的人生
查看>>
并行程序设计学习心得1——并行计算机存储
查看>>
JAVA入门到精通-第86讲-半双工/全双工
查看>>
bulk
查看>>
js document.activeElement 获得焦点的元素
查看>>
C++ 迭代器运算
查看>>
【支持iOS11】UITableView左滑删除自定义 - 实现多选项并使用自定义图片
查看>>
day6-if,while,for的快速掌握
查看>>
JavaWeb学习笔记(十四)--JSP语法
查看>>
【算法笔记】多线程斐波那契数列
查看>>
java8函数式编程实例
查看>>
jqgrid滚动条宽度/列显示不全问题
查看>>
在mac OS10.10下安装 cocoapods遇到的一些问题
查看>>
angularjs表达式中的HTML内容,如何不转义,直接表现为html元素
查看>>
css技巧
查看>>
Tyvj 1728 普通平衡树
查看>>
[Usaco2015 dec]Max Flow
查看>>
javascript性能优化
查看>>
多路归并排序之败者树
查看>>
java连接MySql数据库
查看>>