Изменение текстуры на сетке при заданной мировой координате
Я создаю редактор, в котором я хочу построить карту местности. Я хочу использовать мышь для увеличения/уменьшения высоты местности для создания гор и озер.
Технически у меня есть карта высот, которую я хочу изменить на определенном 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
- Используйте барицентрические координаты в качестве весов для координат текстуры соответствующих точек треугольника. Результатом являются координаты текстуры точки пересечения, а также то, что вы хотите.
Если я неправильно понял, что вы хотели, отредактируйте свой вопрос с дополнительной информацией.
Другой вариант, определенный для карты высоты:
Предполагается, что предположения изменяются следующим образом:
- В мире есть наземная плитка над x и y
- Наземные плитки имеют значения высоты в углах.
- Для точки внутри плитки значение высоты интерполируется каким-то образом, например, путем билинейной интерполяции.
- Текстура интерполируется таким же образом, снова с заданными координатами текстуры для углов
Допустимый алгоритм для этого (аппроксимативный):
- Опять же, вычислите начало и направление.
- Wlog, мы предполагаем, что направление имеет более высокое изменение в направлении x. Если нет, замените x и y в алгоритме.
- Проследите луч в заданной длине шага для x, т.е. на каждом шаге x-координата изменяется на эту длину шага. (возьмите направление, умножьте его на размер шага, деленное на его значение x, добавьте это новое направление в текущую позицию, начиная с начала координат)
- Для вашей текущей координаты проверьте, находится ли значение z ниже текущей высоты (ака только что столкнулась с землей).
- Если это так, закончите или уменьшите размер шага и сделайте более тонкий поиск в этой окрестности, идите назад, пока не будете выше высоты, а затем, возможно, перейдите вперед еще более мелкие шаги снова и снова. Результатом являются текущие координаты x и y
- Вычислить относительное положение ваших координат x и y в текущей плитке. Используйте это для весов для координат угловой текстуры.
Этот алгоритм теоретически может перепрыгнуть через очень тонкие вершины. Выберите небольшой размер шага, чтобы противостоять этому. Я не могу дать точный алгоритм, не зная, какой тип интерполяции использует карта высоты. Может быть, не самая худшая идея создать треугольники в любом случае, возможно, из билинейных интерполированных координат? В любом случае алгоритм хорош, чтобы найти фрагмент, в котором он сталкивается.
Другим вариантом было бы проследить лучи над точками, в которых х-у-координаты пересекают сетку плитки, а затем посмотреть, изменилась ли координата z ниже карты высоты. Тогда мы знаем, что он сталкивается в этой плитке. Это может привести к ложному отрицанию, если высота может быть больше внутри плитки, чем на ее краях, поскольку могут проявляться некоторые формы интерполяции, особенно те, которые рассматривают соседние плитки. Однако работает отлично с билинейной интерполяцией.
В билинейной интерполяции точное пересечение может быть найдено следующим образом: Возьмем две (x, y) координаты, в которых сетка пересекается лучом. Вычислите высоту тех, которые извлекают две (x, y, z) координаты. Создайте из них линию. Вычислите пересечение этой линии с лучом. Их пересечением является пересечение с картой высоты плитки.
Ответ 4
Самый простой способ - отобразить сетку как предварительный проход с uvs в качестве цвета. Никакой экран в мире не нужен. Uv - значение в позиции мыши. Просто будьте осторожны, хотя с mips/filtering etv