基于CPU的Bank BRDF经验模型,实现各向异性光照效果!

原文 : http://blog.csdn.net/pizi0475/article/details/6650841




摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文 名“GPU编程与CG语言之阳春白雪下里巴人”  

 

 

BRDF 光照模型

10.2.1 什么是 BRDF 光照模型

1965 年, Nicodemus, Fred 在论文 Directional reflectance and emissivity of an opaque surface ” 中提出了 BRDF 的概念。 BRDF , Bidirectional Reflectance Distribution Function ,中文翻译为 “ 双向反射分布函数 ” 。该函数描述了入射光线在非透明物体表面如何进行反射。

BRDF 的结果是一个没有单位的数值,表示在给定入射条件下,某个出射方向上反射光的相对能量,也可以理解为 “ 入射光以特定方向离开的概率 ” (实时计算机图形学第二版 111 页)。如 图 23 所示, Wi表示光线入射方向, Wo表示光线出射方向(入射点到视点),则该情况下的 BRDF 值 表示:光线以Wi 方向入射,然后以 Wo方向出射的概率,或者光强。 这些信息也可以用仪器进行测试记录,并存放在图片上,称为 polynomial texture map 

 

依据光学原理, BRDF 的计算公式为:

                

其中 Lr(Wo)表示从 Wo方向反射的光线的辐射亮度( Radiance ); Ei(Wi)表示从 Wi方向入射的光线在辐射照度( Irradiance )。辐射亮度和辐射照度是表示光照性质的光学量,辐射亮度是每单位 立体角 在垂直于给定方向的平面上的单位正投影面积上的 功率 。辐射照度则是整个入射表面的功率,等于投射在包括该点的一个面元上的辐射通量 dφ 除以该面元的面积 dA 。故而,从物理光学上我们可以将公式理解为: BRDF 函数计算的是 “ 特定反射方向的光强与入射光强的比例 ” 

所以给定一个具体的 BRDF 数学描述后,就可以放到 rendering equation 中使用(参阅 9.4 节)。

10.2.2 什么是各向异性

各向异性 (anisotropy ) 与 均向性 相反,是指在不同方向具有不同行为的性质,也就是其行为与方向有关。如在物理学上,沿着材料做不同方向的量测,若会出现不同行为,通常称该材料具有某种 “ 各向异性 ” ,这样的材料表面称为各向异性表面( anisotropic surface );

特殊的晶体结构会导致各向异性,材质表面上存在有组织的细小凹凸槽也会导致各向异性。各向异性反射是指:各向异性表面反射光的一种现象。在生活中我们经常见到各向异性光照效果,例如光滑的炊具上的扇面光斑( 图 24 所示)。

 

由于材质有组织的细微凹凸结构的不同,各向异性也分为基本的三种类型(如 图 25 所示):

1.      线性各向异性;

2.      径向各向异性;

3.      圆柱形各向异性,实际上线性各向异性,单被映像为圆柱形。

 

10.3 Bank BRDF 经验模型

Bank BRDF 属于经验模型,由于其计算简单,且效果良好,所以该模型在各向异性光照效果的模拟方面非常有用。 Bank BRDF 的镜面反射部分可以表达为公式 ( 10-14 )的 形式:

Ks、 ns分别表示镜面反射系数和高光系数; L表示入射光线方向、V 表示实现观察方向、 T表示该点的切向量。尤其要注意切向量的计算方法,因为一个三维空间点可能存在无数个切向量,通常我采用 “ 顶点的法向量和视线方向做叉积,其结果作为 T 。

Bank BRDF 模型渲染效果如 图 26 、 图 27 所示。 图 27 的渲染图非常明显的呈现出各向异性的光照效果。

下面分别给出 Bank BRDF 的顶点着色程序和片段着色程序代码。

代码 10 Bank BRDF 的顶点着色程序

 

void main_v(float4 position   : POSITION,

          float4 normal   : NORMAL,

 

          out float4 oPosition : POSITION,

          out float3 worldPos : TEXCOORD0,

          out float3 worldNormal   : TEXCOORD1,

 

          uniform float4x4 modelViewProj,

          uniform float4x4 worldMatrix,

          uniform float4x4 worldMatrix_IT)

{

       oPosition = mul(modelViewProj, position);

        worldPos = mul(worldMatrix, position).xyz;

       worldNormal = mul(worldMatrix_IT, normal).xyz;

}

代码 11 Bank BRDF 片段着色程序

 

void main_f(float4 position  : TEXCOORD0,                       

          float3 normal    : TEXCOORD1,

 

          out float4 color     : COLOR,

 

          uniform float3 globalAmbient,

           uniform float3 lightColor,

           uniform float3 lightPosition,

           uniform float3 eyePosition,

           uniform float3 Ka,

           uniform float3 Kd,

           uniform float3 Ks,

           uniform float  shininess)

{

  float3 P = position.xyz;

  float3 N = normalize(normal);

 

  float3 ambient = Ka * globalAmbient; // 计算环境光分量

 

  float3 L = normalize(lightPosition - P);

  float ln = max(dot(L, N), 0);

  float3 diffuse = Kd * lightColor *ln; // 计算有向光漫反射分量

 

  // 计算镜面反射分量

  float3 V = normalize(eyePosition - P);

  float3 H = normalize(L + V);

    float3 specular = float3(0.0,0.0,0.0);

  bool back = (dot(V,N)>0) && (dot(L,N));

  if(back)

  {

     float3 T = normalize(cross(N,V));  // 计算顶点切向量

     float a = dot(L,T);

     float b = dot(V,T);

     float c = sqrt(1-pow(a,2.0))* sqrt(1-pow(b,2.0)) - a*b; // 计算 Bank BRDF 系数

     float brdf = Ks* pow(c, shininess);

          

     specular = brdf * lightColor *ln;

  }

  color.xyz = ambient + diffuse + specular;

  color.w = 1;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值