Изменение текстуры на сетке при заданной мировой координате

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

Технически у меня есть карта высот, которую я хочу изменить на определенном texcoord, который я выбираю с помощью мыши. Для этого я сначала перехожу от экранных координат к мировому положению - я это сделал. Следующий шаг, переходя от мирового положения к выбору правильной текстурной координаты, меня озадачивает. Как это сделать?

Ответ 1

Если вы используете простую карту hightmap, которую вы используете в качестве карты смещения, давайте скажем направление y. Базовая сетка лежит в xz-равнине (y = 0).

Вы можете отменить координату y из координаты мира, которую вы рассчитали, и получить точку на базовой сетке. Оттуда вы можете сопоставить его текстурному пространству таким образом, вы нарисуете свою текстуру.

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

Ответ 2

Предполагая, что ваш ландшафт представляет собой простой прямоугольник, вы сначала вычисляете вектор между положением мыши и положением вашего ландшафта. (Вершина вашего квадрата местности, где отображается верхний левый угол вашей карты высот). Например. mouse (50,25) - origin(-100,-100) = (150,125).
Теперь разделите координаты x и y на ширину и высоту мирового пространства вашего квадроцикла. 150 / 200 = 0.75 и 125 / 200 = 0.625. Это дает вам координаты текстуры, если вы нуждаетесь в них в качестве координат пикселей, вместо этого просто умножайте размер вашей текстуры.

Ответ 3

Я предполагаю следующее:

  • Координаты мира, которые вы вычислили, - это указатели мыши в представлении frustrum. Я называю их mouseCoord
  • У нас также есть координаты камеры, camCoord
  • Мир состоит из треугольников
  • Каждая точка треугольника имеет координаты текстуры, которые интерполируются барицентрическими координатами.

Если это так, решение будет выглядеть следующим образом:

  • используйте camCoord как источник. Вычислите направление луча как mouseCoord - camCoord.
  • Вычислить точку пересечения с треугольником. Наивный вариант состоит в том, чтобы проверять каждый треугольник, если он пересекается, более сложным было бы исключить несколько треугольников сначала каким-то другим алгоритмом, например, разделить мир в кубах, проследить лук вдоль кубов и посмотреть только на треугольники с перекрытиями с кубом. Пересечение с треугольником можно вычислить как на этом сайте: http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
  • Вычислить барицентрические координаты точек пересечения относительно этого треугольника, например: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
  • Используйте барицентрические координаты в качестве весов для координат текстуры соответствующих точек треугольника. Результатом являются координаты текстуры точки пересечения, а также то, что вы хотите.

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

Другой вариант, определенный для карты высоты:

Предполагается, что предположения изменяются следующим образом:

  1. В мире есть наземная плитка над x и y
  2. Наземные плитки имеют значения высоты в углах.
  3. Для точки внутри плитки значение высоты интерполируется каким-то образом, например, путем билинейной интерполяции.
  4. Текстура интерполируется таким же образом, снова с заданными координатами текстуры для углов

Допустимый алгоритм для этого (аппроксимативный):

  • Опять же, вычислите начало и направление.
  • Wlog, мы предполагаем, что направление имеет более высокое изменение в направлении x. Если нет, замените x и y в алгоритме.
  • Проследите луч в заданной длине шага для x, т.е. на каждом шаге x-координата изменяется на эту длину шага. (возьмите направление, умножьте его на размер шага, деленное на его значение x, добавьте это новое направление в текущую позицию, начиная с начала координат)
  • Для вашей текущей координаты проверьте, находится ли значение z ниже текущей высоты (ака только что столкнулась с землей).
  • Если это так, закончите или уменьшите размер шага и сделайте более тонкий поиск в этой окрестности, идите назад, пока не будете выше высоты, а затем, возможно, перейдите вперед еще более мелкие шаги снова и снова. Результатом являются текущие координаты x и y
  • Вычислить относительное положение ваших координат x и y в текущей плитке. Используйте это для весов для координат угловой текстуры.

Этот алгоритм теоретически может перепрыгнуть через очень тонкие вершины. Выберите небольшой размер шага, чтобы противостоять этому. Я не могу дать точный алгоритм, не зная, какой тип интерполяции использует карта высоты. Может быть, не самая худшая идея создать треугольники в любом случае, возможно, из билинейных интерполированных координат? В любом случае алгоритм хорош, чтобы найти фрагмент, в котором он сталкивается.

Другим вариантом было бы проследить лучи над точками, в которых х-у-координаты пересекают сетку плитки, а затем посмотреть, изменилась ли координата z ниже карты высоты. Тогда мы знаем, что он сталкивается в этой плитке. Это может привести к ложному отрицанию, если высота может быть больше внутри плитки, чем на ее краях, поскольку могут проявляться некоторые формы интерполяции, особенно те, которые рассматривают соседние плитки. Однако работает отлично с билинейной интерполяцией.

В билинейной интерполяции точное пересечение может быть найдено следующим образом: Возьмем две (x, y) координаты, в которых сетка пересекается лучом. Вычислите высоту тех, которые извлекают две (x, y, z) координаты. Создайте из них линию. Вычислите пересечение этой линии с лучом. Их пересечением является пересечение с картой высоты плитки.

Ответ 4

Самый простой способ - отобразить сетку как предварительный проход с uvs в качестве цвета. Никакой экран в мире не нужен. Uv - значение в позиции мыши. Просто будьте осторожны, хотя с mips/filtering etv