gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 02:39:01 34 4
gpt4 key购买 nike

我在将 2d Sprite 渲染到 GL Canvas 时遇到问题。当我的浏览器在较低分辨率的显示器上呈现时,它会以比在较高分辨率的显示器上呈现时更高的 FPS 呈现。

Mac Retina 显示屏:2880x1800 = ~20 FPS

外部显示器:1920x1080 = ~60 FPS

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

强制 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;

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

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 渲染。

最佳答案

根据 MDN 的 WebGL best practices :

Rendering to a canvas can be done at a different resolution than the style sheet will eventually force the canvas to appear at. If struggling with performance you should consider rendering to a low resolution WebGL context and using CSS to upscale its canvas to the size you intend.

<小时/>

WebGL 将根据 Canvas 的宽度和高度属性进行渲染。 Canvas 如下所示:<canvas width="256" height="256">将以 256x256 渲染。但是,您可以通过使用 CSS 设置 Canvas 样式来放大绘图: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}`);
canvas {
width: 512px;
height: 512px;
}
<canvas width="256" height="256">

<小时/>

查看代码后,您的游戏似乎“放大”的原因是因为您将 viewport 绑定(bind)在一起。到您的渲染尺寸。不要把这些结合起来。您的视口(viewport)设置绝对应该反射(reflect)您的纵横比,但应该独立于您的绘图尺寸。 WebGL 会将其默认为您的 Canvas 大小,但由于您想要放大,请尝试将其设置为放大后的 Canvas 大小,看看是否仍然可以缩放。从我上面的示例来看,代码如下所示:

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

哪里widthheight来自计算的元素的大小。

<小时/>

放大示例:

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

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);
canvas {
width: 512px;
height: 512px;
}
<canvas width="256" height="256"></canvas>
<canvas width="512" height="512"></canvas>

关于javascript - 降低 WebGL 渲染分辨率并提高 FPS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47699592/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com