我有一個着色器,它將照明添加到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);
}
注:我知道這不是最佳的,使這個計算每個光,每個像素 - 我應該是使光的可能在另一個制服的位置。
我不知道爲什麼「正常」涉及紋理。你能解釋一下pixcoord是什麼或簡化這一點嗎?只需要一盞燈就能找出問題所在,對嗎?由於這是關於current_light的,而且它僅取決於light_direction和normal,所以您可以從該行刪除衰減並查看會發生什麼。 – AbleArcher
我試圖將它編輯一下......精靈有一個基本紋理和一個由碎片着色器使用的正常映射的紋理。 Pixcoord只是應用了正交矩陣之後的頂點着色器的位置。我使用正交矩陣來轉換精確的屏幕像素座標。 –
謝謝。你是否將相同的ortho_matrix應用於gl_Position以獲得像素點?在我看來,在片段着色器中做得更好。如果你完全刪除cel_light會發生什麼?如果問題仍然存在,那麼我們會到達某個地方。我不確定你的目標是用mix(vec3(-1),vec3(1),normal)',你能解釋一下嗎? – AbleArcher