Изменить размер холста без увеличения элементов WEBGL - PullRequest
2 голосов
/ 13 мая 2019

Я новичок в 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 );

фигура будет вдвое меньше, но пространство останется прежним. Мне нужно больше места для анимации, потому что теперь в какой-то момент анимация покидает экран, даже если у меня еще есть много свободного места (белого цвета).

Я хочу загрузить несколько фотографий, чтобы лучше объяснить мою точку зрения

Мой холст

My canvas

Сведения о веб-инспекторе

details of web inspector

спасибо.

1 Ответ

2 голосов
/ 13 мая 2019

WebGL требует, чтобы вы сами рисовали элементы в соответствии с размером. WebGL принимает нормализованные координаты в (называемое пространство клипа). Они всегда идут от -1 до +1 по холсту и от -1 до +1 по холсту независимо от размера. Чтобы нарисовать все, что вы предоставляете, с помощью JavaScript и / или GLSL-шейдеров, которые берут все предоставленные вами данные и преобразуют их в пространство клипа. Это означает, что если вы хотите, чтобы элементы оставались одинакового размера, вам нужно настроить математику, которую вы используете для рисования объектов, которые вы рисуете. Не видя твоей математики, мы не можем знать, что предложить.

Самый распространенный способ рисования объектов в WebGL - это умножение 2D или 3D данных на 1 или более матриц. Вы можете прочитать об этом здесь . Возможно, вам придется прочитать статьи до этого, чтобы понять это. Вы также можете прочитать статьи после этой, поскольку они переходят с 2D на 3D

Итак, тогда нет простого ответа, кроме как сказать, что вам решать, как исправить математику. Не зная, какую математику вы используете, мы не можем предложить способ сохранить размер таким же.

Если бы вы использовали координаты пространства клипа напрямую, то вы могли бы просто передать в масштабе X и Y. если холст становится в два раза больше, то масштабируется вдвое меньше, а объекты остаются одинакового размера.

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

Если бы вы использовали ортографическую проекцию , вы бы выбрали некоторое количество единиц на пиксель и скорректировали значения, которые вы передаете в функцию создания матрицы ортографической проекции

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

Если вы рисуете в 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 градусов или шире, математика перспективы нарушается и все не отображается.

Чтобы отрегулировать, перемещая камеру, см. этот ответ в качестве отправной точки.

...