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

BRDF 光照模型

10.2.1 什么是 BRDF 光照模型

Wi表示光线入射方向, Wo表示光线出射方向(入射点到视点),则该情况下的 表示:光线以Wi 方向入射,然后以 Wo方向出射的概率,或者光强。 

(z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!-LMLPHP

(z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!-LMLPHP

10.2.2 什么是各向异性

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

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

(z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!-LMLPHP

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

1.      线性各向异性;

2.      径向各向异性;

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

(z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!-LMLPHP

10.3 Bank BRDF 经验模型

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

(z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!-LMLPHP

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

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

(z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!-LMLPHP

下面分别给出 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;

}

作者:pizi0475 发表于2011-8-1 15:00:30 原文链接
 
 
http://www.cnblogs.com/guoyiqi/archive/2011/08/01/2137116.html
05-08 08:35