Чтобы прояснить ответ datenwolf, отображение координат между вашим 3D-пространством и 2D-холстом - это именно то, что вы хотите.Вы управляете им с помощью gl.viewport
и матриц, которые вы передаете своему шейдеру.
gl.viewport
просто блокирует прямоугольник пикселей на холсте, на который вы рисуете.В большинстве случаев это точно соответствует размерам вашего холста, но есть некоторые сценарии, в которых вы хотите рисовать только его часть.(Например, игры с разделенным экраном.) С этого момента область холста, на которую вы рисуете, будет называться областью просмотра.Вы можете предположить, что это означает то же самое, что и «холст», если хотите.
В самом простом виде окно просмотра всегда имеет неявную систему координат от -1 до 1 по осям X и Y.Это пространство, в котором работает вывод gl_Position
вашего вершинного шейдера. Если вы выводите вершину в точке (-1, -1), она будет в левом нижнем углу окна просмотра.вершина в (1, 1) будет в правом верхнем углу.(Да, сейчас я игнорирую глубину.) Используя это, вы можете создать геометрию, предназначенную для отображения в этом пространстве и нарисовать ее без каких-либо матричных преобразований, но это может быть немного неудобно.
Чтобы сделатьжизнь проще, мы используем проекционные матрицы.Матрица проекции - это просто матрица, которая преобразует вашу геометрию из некоторого произвольного трехмерного пространства в пространство от -1 до 1, требуемое для области просмотра.Наиболее распространенной является перспективная матрица.То, как вы его создадите, будет выглядеть по-разному в зависимости от используемой вами библиотеки, но обычно это что-то вроде этого:
var fov = 45;
var aspectRatio = canvas.width/canvas.height;
var near = 1.0;
var far = 1024.0;
var projectionMat = mat4.perspective(fov, aspect, near, far);
Я не собираюсь вдаваться в то, что означают все эти значения, но вы можете четковидим, что мы используем ширину и высоту холста, чтобы помочь настроить эту проекцию.Это позволяет ему не выглядеть растянутым или сжатым в зависимости от размера холста.Однако все сводится к тому, что, взяв любую трехмерную точку в пространстве и умножив ее на эту матрицу, вы получите точку, которая отображается в это пространство от -1 до 1, принимая во внимание расстояние от «камеры» и все остальное.(На самом деле он может выходить за эти границы, но это просто означает, что он находится вне камеры.) Это то, что заставляет наши 3D-сцены выглядеть трехмерными.
Однако возможно также создать матрицу проекции специально для рисования 2D-геометрии.Это называется орфографической матрицей, и установка обычно выглядит примерно так:
var left = 0;
var top = 0;
var right = canvas.width;
var bottom = canvas.height;
var near = 1.0;
var far = 1024.0;
var projectionMat = mat4.ortho(left, right, bottom, top, near, far);
Эта матрица отличается от матрицы перспективы тем, что она полностью игнорирует компонент z вашей позиции.Вместо этого эта матрица преобразует плоские координаты, например пиксели, в диапазон от -1 до 1.Таким образом, ваши сцены не выглядят трехмерными, но легче точно контролировать, где что-то появляется на экране.Таким образом, используя матрицу выше, если мы дадим ей вершину в (16, 16, 0), она появится в (16, 16) на нашем холсте (при условии, что область просмотра имеет те же размеры, что и холст).Таким образом, когда вы хотите рисовать такие вещи, как плоские элементы пользовательского интерфейса, вам нужен именно такой тип матрицы!
Приятная часть в том, что, поскольку это просто значения, которые вы передаете шейдеру, вы можете использовать совершенно разные матрицы.от одного розыгрыша до следующего.Обычно вы рисуете всю свою трехмерную геометрию с помощью матрицы перспективы, а затем весь свой пользовательский интерфейс с ортогональной матрицей.
Извинения, если это было немного бессмысленно.Я никогда не был очень хорош в объяснении всего этого математического материала.