当前位置: 首页 > news >正文

山东响应式网站建设google adsense

山东响应式网站建设,google adsense,wordpress在线改主题,注册公司名字查询网Phinecos(洞庭散人) 专注于开源技术的研究与应用 【译】光线跟踪:理论与实现(三) 折射与Lambert-Beer 定律 Introduction 作者在这一篇中将解释如何去跟踪折射光线。这将涉及到在相交点处产生新的光线,并且计算新光线的方向。此外…

【译】光线跟踪:理论与实现(三) 折射与Lambert-Beer 定律

Introduction

      作者在这一篇中将解释如何去跟踪折射光线。这将涉及到在相交点处产生新的光线,并且计算新光线的方向。此外,作者还将运用Lambert-Beer 定律来解释光线在物体内部的吸收情况。最后作者将展示如何加入反锯齿的效果,并且如何对光线跟踪器进行加速优化。

Refractions

折射的情况如图1所示,注意观察光线在几何体表面是如何改变方向的,又是如何穿过几何体后面那个点的。在这个点后面的物体会看起来是倒转的镜像。

      几何体表面处光线的弯曲程度取决于两种物质的折射率:光线进入几何体前所在的物质的折射率,构成几何体的物质的折射率。例如:空气和真空的折射率为1.0,20摄氏度的水的折射率为1.33。
   2008041302.jpg

   下面这段代码应该让你感到很熟悉了吧。它就是构造折射光线,递归地跟踪它,并将结果颜色值加入到产生折射光的光线中去。有一点值得注意:法向量乘以了一个值’result’。这个值是对每个几何体的相交测试时获得的,值是1或0,分别表示是否命中。当然,还有第3个选择:-1,这表示是从几何体内部命中的。这点也是很重要的:如果一个光线命是从外部命中一个几何体的,那其实是没有命中这个几何体,而是它附件的物质。因此,其法向量应该取反。

     //  calculate refraction
         float refr = prim->GetMaterial()->GetRefraction();
         if ((refr >  0) && (a_Depth < TRACEDEPTH))
         {
            float rindex = prim->GetMaterial()->GetRefrIndex();
            float n = a_RIndex / rindex;
            vector3 N = prim->GetNormal( pi ) * (float)result;
            float cosI = -DOT( N, a_Ray.GetDirection() );
            float cosT2 = 1.0f - n * n * (1.0f - cosI * cosI);
            if (cosT2 > 0.0f)
            {
                vector3 T = (n * a_Ray.GetDirection()) + (n * cosI - sqrtf( cosT2 )) * N;
                Color rcol( 000 );
                float dist;
                Raytrace( Ray( pi + T * EPSILON, T ), rcol, a_Depth + 1, rindex, dist );
                a_Acc += rcol * transparency;
            }

        }


下图就是加入折射的效果图:
   2008041303.jpg

毫无疑问,你会注意到现在光线跟踪器很慢的,这是因为每条光线要与每个几何体进行相交测试来找出最近的相交点。当然,有很多方法可以对其进行改进,作者在后面的文章中会使用一种空间细分的方法来对相交测试的数量进行限制的。

Lambert-Beer定律

      上面的图中,你会发现球是蓝色的,因此折射图的颜色也是稍微偏蓝色的。这是因为折射光返回的颜色值会与几何体颜色相乘。这在反射,散射以及镜面光的计算中都有这种情况。

      现在让我们来想象有这么一个水池,里面充满了带颜色的物质(比如说水里面混合着蓝墨水)。池子的浅处大概10cm深,深处呢有1米深。如果你从上往底下看,很明显可以看到在较深的那端的底部受到颜色的影响会比浅处的要大。这种效应就叫Beer定律。

      Beer定律可以用下列公式表示:

light_out = light_in * e(e * c * d)

这个公式主要是用来计算溶解在水中的物质的光吸收度的。’e’是一个常量,表明溶剂的吸收度(准确来说,是单位为L/mol*cm的摩尔吸光率)。’c’是溶质的数量,单位mol/L.’d’是光线的路径长度。一般我们可以简化公式如下:

light_out = light_in * e(d * C)

这个d是路径长度,C是一个常量,表示物质的密度,减小它的值会使得光线在穿越物体时的时间增大。

吸收及透明度的计算需要以颜色因子来单位进行逐个计算。

                 //  apply Beer's law
                Color absorbance = prim->GetMaterial()->GetColor() *  0.15f * -dist;
                Color transparency = Color( expf( absorbance.r ), expf( absorbance.g ), expf( absorbance.b ) );
                a_Acc += rcol * transparency;

下面是效果图:
2008041301.jpg
   对于目前程序中使用的场景来说,应用这个定律对于画面的质量没有多大影响。不过一旦你开始使用复杂的场景,情况就大不一样了。

很多光线跟踪器都使用下述简单的方法:每个物体都有一个“反射”变量,它会与折射光返回的颜色值相乘,同时还有一个“折射”变量,会与折射光返回的颜色值相乘。然而对于折射光来说,这并不正确:每条折射光线在进入和退出几何体时会被计算两次。而且,从一个薄的物体穿过与穿过一个厚的物体有相同的衰减度。最大的问题更在于我们直观上会感觉不对:光线密度在几何体表面没有减小,而只会在几何体内部减小。

SuperSampling

假设我们使用下列代码来替换产生光线处的代码:

for (  int tx =  0; tx <  4; tx++ )  for (  int ty =  0; ty <  4; ty++ )
{
    vector3 dir = vector3( m_SX + m_DX * tx / 4.0f, m_SY + m_DY * ty / 4.0f0 ) - o;
    NORMALIZE( dir );
    Ray r( o, dir );
    float dist;
    Primitive* prim = Raytrace( r, acc, 11.0f, dist );
}


int red = ( int)(acc.r *  16);
int green = ( int)(acc.g *  16);
int blue = ( int)(acc.b *  16); 

这段代码作用是为每个像素点发射16条光线,因此结果图像具有抗锯齿效果,但缺点就是耗时太多。

也许你注意到了光线跟踪器返回的是指向几何体的指针,它指向被primary ray命中的几何体。我们做如下修改,代码的性能就大幅提升:

//  fire primary rays
Color acc(  000 );
vector3 dir = vector3( m_SX, m_SY,  0 ) - o;
NORMALIZE( dir );
Ray r( o, dir );
float dist;
Primitive* prim = Raytrace( r, acc,  11.0f, dist );
int red, green, blue;
if (prim != lastprim)
{
        lastprim = prim;
    Color acc( 000 );
    for ( int tx = -1; tx < 2; tx++ ) for ( int ty = -1; ty < 2; ty++ )
    {
        vector3 dir = vector3( m_SX + m_DX * tx / 2.0f, m_SY + m_DY * ty / 2.0f0 ) - o;
        NORMALIZE( dir );
        Ray r( o, dir );
        float dist;
        Primitive* prim = Raytrace( r, acc, 11.0f, dist );
    }

    red = (int)(acc.r * (256 / 9));
    green = (int)(acc.g * (256 / 9));
    blue = (int)(acc.b * (256 / 9));
}


else
{
    red = (int)(acc.r * 256);
    green = (int)(acc.g * 256);
    blue = (int)(acc.b * 256);
}

if (red >  255) red =  255;
if (green >  255) green =  255;

if (blue >  255) blue =  255;

ok,it’s over.在下一篇中作者将介绍“空间分割”思想的运用。

原文链接:http://www.devmaster.net/articles/raytracing_series/part3.php

作者:洞庭散人

出处:http://phinecos.cnblogs.com/    

本博客遵从 Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL
http://www.hkea.cn/news/823421/

相关文章:

  • 做婚礼网站的公司简介seo网站关键词优化软件
  • 哪些客户需要做网站推广平台排名前十名
  • 团购的网站扣佣金分录怎么做厦门百度竞价
  • 国家疫情最新政策麒麟seo外推软件
  • 河南第二波疫情最新消息淘宝关键词优化技巧教程
  • 优化好的网站做企业网站百度代理公司
  • 外贸b2c网站如何做推广百度电话人工服务
  • 百度怎样做网站并宣传网站2023上海又出现疫情了
  • wordpress后台登录慢阳山网站seo
  • 深圳网站建设企网络推广运营途径
  • 给自己女朋友做的网站yandex搜索引擎
  • 购物网站建设教程怎么在网上做广告宣传
  • 冠县做网站推广网站怎么制作
  • 开封 网站建设苹果被曝开发搜索引擎对标谷歌
  • 东莞虎门高铁站百度客户端电脑版下载
  • 建网站怎么挣钱的学seo推广
  • 自如网站做的好 服务哪个网站学seo是免费的
  • 国外网站阻止国内访问怎么做竞价推广工具
  • 建设一个网站需要哪些方面的开支百度人工客服
  • 品牌网站建设-建站之路最新疫情新闻100字
  • 东莞网站优化科技有限公司怀柔网站整站优化公司
  • 郑州网站建设联系方式外链是什么意思
  • 用wordpress做网站教程电脑优化大师有用吗
  • 佛山企业网站制作今日热点新闻事件
  • 企业网站网络推广黑帽seo培训
  • 欧美做的爱爱网站有哪些广告推广赚钱
  • 泉州网站建设工作室谷歌seo价格
  • 国建设委员会网站百度推广一天烧几千
  • 做网站 花园路国贸营销推广方案包括哪些内容
  • 做商城网站哪里买口碑营销属于什么营销