我正在寫一個Phong底紋的小測試,並且正在試圖讓我的頭靠在一堵磚牆上試圖讓鏡面組件工作。它似乎能夠正常工作,除了鏡面光線被應用於物體後部的前部&。 (該物體本身是透明的,手動對面對CPU側進行排序。)鏡面照明出現在對象的眼睛和背面兩側
請注意,漫反射組件完美工作(只在面對光源的一側顯示) - 這似乎排除了與法線到達片段着色器,我想。
據我所知,鏡面反射分量與反射光矢量的眼矢量之間的角度的cos成正比。
爲了讓事情變得非常簡單,我的測試代碼試圖在世界空間中做到這一點。相機位置和光矢量分別以(0,0,4)
和(-0.707, 0, -0.707)
進行硬編碼(對不起)。眼球矢量因此是(0,0,4) - fragPosition
。
由於模型矩陣只執行旋轉,所以頂點着色器只是通過模型矩陣變換頂點法線。 (注意:這是不好的做法,因爲許多類型的轉換不保留正常的正交性。一般對於正常矩陣,you should use是模型矩陣的左上角3x3的逆轉置。)爲了簡單起見,片段着色器在單個浮點顏色通道上運行,並跳過鏡面指數(/使用1的指數)。
頂點着色器:
#version 140
uniform mat4 mvpMtx;
uniform mat4 modelMtx;
in vec3 inVPos;
in vec3 inVNormal;
out vec3 normal_world;
out vec3 fragpos_world;
void main(void) {
gl_Position = mvpMtx * vec4(inVPos, 1.0);
normal_world = vec3(modelMtx * vec4(inVNormal, 0.0));
fragpos_world = vec3(modelMtx * vec4(inVPos, 1.0));
}
片段着色器:
#version 140
uniform float
uLightS,
uLightD,
uLightA;
uniform float uObjOpacity;
in vec3 normal_world, fragpos_world;
out vec4 fragOutColour;
void main(void) {
vec3 vN = normalize(normal_world);
vec3 vL = vec3(-0.707, 0, -0.707);
// Diffuse:
// refl in all directions is proportional to cos(angle between -light vector & normal)
// i.e. proportional to -l.n
float df = max(dot(-vL, vN), 0.0);
// Specular:
// refl toward eye is proportional to cos(angle between eye & reflected light vectors)
// i.e. proportional to r.e
vec3 vE = normalize(vec3(0, 0, 4) - fragpos_world);
vec3 vR = reflect(vL, vN);
float sf = max(dot(vR, vE), 0.0);
float col = uLightA + df*uLightD + sf*uLightS;
fragOutColour = vec4(col, col, col, uObjOpacity);
}
我不能在這裏找到一個錯誤;任何人都可以解釋爲什麼鏡面組件出現在背面以及物體的面向光的一側?
非常感謝。
需要sccreenshot效果,你使用什麼幾何? –
此外,這是可怕的,你應該把方向是作爲制服,並有一個單獨的矩陣來轉換法線,而統一的尺度是必需的,這是唯一的,如果一個統一的尺度是一個等距,這並非總是如此。 –
嗨亞歷克,對於硬編碼的方向抱歉,試着想像他們是制服。我這樣做是爲了讓它們超簡單,但我在這裏找不到一個不一致的地方。屏幕截圖:http:/ben.am/temp/specular-problem.png – ASpence