<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【RAY TRACING THE REST OF YOUR LIFE 超詳解】 光線追蹤 3-7 混合概率密度

       

       Preface

      注:鑒于很多網站隨意爬取數據,可能導致內容殘缺以及引用失效等問題,影響閱讀,請認準原創網址:

      http://www.rzrgm.cn/lv-anchoret/category/1368696.html

       

      我們這節主要講把之前的概率密度做混合,以得到更好的效果

      我們上一篇以前經常用關于cos函數的pdf,上一節用的是與光源采樣相關的pdf,那么,我們把兩者結合到一起,協調它們之間的比例,我們就可以得到一個有著兩種概率密度模型的pdf,這往往是更貼近生活的,那么我們今天就來學習測試一下。

       

       Ready

      這一節就是把前幾篇的概率密度做混合,所以,需要的就是熟悉之前的內容。

      當然,之前的框架代碼也比較丑,基本都是在lerp函數里面做調整,所以,我們順便把框架搭得更好一點

       

       正文

      我們都知道,設計pdf的一個很重要的原則就是使得累積概率密度達到且只達到1,所以,我們先采用一種非常簡單的比例協調方式混合兩個pdf。

      例如我們有如下的混合密度方程

      pdf_mixture(direction) = 1/2 * pdf_reflection(direction) + 1/2 * pdf_light(direction)

      即,兩者各占一半

      要實現兩者,代碼描述也很簡單:

      if ( rand01() < 0.5 )
          pdf_reflection();  ...
      else
          pdf_light();  ...
      但是評估pdf_mixture會稍微有點微妙。 我們需要同時評估pdf_reflection和pdf_light,因為有一些方向可以生成pdf方向。 例如,我們可以使用pdf_reflection生成朝向光的方向
       
      如果我們回顧之前的內容,你會發現,這一部分主要解決兩個問題:
      1.此處的pdf函數值
      2.按照某個隨機模型產生一個隨機數
       
      我們抽象出這些操作之后,就可以寫一個關于我們的pdf的一個基類:
      ///pdf.hpp
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2019.3
      // [brief ]        In the Monte Carlo system, pdf acts as the
      //                most important element of Important-Sample
      // -----------------------------------------------------
      
      
      #pragma once
      
      
      namespace rt
      {
      
      // the basic class of pdf system
      class pdf
          {
      public:
          /*
          @brief: we get the value of pdf function by this interface
          @param: the direction of location
          @retur: the value of the pdf function
          */
          virtual rtvar value(const rtvec & direction)const = 0;
      
          /*
          @brief: generate a random number with a Probability model
          @param: none
          @retur: the Three-dimensional random vector
          */
          virtual rtvec generate()const = 0;
          };
      
      
      }//rt namespace

       

      我們來實現關于它的一些子類

      首先我們來實現關于cosine 概率密度的模型

      ///cosine_pdf.hpp
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2019.3
      // [brief ]        one of the pdf' forms
      // -----------------------------------------------------
      
      
      #pragma once
      
      
      namespace rt
      {
      
      class cosine_pdf :public pdf
          {
      public:
          //constructor
          cosine_pdf(const rtvec& w);            
      
          /*
          @brief: we get the value of pdf function by this interface
          @param:    the direction of location
          @retur: the value of the pdf function
          */
          virtual rtvar value(const rtvec& direction)const;
      
      
          /*
          @brief: generate a random number with a Probability model
          @param: none
          @retur:    the Three-dimensional random vector
          */
          virtual rtvec generate()const;
      
      private:
      
          onb _uvw;
          };
      
      inline cosine_pdf::cosine_pdf(const rtvec& w)
          {
          _uvw.build_from_w(w);
          }
      
      rtvar cosine_pdf::value(const rtvec& direction)const
          {
          rtvar cosine = dot(direction.ret_unitization(), _uvw.w());
          if (cosine > 0.)
              return cosine / π;
          else
              return 0.;
          }
      
      rtvec cosine_pdf::generate()const
          {
          return _uvw.local(random_cosine_direction());
          }
      }

      這個模型之前細說過,cosine大于0的時候返回cosine/π,反之,則返回0。因為光線反射之后如果和表面法線的夾角為鈍角的時候,違反反射規律,不以反射。生成隨機數的那個之前也講過,在上上一篇

       

      其實這些都不是新東西,就是把之前講的的那一套整合了一下

      得到結果也就是之前的效果

      我們把主函數里面的lerp()也改一下

       

      每個像素點采樣100次,取均值,即sample 為 100時

       

       

       這是代碼敲錯了,意外得到的一張圖

       

       現在我們嘗試,光源采樣,即

      ///hit_pdf.hpp
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2019.3
      // [brief ]        toward to the hitable
      // -----------------------------------------------------
      
      #pragma once
      
      
      namespace rt
      {
      
      class hit_pdf :public pdf
          {
      public:
      
          /*
          @param: info -> Geometry information
                  origion -> the point of intersection
          */
          hit_pdf(intersect* info, const rtvec& origion)
              :_intersectp(info)
              ,_o(origion)
          {
          }
      
      
          /*
          @brief: we get the value of pdf function by this interface
          @param:    the direction of location
          @retur: the value of the pdf function
          */
          virtual rtvar value(const rtvec& direction)const
              {
              return _intersectp->pdf_value(_o, direction);
              }
          
      
          /*
          @brief: generate a random number with a Probability model
          @param: none
          @retur:    the Three-dimensional random vector
          */
          virtual rtvec generate()const
              {
              return _intersectp->random(_o);
              }
      
      private:
              
          rtvec _o;
      
          intersect * _intersectp;
          };
      
      }// rt namespace

       

      對應的intersect類也要改一下

      /// intersect.hpp
      //http://www.rzrgm.cn/lv-anchoret/p/10190092.html
      // -----------------------------------------------------
      // [author]        lv
      // [begin ]        2018.12
      // [refre ]        2019.3
      // [brief ]        the intersect-class for the ray-tracing project
      //                from the 《ray tracing in one week》
      // -----------------------------------------------------
      
      #pragma once
      
      #include "E:\OpenGL\光線追蹤\code\ray tracing 1-3\ray tracing 1-3\ray.hpp"
      
      
      namespace rt
      {
      class material;
      class aabb;
      
      
      // the infomation of intersection point
      
      struct hitInfo
          {
          lvgm::precision _t;        //ray 中的系數t
          rtvec _p;                //相交點、撞擊點
          rtvec _n;                //_p點的表面法線
          material* _materialp;    //材質
          rtvar _u;                //texture-u
          rtvar _v;                //texture-v
          };
      
      
      // the statement of intersect class
      
      class intersect
          {
      public:
      
          /*
          @brief: 撞擊函數,求取撞擊點相關記錄信息
          @param: sight->視線
          系數t的上下界->篩選撞擊點
          info->返回撞擊點信息
          @retur: 是否存在合法撞擊點
          */
          virtual bool hit(const ray& sight, rtvar t_min, rtvar t_max, hitInfo& info)const = 0;
      
          /*
          @brief: get the box of Geometry
          */
          virtual aabb getbox()const = 0;
      
          /*
          Get the value of pdf function
          */
          virtual rtvar pdf_value(const rtvec& o, const rtvec& v)const
              {
              return 0.;
              }
      
          /*
          generate the random number
          */
          virtual rtvec random(const rtvec& o)const
              {
              return rtvec(1, 0, 0);
              }
      
      
          };
      
      }// rt namespace

       

      因為我們現在只是拿區域光源做實驗,并不是所有的幾何體派生類都要繼承pdf相關的方法,所以,它們兩個以虛函數的形式存在即可。

      那么就剩下xz長方形了

      rtvar xz_rect::pdf_value(const rtvec& o, const rtvec& v)const
          {
          hitInfo rec;
          if (this->hit(ray(o, v), 1e-3, rt::rtInf(), rec))
              {
              rtvar area = (_x2 - _x1)*(_z2 - _z1);
              rtvar distance_squared = rec._t * rec._t * v.squar();
              rtvar cosine = fabs(dot(v, rec._n) / v.normal());
              return distance_squared / (cosine*area);
              }
          else
              return 0.;
          }
      
      rtvec xz_rect::random(const rtvec& o)const
          {
          rtvec random_point = rtvec(_x1 + lvgm::rand01() * (_x2 - _x1), _other, _z1 + lvgm::rand01()*(_z2 - _z1));
          return random_point - o;
          }

       

       把上一篇寫在lerp函數里面的一大堆東西整合到類里面

      那么我們的lerp就統一化了:

      我們取sample為10,即可得到很好的效果:

       

      現在我們將寫一個關于混合概率密度的類:

      ///mixture_pdf.hpp
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2019.3
      // [brief ]        mixture pdfs
      // -----------------------------------------------------
      
      
      #pragma once
      
      
      namespace rt
      {
      
      class mixture_pdf :public pdf
          {
      public:
      
          mixture_pdf(pdf * p1, pdf* p2)
              {
              _p[0] = p1;
              _p[1] = p2;
              }
      
      
          /*
          @brief: we get the value of pdf function by this interface
          @param:    the direction of location
          @retur: the value of the pdf function
          */
          virtual rtvar value(const rtvec& direction)const
              {
              return 0.5*_p[0]->value(direction) + 0.5*_p[1]->value(direction);
              }
      
      
          /*
          @brief: generate a random number with a Probability model
          @param: none
          @retur:    the Three-dimensional random vector
          */
          virtual rtvec generate()const
              {
              if (lvgm::rand01() < 0.5)
                  return _p[0]->generate();
              else
                  return _p[1]->generate();
              }
      
      private:
      
          pdf* _p[2];
      
          };
      
      
      }// rt namespace

       

      我們的lerp函數如下:

       

      我們采樣10次得到:

      但是覺得效果不是很理想,我們來做一些測試

       

      1. pdf 方程修改為 mixture_pdf = 1/3 * hit_pdf + 2/3  * cosine_pdf

       

      2. pdf 方程修改為 mixture_pdf = 2/3 * hit_pdf + 1/3  * cosine_pdf

       

      3. random修改  2/3 取 hit_pdf產生的隨機值, 1/3 取 cosine_pdf 產生的隨機值

       

      4. random修改  1/3 取 hit_pdf產生的隨機值, 2/3 取 cosine_pdf 產生的隨機值

       

      我們去上述方案的3、1,即:

       

      得到圖:

      這張圖顯然比均分的效果要好

       

      這里我們看不出到底是random起作用還是value,我們不妨取2、3組合

      3把2的彩色噪聲消除了些,但是這張圖和原始的均分圖差不多一樣

       

      所以結論,random和value的比例交叉比較好

       

      我們采樣1000次得到:

       渲染中。。。。(就是清晰了點)

      /***********************************************************************************/

      跑了一晚上爬起來發現除零錯誤了,又抽空跑完了

      /************************************************************************************/

       

      本書第九章(下一章)介紹了一些關于當前渲染器的看法

      作者在描述陰影光線和混合密度設計時,作者個人更偏向于混合密度設計,所以并沒有在渲染器中采用陰影光線

      作者描述了關于lerp函數中內存問題以及編碼的不足

      作者描述了關于玻璃材質和鏡面的一些處理方法

      作者還描述了關于HDR的0~1浮點表示以及RGB分組的0~255表示,還說明了這個渲染器是RGB的且基于物理的,還有一種是基于光譜的,以及兩者結合的,但做起來很難,所以我們堅持RGB且基于物理的渲染器。

       

       感謝您的閱讀,生活愉快~

       

      posted @ 2019-03-26 23:35  林-兮  閱讀(2122)  評論(4)    收藏  舉報
      主站蜘蛛池模板: 中文国产成人精品久久不卡 | 久久国产精品夜色| 中文字幕av无码不卡| 欧美成人www免费全部网站 | 国产狂喷潮在线观看| 日本丰满人妻xxxxxhd| 手机看片日本在线观看视频| 四川省| 资源在线观看视频一区二区 | 日本三级香港三级三级人妇久 | 日韩中文字幕人妻精品| 激情五月天一区二区三区| 国产精品自拍中文字幕| 天堂…中文在线最新版在线| 色噜噜一区二区三区| 日韩成人精品一区二区三区| 91中文字幕在线一区| 欧美激情一区二区久久久| 亚洲人成伊人成综合网小说| 三上悠亚精品一区二区久久| 91亚洲免费视频| 日本丶国产丶欧美色综合| 中文字幕色av一区二区三区| 亚洲精品国产第一区二区| 人妻丝袜中文无码av影音先锋 | 亚洲精品成人片在线观看精品字幕 | 国产成人av性色在线影院| 国产激情艳情在线看视频| 国产亚洲精品一区二区无| 亚洲老女人区一区二视频| 亚洲国产成人极品综合| 久久亚洲精品成人综合网| 久久99热只有频精品6狠狠| 久久精品亚洲中文字幕无码网站| 久久精品国产99精品亚洲| 无码成人午夜在线观看 | 狠狠做五月深爱婷婷天天综合| 午夜福利高清在线观看| 特黄三级又爽又粗又大| 亚洲一区中文字幕人妻| 我要看特黄特黄的亚洲黄片|