当调整窗口大小或框架具有白色边框时,许多Three.js样本会闪烁。例如:http://threejs.org/examples/webgl_animation_skinning.html
另一方面,WebGL Aquarium不会闪烁。这是怎么做到的?
答案 0 :(得分:1)
AFAICT大多数Three.JS样本通过查看窗口大小或容器的大小来手动设置画布的大小,然后将canvas.width,canvas.height设置为匹配。
另一方面,包括WebGL Aquarium在内的TDL示例使用CSS让浏览器缩放画布,然后在requestAnimationFrame回调中更新画布后备存储的大小。
这是一个例子
const gl = document.querySelector("#c").getContext("webgl");
function render() {
resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// Draw a 2 pixel border around the edge using
// the scissor test since it's easier than setting up
// a lot of stuff
gl.clearColor(1, 0, 0, 1); // red
gl.disable(gl.SCISSOR_TEST);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.enable(gl.SCISSOR_TEST);
gl.scissor(2, 2, gl.canvas.width - 4, gl.canvas.height - 4);
gl.clearColor(0, 0, 1, 1); // blue
gl.clear(gl.COLOR_BUFFER_BIT);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
function resizeCanvasToDisplaySize(canvas) {
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
}
}
body {
margin: 0;
}
#c {
width: 100vw;
height: 100vh;
display: block;
}
<canvas id="c"></canvas>
答案 1 :(得分:1)
调整窗口大小后,您需要立即调用渲染。
更好的是你可以拥有requestAnimationFrame
并调整大小,然后在一个函数调用中渲染。它将确保回流和渲染在一次回流中直接发生,而不是分开导致闪烁。
答案 2 :(得分:1)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
}