Главная » WPF » Трехмерная графика

0

Хочу начать этот раздел с признания: я не занимаюсь программированием трехмерной графики. Мне кажется, что это «круто», и я предпринимал немало попыток освоиться  с этой областью, но она мне никак не дается. Однако я не ду маю, что надо так уж глубоко разбираться в 3D графике, чтобы применять ее в собственных  программах.  В WPF мы считали,  что трехмерная  графика  должна быть согласована  с двумерной.  Мы попытались свести к минимуму  количество новых концепций и упростить  интеграцию  обоих миров.

В WPF трехмерные  изображения – это частный  случай  векторной  графики. Нет ни физической модели, ни обнаружения столкновений, ни других высокоу ровневых служб, которые необходимы для написания игр или создания  трехмер ной среды с полным погружением.  3D графика в WPF – это лишь трамплин,  от которого  мы хотим отталкиваться в будущем. Имея  уже наличествующие базо вые блоки, мы можем создавать в WPF весьма интересные картины, но для этого требуется  много работы и понимание  принципов трехмерной  графики.

В двумерном мире есть четкая граница между рисунками (понимаемыми как низ коуровневые объекты композиции) и элементами управления – объектами более вы сокого уровня, которыми пользуется прикладной программист. В 3D графике, реали зованной  в текущей  версии  WPF,  мы отчасти  приблизились к этому разделению: Visual3D – это трехмерный аналог Visual, а Model3D – аналог Drawing. Однако нет ни каркаса, необходимого для создания  элементов  управления, ни фигур, средств ввода и шаблонов, ни других более продвинутых служб. Но зачатки  то присутствуют.

Программа «Здравствуй, мир» в трехмерной ипостаси

Для  того чтобы хоть что то изобразить в трехмерном  виде, нужно  понимать четыре основных концепции:  модель, материал, источник освещения  и камера.

У моделей и материалов  в двумерном  мире есть простые аналоги: рисунки  и кисти. Базовая модель в 3D графике называется GeometryModel3D и представ ляет  трехмерный  вариант  геометрического  примитива;  это точный  эквивалент класса GeometryDrawing в двумерной  графике. Определение геометрического примитива в 3D графике сложнее,  чем в 2D; начнем  с построения  простейшей трехмерной  фигуры, а именно треугольника:

MeshGeometry3D CreateTriangle() { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions.Add(new Point3D(0, 0, 0)); mesh.Positions.Add(new Point3D(1, 0, 0)); mesh.Positions.Add(new Point3D(0, 1, 0)); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2);

return mesh;

}

Здесь  с помощью свойства  Positions определены  три вершины  треугольника. Затем,  пользуясь  свойством  TriangleIndices, мы сообщаем  порядок  следования вершин. На базе этого примитива мы создаем модель:

GeometryModel3D model = new GeometryModel3D();

model.Geometry = CreateTriangle();

Трехмерным аналогом кисти является класс Material.  Материал  принимает  в качестве параметра кисть, задающую цвет заливки, а также имеет ряд свойств, уп равляющих  отражением света:

model.Material = new DiffuseMaterial(Brushes.Red);

Теперь, имея модель и материал, мы можем осветить сцену. Пожалуй, самой расп ространенной ошибкой в трехмерном моделировании является неправильное распо ложение источников  освещения. Если источники освещения  находятся  позади трех мерного  объекта,  слишком  далеко  от него или  недостаточно  яркие,  то мы увидим

лишь черный контур фигуры. Как и в реальном мире, существует много разных типов источников  освещения.  Самый  простой  – это точечный  источник,  который  можно представлять себе как обособленную лампу, излучающую свет во всех направлениях:

PointLight light = new PointLight(); light.Position = new Point3D(12, 12, 12); light.Color = Colors.White;

light.Range = 150;

light.ConstantAttenuation = 1.0;

Свойство Range определяет  «силу» свету (световой  поток), свойства Position и Color не нуждаются  в пояснениях, а ConstantAttenuation – одно из свойств, опи сывающих скорость угасания света (подробнее мы рассмотрим этот вопрос ниже).

Итак,  у нас есть модель, материал  и источник  освещения.  Последний шаг – создание камеры. Камера – это устройство,  которое снимает сцену и проецирует ее на двумерную поверхность. Объединив объект Camera с объектом Viewport3D, мы наконец увидим сцену. Сначала  подготовим  камеру:

PerspectiveCamera viewer = new PerspectiveCamera(); viewer.LookDirection = new Vector3D(0, 0,  1); viewer.Position = new Point3D(0, 0, 12); viewer.FieldOfView = 45;

viewer.UpDirection = new Vector3D(0, 1, 0);

Свойство FieldOfView (зона обзора) определяет коэффициент увеличения (зум), UpDirection – ориентацию  камеры  (то есть то, какое направление будет считаться

«вверх»), а LookDirection – направление, в котором «смотрит» камера. Ну и напосле

док объединим все это с окном проекций (viewport) и выведем на экран (рис. 5.32).

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Media;

using System.Windows.Media.Media3D;

using System.Windows.Shapes;

namespace EssentialWPF {

public class Window3D : Window {

public Window3D() { Title = «3D Rocks»;

Viewport3D viewport = new Viewport3D();

Model3DGroup group = new Model3DGroup(); GeometryModel3D model = new GeometryModel3D(); model.Geometry = CreateTriangle();

model.Material = new DiffuseMaterial(Brushes.Red);

group.Children.Add(model);

PerspectiveCamera viewer = new PerspectiveCamera(); viewer.LookDirection = new Vector3D(0, 0,  1); viewer.Position = new Point3D(0, 0, 12); viewer.FieldOfView = 45;

viewer.UpDirection = new Vector3D(0, 1, 0);

viewport.Camera = viewer;

PointLight light = new PointLight(); light.Position = new Point3D(12, 12, 12); light.Color = Colors.White;

light.Range = 150;

light.ConstantAttenuation = 1.0;

group.Children.Add(light);

ModelVisual3D scene = new ModelVisual3D(); scene.Content = group; viewport.Children.Add(scene);

Content = viewport;

}

MeshGeometry3D CreateTriangle() { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions.Add(new Point3D(0, 0, 0)); mesh.Positions.Add(new Point3D(1, 0, 0)); mesh.Positions.Add(new Point3D(0, 1, 0)); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2);

return mesh;

}

}

}

Рис. 5.32. Вид простой трехмерной фигуры (треугольника)

Однако!  Сколько  кода, чтобы вывести  простой  треугольник.  Прежде  чем пе рейти к созданию  более интересных  фигур, сформулируем основные  принципы трехмерной  графики.

Источник: К. Андерсон  Основы  Windows Presentation Foundation. Пер. с англ. А. Слинкина — М.: ДМК Пресс, 2008 — 432 с.: ил.

По теме:

  • Комментарии