我寫了一個光線追蹤程序(目前)有兩個表面照明選項:環境和反射。環境照明覆制自然表面如何散射光線。反射明顯地重現了鏡子如何反射光線。一切工作正常,但我無法弄清楚如何混合顏色與光澤反射。Java:光線追蹤:光澤反射着色
反射算法返回一個顏色並遞歸地工作。光線是以參數化線的形式「投射」的。當他們擊中反射表面時,他們完美地反彈(以及我的工作方法)。然後將這些反射光線用作再次調用反射算法的參數。這一直持續下去,直到當前光線遇到環境(非反射)表面或者當前光線根本沒有碰到表面。
我現在計算顏色的方式是我平均反射表面的顏色和從後到前新打的表面。因此,光線早期點擊的表面上的顏色比以後的表面顏色更多。
如果顏色A是它遇到的第一個(反射)表面的顏色,則顏色B是它碰到的第二個表面的顏色,C是第三個表面的顏色,依此類推。所以在最終的顏色返回將是50%A,25%B,12.5%C ...
我用於此的方法實際上支持加權平均值,以便鏡像表面對最終顏色影響較小。它是:
public void addColor(Color b, double dimFac) {
double red = c.getRed() * (1 - dimFac) + b.getRed() * dimFac;
double green = c.getGreen() * (1 - dimFac) + b.getGreen() * dimFac;
double blue = c.getBlue() * (1 - dimFac) + b.getBlue() * dimFac;
c = new Color((int) red,
(int) green,
(int) blue);
}
下面是該程序的截圖。有三種環境球體懸停在一個光滑的反射面,隨着a的0.5「dimFac」:
這裏是相同的模擬用的1,使得反射鏡對最終顏色沒有影響一個dimFac:
這裏dimFac是0.8
這裏,它是0.1
也許這只是我,但沒有這些反射看起來驚人的逼真的。我用作指南的是康奈爾的一個簡報,其中除了別的以外,還提到了有關添加顏色的任何內容。鏡子確實有一定的顏色,我不知道混合顏色的正確方法。我在做什麼錯了?
所以我從光線中獲取顏色的方式如下。射線追蹤器的每次迭代都以形狀的初始化開始。該程序支持三種形狀:平面,球體和直角棱鏡(最終只有6個平面)。我有一個每個形狀的類,和一個類(稱爲形狀),可以存儲每種類型的形狀(但每個對象只有一個)。
形狀形成後,一個類(稱爲投影儀)通過稱爲MasterLight的另一個類(實際上包含用於基本光線追蹤,陰影,反射和(現在)折射的方法)投射光線。
爲了得到一個交點的顏色,我調用getColor()方法,該方法使用交點的向量(我如何存儲3d點)。我用它來確定表面的無陰影顏色。如果曲面是無紋理的並且只是一個空白顏色(如上面的形狀),那麼將返回一個無陰影的顏色(它只存儲在每個形狀類「Color c = Color.RED」中)。一個例子是Color.RED
我採取了這種顏色,遞歸地插回到MasterLight作爲基礎顏色來獲得陰影,就好像表面是正常的和環境的。這個過程返回形狀通常會有的陰影。現在RGB值可能是(128,0,0);
public Color getColor(Vector v) {
if (texturing) {
return texturingAlgorithm;
}
else {
return c;
}
}
DimFac它被使用的方式有可能是0到1之間的任何值;現在在我的程序中,它是0.8(這是普遍的陰影常數,在環境陰影中,我把我調暗的值乘以0.8並加上0.2(1 - 0.8),這樣最暗的a顏色可以是其原始亮度的0.2)。
addColor在另一個類中(我現在有17個,其中一個是一個枚舉)稱爲Intersection。這存儲了有關光線交點與形狀(顏色,位置,擊中表面的法向矢量以及與物體材質有關的其他常數)的所有重要信息。顏色c是計算中當前的顏色。
反射的每次迭代調用addColor與最新的表面顏色。詳細說明一下,如果(在上圖中)一條光線剛剛從平面反射回來,撞到一個球體並跳入空白區域,我首先在球反射點處發現球體表面的顏色,這就是'c ' 被設定爲。然後我在交叉點(第一次)使用平面顏色調用addColor。
只要我回溯了所有的反射,我就留下了一種顏色,這是我用來對該特定光線的像素着色的顏色。
告訴我是否錯過了任何東西或者不清楚。
您能否提供您正在使用的獲取光線顏色的方法的副本?另外,你可以提供一些你的'addColor()'方法的上下文:dimFac是一個per-object屬性,就像在一個材質中一樣?還是全球價值?你能解釋你如何使用'Color''c'嗎? –