【问题标题】:Resize canvas without enlarge the elements WEBGL调整画布大小而不放大元素 WEBGL
【发布时间】:2019-05-13 06:59:32
【问题描述】:

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

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

用新的

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

但 html 中的数字会更大,我不想要。我只想调整包含元素的空间。

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

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

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

图形会小一半,但空间保持不变。我需要更多空间来播放动画,因为现在即使我还有很多可用空间(白色),动画也会在某些时候退出屏幕。

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

我的画布

Web Inspector 的详细信息

谢谢。

【问题讨论】:

    标签: javascript canvas graphics webgl interactive


    【解决方案1】:

    WebGL 要求您自己绘制项目以匹配大小。 WebGL 采用标准化坐标(称为剪辑空间)。无论大小,它们总是在画布上从 -1 到 +1,在画布上从 -1 到 +1。要通过 JavaScript 和/或 GLSL 着色器绘制任何你提供的数学运算,这些着色器会获取你提供的任何数据并将该数据转换为剪辑空间。这意味着,如果您希望项目保持相同大小,则需要调整用于绘制所绘制事物的数学。没有看到你的数学,我们真的不知道该建议什么。

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

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

    如果您直接使用剪辑空间坐标,则只需传入 X 和 Y 比例即可。如果画布变大两倍,则缩放一半,对象将保持相同大小。

    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 绘图,那么您必须根据画布的宽度或高度计算视野以保持对象大小相同,或者将相机移近或远离物体。

    要根据视野进行调整,您可以这样做

    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);
    

    请注意,此方法存在的问题是,随着画布变大,绘制到画布边缘的东西会变得越来越扭曲,因为视野变得越来越宽以保持所有东西的大小相同。当视野达到 180 度或更宽时,透视数学将中断并且无法显示。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多