如何利用物理原理来避免运动模糊?
P5.js用于渲染,但这可以在任意语言和图形库中实现(并非引擎)。
在没有固定时间步和插值的情况下移动对象会很清晰;但使用固定时间步和插值时,画面会变得模糊。去掉插值也会让它显得卡顿,原因很明显。
沙盒: editor.p5js.org,把左侧的示例粘贴进去,然后用按钮或 ctrl + enter 运行。
const step = 1 / 60; // Physics step
let acc = 0; // Accumulator
let pos1; // Upper rectangle
let lastPos1; // Last position of the upper rectangle
let pos2; // Lower rectangle
// The function is called once (init)
function setup() {
createCanvas(windowWidth, windowHeight); // Create the canvas
frameRate(144); // Set the number of frames per second
// Initialize the rectangle positions
pos1 = createVector(0, height / 2 - 100);
pos2 = createVector(0, height / 2);
}
// The function is called every frame
function draw() {
background(220); // Fill the background
acc += deltaTime / 1000; // Increase the accumulator
lastPos1 = pos1; // Store the last position of the top rectangle
while (acc >= step) {
// While the accumulator is greater than the physics step
pos1.x += 100 * step; // Move the top rectangle to the right
acc -= step; // Decrease the accumulator
}
pos2.x += 100 * (deltaTime / 1000); // Move the bottom rectangle to the right
const alpha = acc / step; // Interpolation coefficient
// Position interpolation
const interpPos = p5.Vector.lerp(lastPos1, pos1, alpha);
// Top rectangle (moves: physics)
rect(interpPos.x, interpPos.y, 200, 50);
// Bottom rectangle (moves: render)
rect(pos2.x, pos2.y, 200, 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/p5.js"></script>
解决方案
我错过了一个链接,导致我得出了错误的结论。
-lastPos1 = pos1;
+lastPos1 = pos1.copy();
并把上一次的位置更新移到物理循环中,在当前这次之前。
const step = 1 / 60; // Physics step
let acc = 0; // Accumulator
let pos1; // Upper rectangle
let lastPos1; // Last position of the upper rectangle
let pos2; // Lower rectangle
// The function is called once (init)
function setup() {
createCanvas(windowWidth, windowHeight); // Create the canvas
frameRate(144); // Set the number of frames per second
// Initialize the rectangle positions
pos1 = createVector(0, height / 2 - 100);
lastPos1 = pos1.copy();
pos2 = createVector(0, height / 2);
}
// The function is called every frame
function draw() {
background(220); // Fill the background
acc += deltaTime / 1000; // Increase the accumulator
// Store the last position of the top rectangle
while (acc >= step) { // While the accumulator is greater than the physics step
lastPos1 = pos1.copy();
pos1.x += 100 * step; // Move the top rectangle to the right
acc -= step; // Decrease the accumulator
}
pos2.x += 100 * (deltaTime / 1000); // Move the bottom rectangle to the right
const alpha = acc / step; // Interpolation coefficient
// Position interpolation
const interpPos = p5.Vector.lerp(lastPos1, pos1, alpha);
// Top rectangle (moves: physics)
rect(interpPos.x, interpPos.y, 200, 50);
// Bottom rectangle (moves: render)
rect(pos2.x, pos2.y, 200, 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/p5.js"></script>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。