2014-01-23 33 views
0

我剛剛嘗試實施高光反射。問題在於,當遠離表面移動時,突出部分變得越來越強,突出部分的邊緣變得非常嚴酷。當移動到表面太近時,高光完全消失。反射高光取決於相機距離

這是我的片段着色器的相關部分。所有的計算都在視圖空間中。我使用定向太陽光。

// samplers 
vec3 normal = texture2D(normals, coord).xyz; 
vec3 position = texture2D(positions, coord).xyz; 
float shininess = texture2D(speculars, coord).x; 

// normalize directional light source 
vec3 source; 
if(directional) source = position + normalize(light); 
else source = light; 

// reflection 
float specular = 0; 
vec3 lookat = vec3(0, 0, 1); 
float reflection = max(0, dot(reflect(position, normal), lookat)); 
int power = 5; 
specular = shininess * pow(reflection, power); 

// ... 

// output 
image = color * attenuation * intensity * (fraction + specular); 

這是我的照明緩衝區的屏幕截圖。你可以看到最重要的鏡筒沒有任何鏡面反射,而遠處的鏡筒太強烈。中間的桶根據需要點亮。

far highlights are too strong and near highlights disappear

我在做什麼錯?

+0

顯示您的客戶端代碼,尤其是光矢量。確保你不要將方向與位置混淆。 –

+0

對於定向光源,我將位置視爲方向。例如,太陽的位置是「0.5,1.0,1.5」。這是否會造成問題?但問題是方向燈和點燈相同。 – danijar

+1

沒有足夠的代碼。顯示如何構建模型視圖矩陣。例如,如果您的向量看起來像l,x,y,z,1那麼它可能是個問題 –

回答

2

您正在計算物體位置的反射矢量,而不是使用反轉的光線方向(從物體指向光源)。

這就像這個圖中,用V代替升:

另外,我覺得光澤應該是你表達的指數不是東西,線性乘以鏡面貢獻。

+0

謝謝。當使用'float reflection = max(0,dot(reflect(normalize(source - position),normal),lookat));'沒有可見的高亮了。當我將「高光」乘以10時,會出現某種高光,但它仍然以某種方式迷失方向。我如何進一步調試我的問題?我知道矩陣是正確的,因爲漫射照明適用於點光源。 – danijar

+0

我認爲你應該使用:specular = pow(reflection,shininess);順便說一句,我也覺得很難調試着色器...我通常會做「色彩調試」(即:http://en.wikibooks.org/wiki/Cg_Programming/Unity/Debugging_of_Shaders) –

+0

什麼是'光澤值呢?我的表面完全沒有鏡面反射。當將「光澤度」設置爲零時,pow函數將變爲一個,並將其添加到光照中,而不是相乘。我可以製作着色器單步執行的屏幕截圖。哪些階段會有幫助? – danijar

1

我認爲變量命名令你感到困惑。 從我讀什麼(假設你在相機的空間,不霸道知識是)

vec3 lookat = vec3(0, 0, 1); 
float reflection = max(0, dot(reflect(position, normal), lookat)); 

lookat是定向光,position是實際lookat

確保normal(它可能已經正常化)和positionlookat)被歸一化。

甲不易混淆代碼將是:

vec3 light_direction = vec3(0, 0, 1); 
vec3 lookat = normalize(position-vec3(0,0,0)); 
float reflection = max(0, dot(reflect(light_direction, normal), -lookat)); 

沒有歸positionreflection會有偏差。當position距相機較遠時,偏差會很強vec3(0,0,0)

請注意lookat不是常數;它隨每個位置而變化。 lookat = vec3(0,0,1)正朝着視角空間中的一個位置。

+0

當我們需要一個從點到相機的向量時,不會(位置 - vec3(0,0,0))從'相機'返回一個向量到點的向量? – 2015-06-11 22:26:08

+0

@racarate(position - vec3(0,0,0))是從相機到位置的矢量,這就是「看」。然而你是對的:點應該位於反射光線和位置指向相機的向量之間(-lookat) –