2014-02-20 48 views
0

我有一個着色器,它將照明添加到2D場景(光線略高於2D平面)。在我的片段着色器中,我通過將每個光線循環通過將正交矩陣應用於光源的pos來計算方向和距離。具有着色器的2D照明 - 受窗口大小影響的光半徑

問題是,燈的「半徑」受到窗口大小和縱橫比的影響。我認爲使用正交矩陣來轉換座標將確保屏幕尺寸無關緊要,但是寬的窗口會產生橢圓形的光線,而較小的窗口會產生比較大窗口更小的橢圓。我應該使用另一種矩陣嗎?

這裏完全Shader(改變窗口大小,看不需要的效果):http://glsl.heroku.com/e#14464.0

uniform vec2 resolution; 

void main(void) 
{ 
    //orthographic matrix 
    mat4 ortho_matrix = mat4(
     2.0/resolution.x, 0, 0, 0, 
     0, 2.0/-resolution.y, 0, 0, 
     0, 0, -1, 0, 
     -1, 1, 0, 1 
     ); 

    //surface normal of the 2D plane (looking straight down) 
    vec3 surface_normal = vec3(0.0, 0.0, 1.0); 

    //screen position of the light 
    vec2 light_screen_pos = vec2(650, 150); 

    //translate light's position to normalized coordinates 
    //the z value makes sure it is slightly above the 2D plane 
    vec4 light_ortho_pos = ortho_matrix * vec4(light_screen_pos, -0.03, 1.0); 

    //calculate the light for this fragment 
    vec3 light_direction = light_ortho_pos.xyz - vec3(gl_FragCoord.x/resolution.x, gl_FragCoord.y/resolution.y, 0); 
    float dist = length(light_direction); 
    light_direction = normalize(light_direction); 
    vec3 light = clamp(dot(surface_normal, light_direction), 0.0, 1.0) * vec3(0.5, 0.5, 0.5); 
    vec3 cel_light = step(0.15, (light.r + light.g + light.b)/3.0) * light; 

    gl_FragColor = vec4(pow(light + cel_light, vec3(0.4545)), 1.0); 
} 

注:我知道這不是最佳的,使這個計算每個光,每個像素 - 我應該是使光的可能在另一個制服的位置。

+0

我不知道爲什麼「正常」涉及紋理。你能解釋一下pixcoord是什麼或簡化這一點嗎?只需要一盞燈就能找出問題所在,對嗎?由於這是關於current_light的,而且它僅取決於light_direction和normal,所以您可以從該行刪除衰減並查看會發生什麼。 – AbleArcher

+0

我試圖將它編輯一下......精靈有一個基本紋理和一個由碎片着色器使用的正常映射的紋理。 Pixcoord只是應用了正交矩陣之後的頂點着色器的位置。我使用正交矩陣來轉換精確的屏幕像素座標。 –

+0

謝謝。你是否將相同的ortho_matrix應用於gl_Position以獲得像素點?在我看來,在片段着色器中做得更好。如果你完全刪除cel_light會發生什麼?如果問題仍然存在,那麼我們會到達某個地方。我不確定你的目標是用mix(vec3(-1),vec3(1),normal)',你能解釋一下嗎? – AbleArcher

回答

0

光線方向需要根據屏幕分辨率進行縮放。我結束了添加以下代碼,使其工作,任意亮度500左右:

light_direction *= vec3(resolution.x/brightness, resolution.y/brightness, 1.0); 
+0

這不正好取消你已經完成的縮放嗎? – AbleArcher

+0

正交矩陣將光線投射到屏幕上的正確位置,但光線形狀(其明顯的「半徑」)不會受到影響,直到我縮放方向計算爲止。 –