游戏相机移动时非跟随对象抖动拖影问题技术求助
相机移动时对象抖动拖影的原因及解决办法
从你的描述和代码来看,这个抖动+拖影的问题大概率是相机位置的浮点精度与屏幕像素离散性的冲突导致的,咱们来一步步拆解:
核心原因
你用了平滑插值的方式计算相机位置:
x+= (xTo-x)/camera_speed_width; y+= (yTo-y)/camera_speed_height;
这种计算会让相机的x和y变成浮点数值,但显示器的像素是离散的整数坐标。当相机处于非整数位置时,所有对象的屏幕坐标都会带有小数,GPU会对这些亚像素位置的对象进行采样,相邻帧的采样结果细微变化就会产生视觉上的抖动;而拖影则是因为对象在像素边界来回“晃”,大脑会把连续的偏移看成拖影。
另外,你设置相机矩阵时直接用了这个浮点位置,没有做像素对齐处理,这就把问题放大了。
解决方案
1. 强制相机位置取整
在设置相机矩阵之前,把相机的x和y转成整数,让相机严格对齐像素:
x+= (xTo-x)/camera_speed_width; y+= (yTo-y)/camera_speed_height; x=clamp(x, CAMERA_WIDTH/2, room_width-CAMERA_WIDTH/2); y=clamp(y, CAMERA_HEIGHT/2, room_height-CAMERA_HEIGHT/2); // 新增:将相机位置取整,对齐像素 x = round(x); y = round(y); if (follow != noone) { xTo=follow.x; yTo=follow.y; } var _view_matrix = matrix_build_lookat(x,y,-10,x,y,0,0,1,0); var _projection_matrix = matrix_build_projection_ortho(CAMERA_WIDTH,CAMERA_HEIGHT,-10000,10000) camera_set_view_mat(camera,_view_matrix); camera_set_proj_mat(camera,_projection_matrix);
这样相机每帧都落在整数像素位置,所有对象的屏幕坐标也会是整数,彻底解决亚像素采样导致的抖动。
2. 开启全局像素对齐
如果你不想修改相机位置的平滑逻辑,可以在游戏初始化时开启GPU像素对齐:
gpu_set_pixel_snap(1);
这个函数会强制所有绘制的对象自动对齐到最近的像素,即使相机是浮点位置,对象也不会出现亚像素偏移,抖动和拖影会大幅减轻。
3. 调整相机平滑参数
如果你的camera_speed_width和camera_speed_height设置得太小,相机需要很多帧才能逼近目标位置,会持续产生细微的位置变化。可以适当调大这两个值,让相机更快跟上角色,减少浮点位置的持续波动。
额外注意点
如果你的跟随角色follow的位置也是浮点值,那即使相机取整,角色的位置偏移也可能导致相机频繁微调。这种情况下可以把角色的x和y也做取整处理,或者让角色的移动逻辑基于整数坐标。
内容的提问来源于stack exchange,提问作者codingpro88




