爲了學習opengl,我使用openGL 3.3創建了一個簡單的3D圖形引擎。我最近在距離上增加了光衰減;這已將所有物體完全變黑。這是通過在片段着色器中加入以下代碼,以我的光計算完成:什麼可能導致變量表現爲無限且同時爲非無限?
float distance = length(lite.position - FragPos);
float attenuation = 1.0f/(lite.constant + (lite.linear * distance) + (lite.quadratic * (distance * distance)));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
result += (ambient + diffuse + specular);
似乎可以認爲attenuation
非常小,有效地或實際0或負(黑色)。爲了測試這個,我使用result += vec3(attenuation);
,結果是白色物體;這表明attenuation
不是接近0,而是1.0或更大;嘗試result += vec3(attenuation/500000);
的附加測試仍會產生白色,這表明衰減非常大,可能是無限的。我做了一些無限和NaN檢查。 NaN支票告訴我這是一個數字,無限檢查告訴我它有時是無限的,有時不是。事實上,它告訴我,它既是無限的,也是無限的。我通過使用以下代碼段確定了這一點:
if(isinf(attenuation)){
result += vec3(1.0, 0.0, 0.0);
}
if(isinf(attenuation) && !isinf(attenuation)){
result += vec3(0.0, 1.0, 0.0);
}
if(!isinf(attenuation)){
result += vec3(0.0, 0.0, 1.0);
}
我的對象變成紫色/洋紅色。如果attenuation
無限,我會希望我的物體呈現紅色;如果它們不是無限的,我會期望它們顯得藍色;他們在某種程度上既是無限的,也是無限的,我希望他們看起來很綠。如果我使result += ...
爲result = ...
,則對象顯示爲紅色。在這種情況下,如果我的紫色物體暗示result
將首先設置爲紅色,然後設置爲藍色,導致藍色物體(如果以某種方式綠色檢查失敗),它既是無限的,也不是無限的。
我希望這能說明我的困惑之源。我的測試顯示attenuation
是無限的,並且它不是無限的,並且它既不是。
頂部事事休,當我使用:
float attenuation = 1.0f/(1.0 + (0.0014 * distance) + (0.000007* (distance * distance)));
確定衰減係數,一切工作完全按照預期;但是這裏顯示爲常數的值是什麼是從我的OpenGL調用(C++)傳遞:
glUniform1f(lightConstantLoc, 1.0f);
glUniform1f(lightLinearLoc, 0.0014f);
glUniform1f(lightQuadraticLoc, 0.000007f);
從那裏我應該得出結論,我的數據沒有被交付給我的着色器正確的,但我相信我的lite.constant
等值已被正確設置,並且distance
是合理的值。當我挑選每一個出來的顏色,對象也把那color.ie:使用此
result = vec3(lite.constant, 0.0, 0.0);
我的對象會變成紅色一些陰影,爲lite.constant
,lite.linear
等
搜索谷歌和堆棧對於像「glsl isinf true and false」或「glsl variable is is and is not infinite」這樣的東西溢出來,我絕對沒有相關的結果。
我明白我對這裏發生的事情,或者某種方式有效的方式,我是完全無知的。所以我轉向你,我是否錯過了一些明顯的東西,這樣做是錯誤的,還是這是一個真正的謎團?
你能否在你的測試中預先設置'result'到vec3(0,0,0),以確保它不是事先搞定的值? (洋紅色沒有意義) –
@Clairvoire感謝您提及重置'result',它將我的注意力引向瞭解決方案。在遍歷所有光源的循環之前,「結果」被設置爲「vec3(0.0)」。問題是,循環迭代次數多於燈光,因此它使用的是不存在的數據。我會很快發佈一個答案。 – Jing