我遇到了将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答案 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
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;
在查看您的代码后,您的游戏似乎放大&#34;的原因是因为您将viewport
绑定到渲染大小。不要把这些结合起来。您的视口设置应该绝对反映您的宽高比,但应该与您的绘图大小无关。 WebGL会将其默认为您的画布大小,但由于您想要升级,请尝试将其设置为放大的画布大小,看看您是否仍然可以进行缩放。从上面的例子中,代码看起来像:
ctx.viewport(0, 0, width, height);
width
和height
来自计算元素的大小。
这是一个演示,显示了相同形状的不同渲染分辨率。您将在第一张图像中看到锯齿,但第二张图像应该清晰。
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;