• Chapter 12-Not All Materials Are the Same


          本章主要讲解的是类似于天鹅绒的材质以及如何在RenderMonkey中构建这种材质的光照方程。

          天鹅绒这种材质,我还是头一次听说,太孤陋寡闻了,于是乎我去认真百度了一下“天鹅绒”。这种材质反射情形如下图所示。 

            特点:布料的折边处非常容易看到类似于镜面高光的反射。

            本章的几个小程序倒是很容易搞定。值得一说的是书中双向反射分布函数(BRDF)明显有错误,跟代码对不上。如222页的图12.6所示的Oren-Nayar光照模型计算公式,这个公式是错误的。

           

                如果看书没有勘误表,看到这种公式跟代码不一致时,真是让人死的心都有了,到底以哪一个为准?

                幸好现在网络很发达,Wiki百科上有这个公式非常详细的解释。

                参考链接如下:http://en.wikipedia.org/wiki/Oren%E2%80%93Nayar_reflectance_model(题外话,维基百科真是太强大了,相比之下,百度在专业搜索方面真显得非常业余)

                最终精确的Oren-Nayar光照计算公式如下图所示:

               

           上图的方位角Φi,Φr ,表示不够明显,我在《计算机图形学》中(Alan Watt著)中找到了一个比较好的图片——方位角就是入射光线、反射光线在正切平面上的投影与两线所在平面的夹角。

           

          公式搞明白之后,就可以写代码了。书中代码并不是严格的按照公式来写的,比如如下代码的第27行在max函数、min函数中分别计算正弦和正切的最大值和最小值,作者就偷懒了,直接按照已经计算好的值来进行比较了,而没有拿反三角函数计算角度再进一步比较角度大小。不过还是行得通的,毕竟角度增减趋势和正弦正切的增减趋势在0°~90°是一致的。

     1 float4 Light1_Color;
     2 float Velvet_Exponent;
     3 float PI;
     4 float rho_pi;
     5 float A;
     6 float B;
     7 float4 Light_Velvet(float3 Normal, float3 EyeVect, float3 LightDir,
     8 float4 LightColor)
     9 {
    10    // calculate all the dot products
    11    float NdotL = dot(Normal, LightDir);
    12    float NdotE = dot(Normal, EyeVect);
    13    // calculate the zenith angles
    14    float sinTheta_r = length(cross(EyeVect,Normal));
    15    float cosTheta_r = max(NdotE,0.001);
    16    float sinTheta_i = length(cross(LightDir,Normal));
    17    float cosTheta_i = max(NdotL,0.001);
    18    float tanTheta_i = sinTheta_i / cosTheta_i;
    19    float tanTheta_r = sinTheta_r / cosTheta_r;
    20    // calculate the azimuth angles
    21    float3 E_p = normalize(EyeVect-NdotE*Normal);
    22    float3 L_p = normalize(LightDir-NdotL*Normal);
    23    float cosAzimuth = dot(E_p, L_p);
    24    // Compute final lighting
    25    float inten = rho_pi * cosTheta_i *
    26    (A + B * max(0, cosAzimuth) *
    27    max(sinTheta_r, sinTheta_i) * min(tanTheta_i, tanTheta_r));
    28    return LightColor * clamp(inten,0,1);
    29 }

         如果你非要按照精确公式计算也是可以的。我顺便翻了一下《Advanced Lighting and Materials with Shaders》,第138页,7.3节,Oren-Nayar Materials这个示例就实实在在拿精确公式进行计算的,感兴趣的话可以参考一下。

          最后关于Oren-Nayar Materials材质,有这么一点要注意:它是属于散射类材质,是专门针对diffuse光的反射模型。因此即便光源包含Specular光和Ambient,也全当Specular和Ambient不存在,在光照方程中不对它们进行处理。Oren-Nayar Materials的反射光与视点是相关的,即它反射出来的光跟Specular非常像,但是,它的的确确是diffuse的处理方式,即散射方式对光线进行处理。

          对比图:左图是传统Phong光照模型,右图是Oren-Nayar光照模型。Oren-Nayar最大的特点,就是当你从入射光方向去观察被照亮模型,会发现整个模型向光面几乎都是亮的;而传统Phong就不一样,明暗分明。

         

    //end

  • 相关阅读:
    Ecshop商品批量上传,内容编码错误 您尝试查看的页面无法显示
    php 数组转化成字符串,并原样还原回数组
    PHP函数 curl_setopt
    <javascript学习笔记> javascript 获得url里参数。
    <yii 框架学习> <转> 关于yii数据库添加新字段之后model类的修改
    <yii 框架学习> 清空数据表
    <javascript学习笔记>javascript 实现隔行变色
    <javascript学习笔记> javascript 检查输入内容的长度。
    <php 代码积累 数组相关>
    <yii 框架学习> yii 框架改为中文提示
  • 原文地址:https://www.cnblogs.com/infintyward/p/3297744.html
Copyright © 2020-2023  润新知