Я использую свой собственный 3D-движок на JavaScript и использую только рисование на холсте, а не WebGL. Это еще один клон Minecraft; Я люблю коробки, не суди меня.
Пока что все работает чудесно, за исключением одного: в 3D, когда некоторые вершины идут за ближней плоскостью отсечения, их проекция на экран получается странной (если предположить, что другие вершины, используемые для трассировки плоскости, находятся впереди).
Я попытался обрезать эти точки, но затем я могу видеть поверхности, которые используют эти вершины. В WebGL / OpenGL графическая карта заботится об этих точках, и плоскость отображается правильно, но у меня нет доступа к оборудованию, поэтому я должен кодировать это сам.
Я не совсем уверен, что с этим делать, в настоящее время последнее, что пришло на ум, - это изменить проекцию точек позади плоскости отсечения игрока, что кажется логичным, поскольку я должен проецировать точку на экран, который находится впереди. вершины.
Вот мои мысли:
Вот несколько изображений, чтобы проиллюстрировать, что происходит:
С расстояния синяя коробка отрисовывается на отлично.
Когда некоторые вершины идут за плоскостью отсечения игрока, я делаю обратную проекцию, но она выглядит неправильно:
focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;
Обратите внимание, что серая рамка позади полностью удалена, поскольку все вершины, используемые для рисования граней, находятся позади игрока.
Вот что происходит, когда смотришь вверх или вниз.
Я не знаю, что делать с этой математикой, я надеюсь, что кто-то уже сталкивался с той же проблемой и может мне помочь.
источник
lineTo(x,y)
функция все еще может быть вызвана, только я не знаю, как она себя ведет ... это странное измерение, я согласен.Ответы:
Назначение ближней плоскости отсечения состоит в том, что это плоскость отсечения . Треугольники, находящиеся вне плоскости отсечения, обрезаются : разрезать на части так, чтобы каждый оставшийся фрагмент находился в области отсечения.
Вы можете попытаться игнорировать ближний клип, если хотите. Действительно, в OpenGL и D3D есть способы полного отключения отсечения вблизи плоскости (хотя буфер глубины все еще имеет минимальное значение вблизи). Проблема не в ближайшем клипе.
Проблема с вершинами, которые находятся за камерой.
Вы не можете визуализировать треугольники, которые находятся за камерой. Не с перспективной проекцией. Такие треугольники не имеют смысла в математике за перспективными проекциями. Кроме того, они также находятся за пределами усеченного конуса.
Выключение рядом с отсечкой превращает усеченный в пирамиду. Причина, по которой пирамида останавливается в этой точке, заключается в том, что точки над пирамидой находятся за всеми четырьмя сторонами пирамиды. Таким образом, любая точка позади камеры (кончик пирамиды) находится выше, ниже, слева и справа от видимой области экрана. Все одновременно.
Как я уже сказал: вершины в перспективной проекции, которые находятся за камерой, не имеют смысла.
Вы должны реализовать отсечение. Вы должны определить, находится ли какая-либо вершина треугольника в пространстве клипа ( до разделения перспективы) за камерой. Если это так, то вы должны обрезать этот треугольник, генерируя только треугольники, которые находятся перед камерой.
Это не простой процесс. Это будет включать математику, которая имеет смысл, только если у вас есть полное понимание однородных систем координат. Кроме того, вы можете просто отбросить любой треугольник, если какая-либо его вершина находится за камерой.
источник
Если часть треугольника находится позади ближней плоскости, можете ли вы выполнить проверку на пиксель, чтобы увидеть, находится ли позиция пикселя позади плоскости отсечения?
Вы можете относиться к ближней плоскости как к любой другой плоскости отсечения. Например, плоскости отсечения используются для таких вещей, как плоскости воды (для отражений и преломлений). Я бы подумал, что эта плоскость отсечения будет работать точно так же, как и ближняя плоскость отсечения, и обрезать по пикселям.
Я знаю, как обрабатывать плоскости отсечения в HLSL с DirectX, но их реализация может быть проприетарной. Если бы вы могли получить информацию для этого, это может быть полезно.
Кроме того, вот ссылка, которая может вам помочь: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html
источник