我有一个着色器,可以为2D场景添加光照(灯光稍微高于2D平面)。在我的片段着色器中,我遍历每个光源,通过将我的邻域矩阵应用到光源的位置来计算方向和距离。
问题是,灯光的“半径”受窗口大小和宽高比的影响。我认为使用正交矩阵平移坐标将确保屏幕尺寸无关紧要,但是宽窗口产生椭圆形光,而较小窗口产生比较大窗口更小的椭圆。我应该使用某种其他矩阵吗?
此处为完整着色器(更改窗口大小以查看不需要的效果):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 :(得分:0)
需要根据屏幕分辨率缩放光线方向。我最后添加了以下代码使其工作,任意亮度为500左右:
light_direction *= vec3(resolution.x / brightness, resolution.y / brightness, 1.0);