降低WebGL渲染分辨率,并提高FPS

时间:2017-12-07 16:32:18

标签: javascript html webgl

我遇到了将2d精灵渲染到GL画布的问题。当我的浏览器使用较低分辨率的显示器时,其渲染速度高于在较高分辨率显示器上渲染时的速度。

Mac Retina显示:2880x1800 = ~20 FPS

外部监视器:1920x1080 = ~60 FPS

WebGL在我的1080分辨率显示器上以比在Mac视网膜显示器上更快的FPS渲染。

强制WebGL以较低分辨率渲染的最佳做法是什么?我一直在寻找资源来帮助回答这个问题,但在网上找不到任何东西。

我尝试按如下方式降低分辨率:

var ratio = 1
var width = $(window).width();
var height = $(window).height();
if (window.screen.height * window.devicePixelRatio > 1080) {
   ratio = 1080/(window.screen.height * window.devicePixelRatio);
}
width = width*ratio;
height = height*ratio;
gl.canvas.width = width;
gl.canvas.height = height;

然后像这样设置我的视口:

gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);

更新代码

var width = $(window).width();
var height = $(window).height();
if (window.screen.height * window.devicePixelRatio > 1080) {
   glTools.ratio = 1080/(window.screen.height * window.devicePixelRatio);
} else {
   glTools.ratio = 1;
}
width = Math.round(width*glTools.ratio);
height = Math.round(height*glTools.ratio);
glTools.gl.canvas.width = width;
glTools.gl.canvas.height = height;
glTools.gl.viewport(0, 0, width, height);

效果更新 虽然这个问题的答案是正确的。我只是想在我的视频游戏中指出我的FPS的另一个罪魁祸首。在我的代码中使用计时器并在我的游戏中执行非硬件加速的css动画设法阻止线程,因此导致渲染被安排在以后。 你可以看到游戏在Obsidio

时呈现60FPS

1 个答案:

答案 0 :(得分:2)

根据MDN' WebGL best practices

  

渲染到画布可以使用不同于分辨率的分辨率   样式表最终会强制画布出现在。如果   在努力表现时你应该考虑降低成绩   解析WebGL上下文并使用CSS将其画布升级为   你想要的大小。

WebGL将根据您的画布进行渲染。宽度和高度属性。看起来像这样的画布:<canvas width="256" height="256">将渲染为256x256。但是,您可以通过使用CSS设置画布样式来放大绘图:canvas {width: 512px;height: 512px;}将以放大的512x512显示渲染图像。

运行下面的代码段,您将看到输出:

[Canvas internal rendering] W: 256 | H: 256
[Actual canvas size] W: 512 | H: 512

&#13;
&#13;
const canvas = document.querySelector("canvas"),
  ctx = canvas.getContext("webgl"),
  {
    width,
    height
  } = canvas.getBoundingClientRect();

console.log(`[Canvas internal rendering] W: ${ctx.drawingBufferWidth} | H: ${ctx.drawingBufferHeight}`);
console.log(`[Actual canvas size] W: ${width} | H: ${height}`);
&#13;
canvas {
  width: 512px;
  height: 512px;
}
&#13;
<canvas width="256" height="256">
&#13;
&#13;
&#13;

在查看您的代码后,您的游戏似乎放大&#34;的原因是因为您将viewport绑定到渲染大小。不要把这些结合起来。您的视口设置应该绝对反映您的宽高比,但应该与您的绘图大小无关。 WebGL会将其默认为您的画布大小,但由于您想要升级,请尝试将其设置为放大的画布大小,看看您是否仍然可以进行缩放。从上面的例子中,代码看起来像:

ctx.viewport(0, 0, width, height);

widthheight来自计算元素的大小。

升级示例:

这是一个演示,显示了相同形状的不同渲染分辨率。您将在第一张图像中看到锯齿,但第二张图像应该清晰。

&#13;
&#13;
const vertSource = `
attribute vec3 a_position;
void main(void) {
    gl_Position = vec4((a_position * 2.0) - 1.0, 1.0);
}`;

const fragSource = `
void main(void) {
    gl_FragColor = vec4(1.0);
}`;

const verts = [
  0.1, 0.1, 0,
  0.9, 0.1, 0,
  0.5, 0.9, 0
];

function setupCanvas(canvas) {
  const gl = canvas.getContext("webgl");

  const {
    width,
    height
  } = canvas.getBoundingClientRect();

  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.enable(gl.DEPTH_TEST);
  gl.viewport(0.0, 0.0, gl.drawingBufferWidth, gl.drawingBufferHeight);

  console.log(`[Canvas internal rendering] W: ${gl.drawingBufferWidth} | H: ${gl.drawingBufferHeight}`);
  console.log(`[Actual canvas size] W: ${width} | H: ${height}`);

  const b = gl.createBuffer(),
    p = gl.createProgram(),
    v = gl.createShader(gl.VERTEX_SHADER),
    f = gl.createShader(gl.FRAGMENT_SHADER);

  gl.bindBuffer(gl.ARRAY_BUFFER, b);
  gl.shaderSource(v, vertSource);
  gl.compileShader(v);
  gl.shaderSource(f, fragSource);
  gl.compileShader(f);
  gl.attachShader(p, v);
  gl.attachShader(p, f);
  gl.linkProgram(p);
  gl.useProgram(p);

  const a = gl.getAttribLocation(p, "a_position");
  gl.vertexAttribPointer(a, 3, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(a);

  function draw() {
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.DYNAMIC_DRAW);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLES, 0, verts.length / 3);
  }
  draw();
}

Array.from(document.querySelectorAll("canvas"))
  .forEach(setupCanvas);
&#13;
canvas {
  width: 512px;
  height: 512px;
}
&#13;
<canvas width="256" height="256"></canvas>
<canvas width="512" height="512"></canvas>
&#13;
&#13;
&#13;