Обо мне
Привет! Меня зовут Лис и это мой блог. Здесь я могу ныть и страдать, писать про код и обо всем.
Январь 2025
ПнВтСрЧтПтСбВс
12345
6789101112
13141516171819
20212223242526
2728293031
Теги
Блог страдающего Лиса
Lorem ipsum hello dolor sit world amet

13 янв 2025 Пн Насколько много необходимо вычислений для рендера простой сцены...

Сейчас вот писал статью по определению расстояния от точки до плоскости (на самом деле это очень простая формула, но выводить ее муторно) и думал, насколько сложно сделать так, чтобы нарисовать хотя бы раз, пусть даже это займет много времени, но простую сцену?
Конечно, если рассчитывать все "в лоб", то займет это прилично времени, для любого процессора с любыми вычислительными возможностями. Но а если не пытаться рисовать так, а как-то может, оптимизировать? К примеру, рисовать только те треугольники, которые видать на сцене, это первое. Второе, рисовать последовательно, а не вычисляя сцену по тысячу раз.
Для статического кадра, хотя, для любого кадра, можно сначала рассчитать параметры треугольников, которые будут позже использоваться для рендера и записать их куда-нибудь в память. Если к примеру, рисуем 1000 треугольников, то для того чтобы нарисовать сцену из 640 на 400, надо будет 256 млн вычислений. На деле, это не настолько уж много для современных процессоров и такое дело можно рассчитать на 32 ядрах с использованием SIMD за доли секунды. Но, однако, скорость все равно недостаточная, потому что 1000 треугольников это реально ни о чем же. Речь может идти о миллионах треугольников на сцене! Какие там 1000... И тогда считать будет намного дольше. Нужна определенная оптимизация.
Как это сделать? Наверняка, нет необходимости обсчитывать абсолютно все треугольники подряд, можно определить с какого момента начинается треугольник и только тогда его начинать рисовать.
С другой стороны, я бы хотел для начала, вообще просто через wireframe графику, просто проверить, а насколько много мне потребуется треугольников, вообще? Я ведь даже не пытался что-либо рисовать даже через wireframe, а почему бы не попробовать хоть раз это сделать.
Теги: 3D

10 янв 2025 Пт Что-нибудь, помимо куба

Мне кажется, я с кубами совсем застрял в этом пространстве жизни. Почему бы мне не сделать что-то другое, кроме куба? Сколько не делаю, все время делаю только куб и ничего больше. А что я еще могу сделать и как? У меня нет идей по этому поводу. Передо мной много объектов, которые можно было бы сделать, но ничего не делаю. Надо бы с чего-то начать, а может даже, с редактора трехмерных объектов, чтобы можно было реально, сделать уже что-то.
Надо бы написать программу, которая бы рендерила бы трехмерные изображения, отсекая невидимые линии от граней. Думаю, надо сделать эту программму сначала именно в JS, а потом уже написать статьи на сайте об этом.
Теги: 3D

31 дек 2024 Вт Скрытие невидимых линии

Однажды у меня была книга про трехмерную графику на Basic, и всё бы ничего, если бы не одна интересная глава в книге. В ней рассказывалось о том, как сделать так, чтобы линии, которые рисовались, могли скрываться за другими выпуклыми фигурами. Это оставило впечатление на меня, и я до сих пор не могу понять, как это сделать.
Если разобраться, то процесс сокрытия линий в целом простой. Допустим, нам надо провести трехмерную линию и проверить, где и в какой точке она будет отрезаться лежащим перед ней объектом. Для этого надо проверить все пересечения линии всех объектов.
То есть, если взять линию, то надо просмотреть все грани фигур на трехмерной сцене и сравнить. Могут быть следующие случаи.
  • Один конец линии начинается за гранью и заканчивается тоже за гранью. Такую линию вообще не выводить
  • Первая точка линии начинается перед гранью, а вторая за гранью. Необходимо отрезать линию в том месте, где она пересекает грань. И закончить на этом.
  • Первая точка линии начинается перед гранью, вторая тоже, и причем обе точки пересекли эту грань. Надо найти точки пересечения грани, после чего найти срединную точку и проверить, где она находится. Если она находится перед гранью, то тогда линия выводится без обрезки. Если за гранью, то вырезается кусок линии в точке пересечения.
Как видно, подобного рода вычисления отнимают колоссальные вычислительные ресурсы и вообще, реализация довольно сложна. Такой способ весьма далек от реальной эффективности.
A B
Выше приведен пример такой линии, которая не рисуется за гранью.
Теги: 3D

20 дек 2024 Пт Технологии графики 3D: Отбрасывание теней

Вчера я задумался насчет 3Д графики и понял, что если не сделать тени, то в таком случае графика будет слишком неинтересной и пресной. Но как сделать тени? Этот вопрос мучает меня до сих пор в очень огромных масштабах.
В графических программах основным строительным блоком является треугольник, и он должен отбрасывать тень на другие треугольники, если они там есть. Есть множество различных способов высчитывать тень, но я хочу рассмотреть пока что одну из самых для меня доступных для понимания.
Допустим, что есть только 3 объекта на сцене: источник света L, треугольник A (который отбрасывает тень) и второй треугольник B (на который отбрасывается тень). Сама по себе тень образует некий треугольный конус, в который может полностью, частично или вообще не попасть треугольник, на который эта тень отбрасывается.
trg.gif
Задача в том, чтобы проверить, попадает ли тень на второй треугольник. Для этого надо провести из точки L через каждую точку треугольника A прямую и проверить, где именно на плоскости треугольника B попадет эта прямая. Если треугольник лежит параллельно этой прямой, то это значит что эта прямая, собственно, нигде треугольник не пересечет.
По итогу получится что-то вроде проекции на плоскость, где лежит треугольник B. Это значит, что от трехмерных координат мы переходим к двухмерным, что дает возможность определить область попадания тени на треугольник B.
shadow1.gif
Вот тут конечно, начинается самое интересное. Как видно, проекция тени A1'A2'A3' пересекла треугольник B в двух местах, раздробив изначально простые треугольнки на большое количество составляющих.
  • Раздробилась сама проекция тени, образовав дочерние теневые треугольники 1,2 и 3
  • А также раздробился исходный треугольник, разделившись на две группы — 4 и 5 (там где легла тень) и 6,7,8 там где тени нет
Как видно, этот способ, который я рассказываю, дробит треугольники на огромное количество других треугольников, что дает огромную нагрузку на вычислительные мощности процессора, который эту вакханалию будет обрабатывать.
Так что я думаю, что этот подход удобен только в качестве учебного пособия, не более того. С другой стороны, этот метод является "запеканием" теней и в каком-то смысле, удобен для того чтобы сгенерировать геометрию изначально до того, как ее отрисовывать, и во время рисования очередного кадра больше не придется обсчитывать тени заново.
Единственное что может обсчитываться, так это интенсивности света, но это уже сделать гораздо проще.
Проблема может возникнуть именно с динамическими тенями, поскольку в этом случае придется считать все заново каждый раз для сцены.
Теги: Графика, 3D

28 окт 2024 Пн Страдания с 3D

Вчера вечером, как обычно, сидел и страдал, писал код, который растеризировал бы 3Д графику и как можно быстрее чтобы это делалось. Все не так просто, как может показаться, честно говоря. Да, если использовать формулы вычисления треугольника, то все нормально, но для этого требуется пройти по всем 64К точкам, а это немало. Я думал о том, как бы ускорить процесс растеризации пока что ничего не придумал быстрее чем можно было придумать ранее.
В общем, надо сначала сделать софтверный рендеринг на JS и посмотреть, с какой скоростью и эффективностью будет это все работать. Создать необходимые сцены и предварительно оценить количество рисуемых треугольников, их качество. Хоть так бы сделать, уже будет достижение. Я раньше делал просто рисование кубов, но этого явно недостаточно, нужно прорисовать хоть какую-то сцену.
Оценка количества памяти
Я примерно прикинул сколько надо чего для того чтобы рисовать треугольники. Для хранения текущего состояния рисуемого треугольника требуется хранить 4 DWORD стартовых значения, 4 DWORD инкрементирования по X, и 4 DWORD по Y, что в сумме дает 12x4 = 48 байт на один треугольник. Хранить их можно в разных банках памяти, например, по 4 банка памяти выделять, то есть доступ к ним будет довольно быстрый, за 2Т полное чтение.
Допустим, надо хранить 256 треугольников, которые рисуются на экране, что дает 12Кб памяти для этого. И еще надо хранить собственно, исходные треугольники, а это уже 6Кб дополнительно, в целом получается 18Кб. Не то чтобы много, терпимо, смотря только вот какой чип юзать для этого.
Перед рисованием треугольника также требуется рассчитать, с какой позиции начнется, а это будет вероятно, 3 деления, то есть, A*dx + B*dy + C = 0, нужно вычислить dx = -(B*dy + C) / A. Это будет то количество шагов, которые необходимо сделать перед тем, как точка соприкоснется с позицией u=0 или v=0. Однако, здесь есть свои нюансы, поскольку еще есть и другая позиция u + d = D, что будет очень сложно подсчитать.
Расчет
A1*dx + A2*dy + A3*dz = u
B1*dx + B2*dy + B3*dz = v
C1*dx + C2*dy + C3*dz = d
Здесь или: u + v = d, или u = 0, или v = 0.
dx = -(A3*dz + A2*dy) / A1
dx = -(B3*dz + B2*dy) / B1
dx = (dz(C3 - A3 - B3) + dy(C2 - A2 - B2)) / (A1 + B1 - C1)
Требуется рассчитать все 3 точки и проверить ближайшее расстояние до них. Это необходимо для того, чтобы узнать, где начинается рабочая область у каждого треугольника. Сравнивать числа можно через соотношения: A/B <=> C/D, или AD <=> BC, то есть, через умножения. Выбрав минимальное, начинать растеризацию оттуда, это сильно сэкономит циклы обработки.
Теги: 3D
<< Ранние записи | Поздние записи >>