2011-12-25 73 views
1

好的,所以我正在使用phong陰影進行射線追蹤。到目前爲止,一切都很好。我已經投射了在我的場景中擊中球體的光線,並將phong陰影應用於它們,而且看起來很正常。Ray-Sphere交叉點:判別式錯誤

現在,我正在計算陰影射線,它是從初級射線到光源的交叉點拍攝射線,並查看它是否在路上撞擊到任​​何物體。如果是這樣,那麼它就在陰影中。但是,當計算陰影射線是否碰到任何球體時,我的判別式似乎有一個誤差,這是很奇怪的,因爲它對於初級射線來說是正確的。

這裏的設置:

// Origin of ray (x,y,z) 
origin: -1.9865333, 1.0925934, -9.8653316 
// Direction of ray (x,y,z), already normalized 
ray: -0.99069530, -0.13507602, -0.016648887 

// Center of sphere (x,y,z) 
cCenter: 1.0, 1.0, -10.0 
// Radius of the sphere (x,y,z) 
cRadius: 1.0 

,這裏的代碼尋找判別:

// A = d DOT d 
float a = dotProd(ray, ray); 

// B = 2 * (o - c) DOT d 
Point temp (2.0*(origin.getX() - cCenter.getX()), 2.0*(origin.getY() - cCenter.getY()), 2.0*(origin.getZ() - cCenter.getZ())); 
float b = dotProd(temp, ray); 

// C = (o - c) DOT (o - c) - r^2 
temp.setAll(origin.getX() - cCenter.getX(), origin.getY() - cCenter.getY(), origin.getZ() - cCenter.getZ()); 
float c = dotProd(temp, temp); 
c -= (cRadius * cRadius); 

// Find the discriminant (B^2 - 4AC) 
float discrim = (b*b) - 4*a*c; 

顯然,光線從球體背向,但這裏的判別是正的( 2.88)表明射線正在擊球。而且這段代碼適用於初級光線,因爲它們的判別式必須正確,但不適用於這些次級陰影光線。

我在這裏錯過了什麼嗎?

+0

我的猜測是你所缺少的是對數學的理解,以及它告訴你什麼。這個算法會告訴你一條線是否與一個球體相交,而不是一條射線?也就是說,一條線在兩個方向上有無限的範圍。 – 2011-12-25 03:50:21

+0

@woodchips射線是一個向量(帶有方向的點),所以它在一個方向(它所指向的方向)上是無限的。該公式基於球體的功能。如果P滿足:P-Pc ||,則點P位於球體上= r^2,其中Pc是球體的中心,r是半徑。對於射線,如果P = Q + td,則點P在射線上,其中Q是射線的起點,d是方向,並且t是「時間」。這裏有一個鏈接,因爲我的解釋簡短:http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection – user1115016 2011-12-25 04:23:38

+0

是的。雖然你已經仔細地複製了線條和射線的定義,但是你根本沒有理解前面的方程並且實現你所引用的方程。正或負的判別式並不意味着射線的交點有解決方案。它告訴你,如果判別式是積極的,那麼對於與球體相交的無限線存在解決方案!!!!!!! (實際上,非否定是關注的標準。)閱讀您提及的文檔並仔細閱讀。 – 2011-12-25 13:05:03

回答

3

我的問題那麼簡單的答案,萬一有人發現這一點,並有同樣的問題:

判別告訴你是否存在一個一擊(和射線,像我想的那樣)。如果它是積極的,那麼它已經在線上檢測到一個點擊。

因此,在計算射線的t值時,檢查它們是否爲負值。如果是這樣,那麼它就是射線背後的一個點(即射線的相反方向),所以放棄它。只保留正值,因爲它們在射線方向上打。

更短的回答:丟棄負值的t值。

積分木012讓我意識到這一點。

-1

很肯定的「O-C」應爲「C-O」

你拍攝的光線關在錯誤的方向,並找到在球體的另一側的交集。

0

問題是,找到一條直線和一個球體相交的技巧需要解二次方程。這樣的方程有三種可能性之一作爲解 - 其中有0,1或2個實數解。判別式的符號告訴我們有多少真實的解決方案(以及幫助我​​們解決這些解決方案)。

如果存在唯一的解決方案,那麼該線只會吻合球體的表面。當判別式恰好爲零時會發生這種情況。

如果存在兩個解,則該線穿過球體,擊中兩個不同點的表面。

如果不存在真正的解決方案(判別式爲負數的情況),那麼該線離球體太遠以至於根本無法觸及它。

發現線條是否曾經接近球體,只有這樣我們才擔心射線是否碰到球體。爲此,我們可以看看我們如何定義射線。射線是一條半線,只向一個方向延伸至無窮遠。所以我們看看交點發生在哪裏。只有在我們關心的線路的一半發生交叉時,纔有RAY球體相交。關鍵是,判別式的計算(並簡單地測試它的符號)只告訴你線路是幹什麼的,而不是關於沿該線路發生交叉的地方。

當然,仔細閱讀你自己提供的鏈接會告訴你所有這些。

+0

評論中的答案更有幫助。 – user1115016 2011-12-30 17:34:06