调整大小 canvas 而不放大元素 WEBGL

Resize canvas without enlarge the elements WEBGL

我是 WebGl 的新手,我希望在不放大所有元素的情况下调整 canvas 的大小。 我尝试在 HTML 文件中编辑这行代码:

<canvas id="gl-canvas" width="512"" height="512">

用新的

<canvas id="gl-canvas" width="1024"" height="1024">

但是html里面的数字会更大,我不想要。我只想调整包含元素的 space 的大小。

我也试过这样做: 在 JS 文件中我试图编辑

gl.viewport( 0, 0, canvas.width, canvas.height );

gl.viewport( 0, 0, 0.5*canvas.width, 0.5*canvas.height );

数字会小一半,但space保持不变。我需要更多的 space 来制作动画,因为现在在某些时候动画会退出屏幕,即使我还有很多 space 可用(白色)。

我想上传一些照片来更好地解释我的观点

我的Canvas

Web 检查器的详细信息

谢谢。

WebGL 要求您自己绘制项目以匹配大小。 WebGL 在(称为 clip space)中采用归一化坐标。无论大小如何,它们总是在 canvas 范围内从 -1 到 +1,在 canvas 范围内总是从 -1 到 +1。要通过 JavaScript and/or GLSL 着色器绘制任何你提供的数学,它会获取你提供的任何数据并将该数据转换为剪辑 space。这意味着如果您希望项目保持相同大小,则需要调整用于绘制正在绘制的内容的数学。没有看到你的数学,我们真的不知道该建议什么。

在 WebGL 中绘制事物的最常见方法是将 2D 或 3D 数据乘以 1 个或多个矩阵。您可以阅读有关 here 的内容。您可能需要阅读该文章之前的文章才能理解该文章。您可能还希望阅读该文章之后的文章,因为它们从 2D 继续到 3D

因此,除了说由您决定解决数学问题的解决方案外,没有简单的答案。在不知道您使用的数学方法的情况下,我们无法建议保持大小不变​​的方法。

如果您直接使用剪辑 space 坐标,那么您可以只传入 X 和 Y 比例。如果 canvas 变大两倍,则缩放一半,对象将保持相同大小。

gl_Position = someClipspaceCoordinates * vec4(scaleX, scaleY, 1, 1);

如果您使用的是 an orthographic projection,那么您将选择每个像素的一些单位数并调整您传递给正交投影矩阵制作函数的值

const pixelsPerUnit = ???;
const unitsAcross = gl.canvas.clientWidth / pixelsPerUnit;
const unitsDown = gl.canvas.clientHeight / pixelsPerUnit;

// assuming you want 0,0 at the center
const left   = -unitsAcross / 2;
const right  =  unitsAcross / 2;
const bottom = -unitsDown / 2;
const top    =  unitsDown / 2;
const near   = ???;
const far    = ???;

const projectionMatrix = someOrthographicProjectionMatrixFunction(
    left, right, bottom, top, near, far);

如果您使用 perspective projection 进行 3D 绘图,则必须根据 canvas 的宽度或高度计算视野,以保持对象大小相同,或者,将相机移近或远离物体。

要根据视野进行调整,您需要做类似的事情

const fovPerPixel = 0.1 * Math.PI / 180;
const fov = gl.canvas.clientHeight * fovPerPixel;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const near = 0.5;
const far = 1000;
const projectionMatrix = somePerspectiveProjectionMatrixFunction(
    fov, aspect, near, far);

请注意,此方法存在一个问题,即随着 canvas 变大,向 canvas 边缘绘制的东西会随着视野越来越宽而变得越来越扭曲保持一切相同的大小。当视野达到 180 度或更宽时,透视数学将中断并且不会显示内容。

要通过移动相机进行调整,请参阅 this answer 作为起点。