POV-RAY基礎教程 - CSG(3)

構造型實體幾何體(CSG)是一種可以組合原始對象以創建更復雜的對象的手段或者說方式,在上一篇介紹黃金鍊就已經用到了CSG方法。

回到上一篇 POV-RAY基礎教程 - 基本SDL(2)

什麼是CSG?

POV-Ray的CSG(Constructive Solid Geometry)允許我們通過以四種不同的方式組合原始形狀來構造複雜的實體。它們是:

  1. 使用union聲明,將兩個或多個形狀合併在一起;
  2. 使用intersection聲明,將兩個或多個形狀組合在一起以形成由兩個形狀共有的區域組成新形狀;
  3. 使用difference聲明,初始的形狀具有從中減去所有後續的形狀;
  4. 使用merge聲明,它就像一個聯合體,其中聯合體內的表面被移除(在透明CSG對象中很有用)。

我們接下來細討論這些細節

CSG Union

讓我們試着做一個簡單的聯合。創建一個名爲的文件 csgdemo.pov並按如下方式編輯它:

  #include "colors.inc"
  camera {
    location <0, 1, -10>
    look_at 0
    angle 36
  }
  light_source { <500, 500, -1000> White }
  plane { y, -1.5
    pigment { checker Green White }
  }

讓我們添加兩個球體,每個球體沿x軸在每個方向上平移0.5個單位。我們將一個藍色和另一個紅色染色。

  sphere { <0, 0, 0>, 1
    pigment { Blue }
    translate -0.5*x
  }
  sphere { <0, 0, 0>, 1
    pigment { Red }
    translate 0.5*x
  }

圖3-1

我們跟蹤此文件並記下結果。現在我們在兩個球體周圍放置一個聯合塊。這將從兩個對象中創建單個CSG聯合。

  union{
    sphere { <0, 0, 0>, 1
      pigment { Blue }
      translate -0.5*x
    }
    sphere { <0, 0, 0>, 1
      pigment { Red }
      translate 0.5*x
    }
  }

圖3-2

我們再次追蹤文件。聯合將看起來與每個球體本身的外觀沒有什麼不同,但現在我們可以給整個聯合提供單個紋理並將其整體轉換。我們現在就這樣做。

  union{
    sphere { <0, 0, 0>, 1
      translate -0.5*x
    }
    sphere { <0, 0, 0>, 1
      translate 0.5*x
    }
    pigment { Red }
    scale <1, .25, 1>
    rotate <30, 0, 45>
  }

圖3-4

我們再次追蹤文件。我們可以看到,該對象發生了巨大變化。我們嘗試不同的比例值並旋轉並嘗試一些不同的紋理。
將一個紋理分配給CSG對象而不是將紋理分配給每個單獨的組件有許多優點。首先,如果我們的CSG對象具有大量組件,則使用一個紋理要容易得多,因爲更改對象外觀只涉及更改一個單一紋理。其次,文件解析得更快,因爲紋理只需要解析一次。在進行大型場景或動畫時,這可能是一個很重要的因素。第三,僅使用一個紋理可以節省內存,因爲紋理只存儲一次並由CSG對象的所有組件引用。將紋理分配給所有n個組件意味着它被存儲n次。

CSG intersection

顧名思義,取物體的交集,現在讓我們使用這些相同的球體來說明intersection聲明的CSG對象。我們將單詞更改unionintersection並刪除scalerotate語句:

  intersection {
    sphere { <0, 0, 0>, 1
      translate -0.5*x
    }
    sphere { <0, 0, 0>, 1
      translate 0.5*x
    }
    pigment { Red }
  }

圖片
圖3-5

我們追蹤文件並將看到一個鏡頭形狀的物體而不是兩個球體。這是因爲交叉點由兩個形狀共享的區域組成,在這種情況下是兩個球體重疊的透鏡形區域。我們喜歡這個鏡片形物體,所以我們將用它來展示差異。

CSG Difference

我們圍繞y軸旋轉鏡頭形狀的交叉點,使得寬邊朝向相機。

  intersection{
    sphere { <0, 0, 0>, 1
      translate -0.5*x
    }
    sphere { <0, 0, 0>, 1
      translate 0.5*x
    }
    pigment { Red }
    rotate 90*y
  }

讓我們創建一個圓柱體並將其粘在鏡頭中間。

cylinder { <0, 0, -1> <0, 0, 1>, .35
    pigment { Blue }
  }

我們渲染場景以查看圓柱體的位置。我們將圍繞鏡頭形狀的交叉點和圓柱體放置一個difference塊,如下所示:

  difference {
    intersection {
      sphere { <0, 0, 0>, 1
        translate -0.5*x
      }
      sphere { <0, 0, 0>, 1
        translate 0.5*x
      }
      pigment { Red }
      rotate 90*y
   }
   cylinder { <0, 0, -1> <0, 0, 1>, .35
      pigment { Blue }
   }
 }

渲染的圖形如下:
圖3-6

我們再次渲染文件,看到鏡頭形狀的交叉點,在它的中間有一個整齊的洞。圓筒已經從交叉區域subtracted。注意,圓柱體的顏料使孔的表面着藍色。如果我們消除這種顏料,孔的表面將是黑色的,因爲如果沒有指定顏色,這是默認顏色。好吧,讓我們現在變得有點狂野。讓我們宣佈我們的穿孔鏡片對象給它一個名字。讓我們也消除聲明對象中的所有紋理,因爲我們希望它們在最終的聯合中。

  #declare Lens_With_Hole = difference {
    intersection {
      sphere { <0, 0, 0>, 1
        translate -0.5*x
      }
      sphere { <0, 0, 0>, 1
        translate 0.5*x
      }
      rotate 90*y
    }
    cylinder { <0, 0, -1> <0, 0, 1>, .35 }
  }

讓我們使用一個聯合來構建一個由這個對象的副本組成的複雜形狀。

  union {
    object { Lens_With_Hole translate <-.65, .65, 0> }
    object { Lens_With_Hole translate <.65, .65, 0> }
    object { Lens_With_Hole translate <-.65, -.65, 0> }
    object { Lens_With_Hole translate <.65, -.65, 0> }
    pigment { Red }
  }

圖3-7

讓我們通過在顏料塊中添加一些過濾器使其成爲部分透明的物體。

  union {
    object { Lens_With_Hole translate <-.65, .65, 0> }
    object { Lens_With_Hole translate <.65, .65, 0> }
    object { Lens_With_Hole translate <-.65, -.65, 0> }
    object { Lens_With_Hole translate <.65, -.65, 0> }
    pigment { Red filter .6 }
  }

圖片如下
圖3-8

可以看到,透過紅色部分可以看到地面紋路,說明有一定的透明度

CSG Merge

這將我們帶到第四種CSG對象,即merge。合併與聯合相同,但不跟蹤合併內的CSG中對象的幾何。這應該消除我們的對象的問題。我們來試試吧。

  merge {
    object { Lens_With_Hole translate <-.65, .65, 0> }
    object { Lens_With_Hole translate <.65, .65, 0> }
    object { Lens_With_Hole translate <-.65, -.65, 0> }
    object { Lens_With_Hole translate <.65, -.65, 0> }
    pigment { Red filter .6 }
  }

圖片如下
圖3-9

果然,確實如此!

CSG問題

我們必須注意CSG代碼中存在嚴重缺陷。POV-Ray使用內部/外部測試來確定光線與CSG對象相交的點。當兩個不同形狀的表面重合時會出現問題,因爲沒有辦法(由於計算機的浮點精度)來判斷重合表面上的點是屬於一種形狀還是另一種形狀。請看下面的示例,其中使用圓柱體在較大的盒子中切割孔。

  difference {
    box { -1, 1 pigment { Red } }
    cylinder { -z, z, 0.5 pigment { Green } }
  }

注意:框定義中的向量-1和1分別擴展爲<-1,-1,-1>;和<1,1,1>。
圖片如下
圖3-10

從圖片中,我們可以看到,在兩個物體相交的表面,產生了紅綠斑點,這是因爲,座標相同的兩個相交表面,POV-Ray不知道具體渲染哪一個,可能一會渲染這個,一會渲染那個,就會產生這種現象。
既然,是因爲座標完全一樣,導致的這種問題,如果想解決這種問題,我們只需將其移動一點位置就可以了

  difference {
    box { -1, 1 pigment { Red } }
    cylinder { -1.001*z, 1.001*z, 0.5 pigment { Green } }
  }

圖片如下
圖3-11
繼續閱讀下一篇 POV-RAY基礎教程 - 光源(4)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章