Принципи тривимірної графіки
Оскільки в поточній версії WPF підтримка тривимірної графіки обмежена, буде правильно спочатку познайомитися з базовими будівельними блоками та зрозуміти, що можна надбудувати над ними. Ми вже говорили, що у тривимірній графіці є чотири основні концепції: модель, матеріал, камера та джерело освітлення.
Строго кажучи, джерела освітлення – це теж моделі (а в деяких системах моделями є і камери). Однак ми поки що обмежимося класами GeometryModel3D і MeshGeometry3D, які при створенні будь-якої моделі завжди йдуть пліч-о-пліч.
Щоб визначити об'єкт класу MeshGeometry3D, нам потрібні координати послідовності точок у тривимірному просторі. Потім, вибираючи з цієї послідовності трійки точок, ми можемо визначити трикутники. Матеріал точок описується за допомогою текстури. Щоб зрозуміти, як усе це пов'язано, створимо складніший тривимірний об'єкт: частину куба (ми розглянемо тільки три видимі грані, а побудову трьох я залишаю читачеві як вправу).
Властивість Positions визначає послідовність точок16. У куба вісім вершин, але оскільки нас цікавлять лише три грані, то потрібно лише сім точок (рис. 5.33).
Ця послідовність точок не визначає жодних трикутників, поки ми не повідомимо сітці порядок їхнього обходу (див. рис. 5.33). За допомогою властивості TriangleIndices ми зіставляємо трикутнику три індекси. Оскільки потрібно створити три грані, знадобиться щонайменше шість трикутників. Спочатку створимо ліву нижню половину передньої грані17:
Потім – праву верхню половину:
Повторимо цю процедуру для чотирьох трикутників, що залишилися.
16 Нагадаємо, що результат суттєво залежить від орієнтації камери. В даному випадку ми припускаємо, що позитивний напрямокосі Y означає «верх». На рис. 5.33 показу але також, що більше координата Z, тим далі об'єкт віддалений від камери.
17 У WPF визначення поверхні трикутника застосовується правило правої руки. Щоб зрозуміти його, зігніть праву руку, піднявши вгору великий палець. Якщо провести координатні осі вздовж інших пальців, великий палець визначить нормаль до поверхні. Можна уявити і інакше: коли ви дивитеся на поверхню, розташовану прямо перед очима, вершини трикутника мають бути впорядковані проти годинникової стрілки.
І ще потрібно зіставити крапкам матеріал (іноді він називається текстурою). За допомогою TextureCoordinate властивості ми визначаємо, як координати матеріалу відносно охоплюючого прямокутника співвідносяться з точкою. Для кожної точки сітки ми збираємося асоціювати двовимірну точку з діапазо від (0,0) до (0,1) з точкою на матеріалі.

Мал. 5.34.Перша спроба скористатися текстурою, не вказавши координати на ній
Нагадаємо, що при визначенні пензля (наприклад, LinearGradientBrush) ми можемо задати початкову і кінцеву точки в системі координат, пов'язаної з прямокутником, що охоплює, тобто в тій же системі, в якій визначаються властивості GradientStop.Offset. Оскільки матеріал повинен охоплювати кілька трикутників і часто доводиться виконувати його рендеринг кілька разів (як у випадку куба, що має шість граней), то необхідно повідомити систему, яким чином зіставити матеріал кожному трикутнику. Оскільки властивості TriangleIndices вже відображають точки на трикутники, то залишається тільки визначити матеріал для кожної точки.
За замовчуванням для кожної точки властивості TextureCoordinate надається значення (0,0). Тому, якщо застосувати пензель LinearGradientBrush,то буде використаний лише колір у точці з нульовим зміщенням (рис. 5.34). Однак, якщо взяти той же градієнт, яким ми заливали прямокутник, то результат виявиться зовсім іншим (рис. 5.35):

Мал. 5.35.Той самий прямокутник, до якого застосована градієнтна текстура
Правильно задавши для сітки властивість TextureCoordinates, ми зможемо отримати такий же результат (площини, освітлення тощо) за допомогою прямокутника, що складається з двох трикутників:
Для нашого куба із трьома гранями необхідно визначити, як обробляти закінчення градієнта. Можна зробити так, щоб куб зафарбовувався зліва направо, а кінцеве ребро мало суцільний фінальний колір. Оскільки типова модель виявляється досить громіздкою, існує також компактна форма запису різних властивостей. Наступна компактна розмітка описує ту саму сітку, що й у попередніх прикладах:
Тепер зберемо все разом і запишемо остаточну розмітку для відображення
ня нашої першої тривимірної фігури (рис. 5.36):