Это немного сложная задача, поэтому я сделаю все возможное, чтобы разбить ее на части.
Я пишу 3D-библиотеку Python для обучения/развлечения (в отличие от той, которую я намеревался использовать для других). В системе, которую я разработал, трехмерные точки обычно выравниваются по изображению следующим образом:
- Увеличение индекса Z на
width
перемещает точку на полпути к точке схода в центре. - В
Z = 0
значения X и Y соответствуют непосредственно пикселю в X, Y.
(У этого метода может быть название, но если оно и есть, то я с ним не знаком.)
В Питоне:
# vx and vy are the vanishing point's coordinates
def flatten_point(width, vx, vy, x, y, z):
distance = (x - vx, y - vy)
flat_distance = [d / (1 + float(z) / width) for d in distance]
return (vx + flat_distance[0], vx + flat_distance[1])
На данный момент я могу довольно эффективно создавать треугольники, сглаживая их вершины и используя барицентрические координаты, чтобы найти и заполнить пиксели, находящиеся между этими тремя точками. Это работает достаточно хорошо, если мне не нужно ничего знать о фактических точках треугольника, которым соответствуют эти пиксели, но если я хочу затенить треугольник, чтобы более глубокие точки были темнее, мне нужно знать, что несглаженная точка на треугольнике, которому соответствует пиксель.
joriki на math.stackexchange рекомендовал использовать барицентрические координаты в качестве весов для нахождения исходной точки. Какое-то время это действительно работало — и, вероятно, сработало бы, если бы я использовал линейную систему глубины, — но оно разваливается, когда глубины точек треугольника достаточно различаются. Кажется, что треугольник приближается к наибольшей глубине быстрее, чем на самом деле, как если бы он был выгнут назад.
Итак, вкратце: как я могу обратить функцию выравнивания точек, чтобы получить фактическую 3D-точку произвольного 2D-пикселя на сплющенном треугольнике? В качестве альтернативы, если есть лучший/более эффективный способ сглаживания треугольников без потери глубины каждого пикселя, это тоже сработает.