task4-v3 (794727), страница 2
Текст из файла (страница 2)
Разным типам пружинможно задать разную жёсткость.std::vector<int>std::vector<float>std::vector<float>edgeIndices;edgeHardness;edgeInitialLen;for (size_t i = 0; i < vertPos.size(); i++){for (int j = i + 1; j < vertPos.size(); j++){float4 vA = vertPos[i];float4 vB = vertPos[j];float dist = dist(vA, vB);6if (dist < 2.0f*sqrtf(2.0f)*edgeLength){float hardness = initialHardnes * (edgeLength / dist);edgeIndices.push_back(i);edgeIndices.push_back(j);edgeHardness.push_back(hardness);edgeInitialLen.push_back(dist);}}}Алгоритм 1. Алгоритм задания соединений для вершин.Алгоритм построения соединений "через 1" и смежных.
Метод грубой силы, прост в реализации. Внашей реализации жёсткость пружины задавалась обратно пропорционально её длине, т.е.удельная жёсткость всех пружин одинакова. В задании вам не обязательно реализовывать именнотакую модель. Возможны вариации числа соединений и их жёсткости. Например, вы можетеиспользовать триангуляцию Делоне.5.2 ОСНОВЫ СИМУЛЯЦИИ И МЕТОДА КОНЕЧНЫХ ЭЛЕМЕНТОВМетод конечных элементов (МКЭ) — это численный метод решения дифференциальныхуравнений с частными производными, а также интегральных уравнений, возникающих прирешении задач прикладной физики [1]. Уравнения, описывающие движение системы из точек,соединённых пружинами, можно найти в [2].
Мы не будем подробно останавливаться наматематической основе. Отметим лишь, что рассматриваемая далее модель эквивалентна методуконечных элементов первого порядка. Разобьём ось времени на набор достаточного большогочисла маленьких интервалов.Будем рассматривать поведение системы в моменты времени t0, t1, t2 (в центре интервала)и.т.д с небольшим шагом по времени ∆. Время ∆ называется шагом дискретизации. В каждыймомент времени точки (вершины), обладающие заданной массой, находятся в известной позиции.Они имеют определённые скорости.
При этом, на каждую точку действуют силы упругостисмежных пружин, определяемые их текущим растяжением/сжатием. Также действуют внешниесилы: гравитация и ветер. Условие небольшого шага по времени позволяют в простейшей моделисчитать все указанные параметры константными в пределах от t[i] до t[i+1]7Рисунок 6. Схема моделирования.На каждом шаге вам необходимо хранить только позиции и скорости вершин.
Зная позициина текущем шаге, можно вычислить текущие длины всех пружин. Зная текущую длину пружины,можно по закону Гука вычислить силу упругости, действующую на вершины на двух её концах.Путём векторного сложения всех сил, действующих на данную вершину, можно получитьрезультирующую силу упругого воздействия пружин. Добавив ветер и гравитацию, получаемрезультирующую силу для данной вершины на текущем шаге.
Зная её, можно вычислитьускорение. Зная ускорение и текущие скорости, можно вычислить новые скорости - наследующем шаге. Наконец, зная скорости, можно вычислить новые позиции и переходить кследующему шагу по времени.5.3 ОСНОВНЫЕ ФОРМУЛЫ⃗⃗⃗⃗⃗⃗⃗упр = ⃗∆где ⃗ – единичный вектор направления пружины, – коэффициент упругости, ∆ – величинарастяжения-сжатия пружины со знаком⃗⃗⃗⃗⃗⃗⃗⃗⃗рез.
= ∑ ⃗⃗⃗⃗⃗⃗⃗упр + ⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗ветра + ⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗тяжести⃗ = ∆∆=∆ 2⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗∆ = ⃗⃗⃗0 ∆ + 28Внимание, хак!Мы заметили, что вычисления позиций на новом шаге можно производить по другойформуле, неправильной с точки зрения МКЭ первого порядка и с физической точки зрения, нодающей визуально более гладкий результат.Неправильная с точки зрения МКЭ 1 порядка (но работающая) формула:∆ 2⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗⃗0 + ∆⃗ )∆ +∆ = (2Поскольку целью задания не является физически точная симуляция, вы можете использовать этуили любые другие аппроксимации, делающие движения ткани более плавными и реалистичными.Однако будьте аккуратны, любые хаки, как правило, делают симуляцию менееустойчивой!!!5.4 ОСНОВЫ ГЕОМЕТРИЧЕСКИХ ПРЕОБРАЗОВАНИЙ И OPENGL 3/4(1) При использовании OpenGL3/4 и шейдеров необходимо помнить одно главное правило.Вершинный шейдер записывает свой выход в gl_Position в clip space, в единичном кубе [-1,1].(2) Также важно помнить, что в процессе растеризации происходит деление позиций вершин начетвёртую координату w.
Это позволяет записать перспективную проекцию в виде матрицы (безперехода в 4 измерения это было бы невозможно). Поэтому четвёртая координата (w) должна бытьравна 1 до применения матрицы проекции. И только после применения матрицы проекции онаможет быть не равной 1.(3) Помните, что драйвер OpenGL обычно выполняет оптимизации неиспользуемых атрибутоввершин. Поэтому если в вершинном шейдере какой-нибудь атрибут не используется, его locationполучается инвалидным.Важная подсказка по реализации отображения треугольного меша и меша из линий:(4) Вы можете создать дополнительный буфер индексов и дополнительный VAO, чтобы рисоватьтот же самый меш не только линиями, но и треугольниками. Не нужно дублировать буферы,содержащие атрибуты вершин.95.5 ОСНОВЫ ЛОКАЛЬНЫХ МОДЕЛЕЙ ОСВЕЩЕНИЯВ OpenGL 3/4 нет встроенных моделей освещения.
Все расчёты освещенностифрагмента/пиксела вы выполняете самостоятельно при помощи вершинных и фрагментныхпрограмм (как правило освещение считается при помощи последних). Для расчёта освещённостиво фрагментном шейдере предлагается использовать модели Ламберта и Фонга [3].Важно помнить, что все расчёты вы должны производить в одном и том же пространстве.Например, если вы всё считаете в мировом пространстве (world space), не забудьте правильновычислить направление на наблюдателя и источник света.Если вы выполняете расчёт освещения в пространстве камеры (в этом пространстве легкополучить направление на наблюдателя), не забудьте корректно перевести в это пространствонаправление на источник.Если вы выполняете расчёт в тангенциальном пространстве (tangent space) для имитациимикрорельефа при помощи карт нормалей, необходимо все вектора перевести в тангенциальноепространство.5.5.1Вычисление сглаженных нормалейВажным требованием базовой части задания является расчёт сглаженных нормалей.
Этонеобходимо для того чтобы получить плавно меняющееся освещение по поверхности ткани. Иначебудут видны отдельные грани. Для того чтобы получить сглаженные нормали в вершинах, вамсначала необходимо вычислить нормали к квадам (или треугольникам) при помощи векторногопроизведения, а затем для каждой вершины усреднить нормали всех квадов (или треугольников),которые её касаются.Рисунок 7. Иллюстрация вычисления сглаженных нормалей в вершинах. Нормали к полигонамусредняются, чтобы получить нормаль в вершине.105.6 МЕТОД КАРТ ТЕНЕЙИдея метода карт теней заключается в том, чтобы запомнить буфер глубины при рендере спозиции источника.
В дальнейшем, зная расстояние от точки до источника, и зная это жерасстояние в буфере глубины, можно определить, лежит точка в тени или нет (рисунки 8 и 9).Рисунок 8. Иллюстрация работы метода карт теней.Рисунок 9. Ещё одна иллюстрация работы метода карт теней.Если расстояние от заданной точки до источника в реальности больше, чем это же самоерасстояние, запомненное в буфере глубины, значит, данная точка в тени, т.к. это расстояние можетбыть меньше только если на пути света к этой точки из источника встретилось препятствие.
Такимобразом, метод карт теней состоит из 4 шагов:1. Расчёт модельно-видовой матрицы для вида из источника освещения. Можно использоватьпредоставляемую библиотечную функцию glusLookAtf.2. Расчёт матрицы проекции для вида из источника освещения.Можно использоватьпредоставляемую библиотечную функцию glusOrthof или glusPerspectivef.113.
Рендер сцены из позиции источника и сохранение глубины в отдельной текстуре.4. При основном рендере с позиции камеры для каждого пиксела нужно перевести его позициииз мирового пространства (world space) в пространство источника света (view space) иполучить значение глубины. Вы делаете это при помощи ровно тех же самых матриц(модельно-видовой матрицы и матрицы проекции), которые были использованы при рендересцены из позиции источника освещения.Помните также, что если вы используете перспективную проекцию при рендере сцены изпозиции источника освещения, после примирения матрицы проекции на 4 шаге вы должныподелить получившиеся координаты на w (алгоритм 2).vec4 posLightSpace= shadowViewMatrix*vec4(fragmentWorldPos, 1);vec4 posLightClipSpace = shadowProjMatrix*posLightSpace;vec2 shadowTexCoord= (posLightClipSpace.xy/posLightClipSpace.w)*0.5 + vec2(0.5, 0.5);Алгоритм 2.
Перевод позиции фрагмента из world space в light space и получение текстурныхкоординат для выборки глубины из карты теней.5.7 РЕНДЕРИНГ В ТЕКСТУРУ В OPENGLРендеринг в текстуру в OpenGL реализуется при помощи абстракции, называемой FrameBuffer Object (FBO) (рис 9).12Рисунок 9. Иллюстрация работы Frame Buffer Object (FBO). Хотя на данном рисунке кGL_DEPTH_ATTACHMENT прикреплён специальный объект renderbuffer, вместо него можетбыть текстура специального формата. Именно так сделано в предоставляемом вам шаблоне.Как только вы делаете фрейм-буфер текущим/активным, весь рендеринг с экранаперенаправляется в прикреплённые к фрейм-буферу текстуры.















