2016-10-06 31 views
0

我使用C++和OpenGL(glDrawPixels)上的光線追蹤工作,而且進展順利,到目前爲止。不過,我的陰影似乎有點偏離。我希望我的球體看起來更平滑一些,而不會在強度之間出現明顯的線條。目前,我只是試圖實現Lambertian着色,即Intensity = Id * pd *(N dot L)。我知道如何通過歸一化法向量和光矢量來計算(N點L),但是如何計算Id和pd(強度彌散和比例因子)?我只是用2.5的恆定值,以實現以下目標:如何實現朗伯明暗

Here is a picture of what my shading looks like

顯然,2.5完全是任意的,我只使用它,因爲我的其他的嘗試甚至沒有像正確的陰影。上面的等式似乎表明,我應該乘以強度的顏色。這是我的方法:

Color simpleIlluminate(Vector3D normal, Vector3D light, Color color) { 
    float intensity = dotProduct(normal, light)*2.5f; 
    color = Color((unsigned int)intensity*color.r, (unsigned int)intensity*color.g, (unsigned int)intensity*color.b); 
    return color; 
} 

假設法向矢量和光矢量是正確的。顏色只是一個顏色結構,我對每個RGB值都有一個無符號整數。參數顏色顏色是我想要遮蔽的球體的顏色,例如,紅色=顏色(255,0,0)。要修改顏色的強度,我只需將每個值乘以計算的強度,但運行時看起來不正確。

有人能解釋我缺少什麼,告訴我正確的函數應該是什麼樣子給出的向量和球的顏色嗎?我到處尋找,但我找不到一個好的解決方案。我也可能會做我的float unsigned int轉換錯誤,但我不確定。任何幫助表示讚賞。

+0

您可能需要糾正伽馬。將RGB值以2.2的冪進行縮放。計算的強度是線性的,但是RGB值是通過所謂的「伽瑪」進行調整的。在wiki中查看sRGB。另外,請確保最亮的曲面RGB值小於255,否則會剪裁。 – doug

回答

1

我會刪除該2.5因素,因爲它可能與結果擰,這很可能會產生的條紋的,因爲你是範圍在0和1

朗伯反射以外的因素擴大到也是已知的作爲餘弦反射,真的很容易理解。考慮一個平面,如果光線與平面垂直,那麼所有的光線都會落到表面(100%,或者因子1.0)。如果光線指向平行於該平面,那麼0光將落在表面上(所有光線是平行的,因此不會與平面相交,因此是0或0)。

朗伯反射率是簡單地之間的光方向的角度的餘弦和表面法線和範圍從0(沒有光射到平面)到1.0(所有光撞擊平面)。注意餘弦(90)= 1.餘弦(0)= 0,因此稱爲餘弦定律(朗伯反射)。

0

我也可能會做我的浮到unsigned int類型轉換錯誤

點上。 (unsigned int)intensity*color.r相當於((unsigned int)intensity)*color.r。所以你的強度在被乘以顏色之前會有離散的水平,這會導致這些線條。改爲嘗試(unsigned int)(intensity*color.r)