Обзор трехмерной графики
Функциональные возможности 3-D системы Windows Presentation Foundation (WPF) позволяют разработчикам рисовать, преобразовывать и анимировать трехмерную графику как в разметке, так и в процедурном коде. Разработчики могут сочетать графику 2-D и 3-D для создания многофункциональных элементов управления, предоставления сложных визуальных представлений данных или повышения удобства работы с интерфейсом приложения. Поддержка 3-D в WPF не предполагает предоставления полнофункциональной платформы для создания игр. В этом разделе содержатся общие сведения о функциональных возможностях 3-D в графической системе WPF.
В этом разделе содержатся следующие подразделы.
- 3-D в контейнере 2-D
- Координаты трехмерного пространства
- Камеры и проекции
- Примитивы модели и сетки
- Применение материалов к модели
- Освещение сцены
- Преобразование моделей
- Анимация моделей
- Добавление трехмерного содержимого к окну
- Связанные разделы
3-D в контейнере 2-D
Графическое содержимое 3-D в приложении WPF инкапсулировано в элементе Viewport3D, который может участвовать в структуре двумерного элемента. Графическая система рассматривает Viewport3D как двухмерный визуальный элемент, подобный многим другим в WPF. Viewport3D функционирует как окно — окно просмотра — трехмерной сцены. Говоря точнее, это поверхность, на которую проецируется сцена 3-D.
В традиционном приложении 2-D элемент Viewport3D используется как любой другой контейнерный элемент, например "Grid" или "Canvas". Хотя элемент Viewport3D можно использовать с другими графическими объектами 2-D в том же графе сцены, нельзя сочетать объекты 2-D и 3-D внутри элемента Viewport3D. Этот раздел будет посвящен рисованию 3-D графики внутри объекта Viewport3D.
Координаты трехмерного пространства
Начало системы координат WPF для графики 2-D отсчитывается от левого верхнего угла области отрисовки (обычно экрана). В системе 2-D положительные значения оси x откладываются вправо, а положительные значения оси y — сверху вниз. Однако в системе координат 3-D начало располагается в центре отрисовываемой области, положительные значения оси x откладываются вправо, оси y — снизу вверх, а оси z — из центра к наблюдателю.
Представления традиционных двухмерных и трехмерных систем координат
Пространство, определяемое этими осями, является стационарной системой отсчета координат для объектов 3-D в приложении WPF. При построении моделей в этом пространстве и создании источников света и камер для их отображения необходимо отличать стационарную систему отсчета координат (или "мировую систему координат") от локальной системы отсчета, которая создается для каждой модели при применении к ней преобразований. Помните, что в зависимости от настройки освещения и камеры, объекты в мировой системе координат могут выглядеть совсем по-другому или вообще быть невидимыми, но положение камеры не изменяет расположения объектов в мировой системе координат.
Камеры и проекции
Разработчики, работающие в координатах 2-D, привыкли к размещению графических примитивов на двухмерном экране. При создании сцены 3-D важно помнить, что фактически создается представление 2-D объектов 3-D. Поскольку сцена 3-D выглядит по-разному в зависимости от точки наблюдения, необходимо указать эту точку наблюдения. Указать эту точку наблюдения для сцены 3-D позволяет класс Camera.
Другой способ понимания того, как представляется сцена 3-D на поверхности 2-D, — это описание сцены как проекции на поверхность просмотра. Камера ProjectionCamera позволяет указать различные проекции и их свойства для изменения того, как наблюдатель видит модели 3-D. Камера PerspectiveCamera указывает проекцию сцены в перспективе. Другими словами, камера PerspectiveCamera предоставляет точку схода перспективы. Можно указать положение камеры в пространстве координат сцены, направление и поле зрения камеры и вектор, определяющий направление "вверх" в сцене. Следующая схема иллюстрирует проекции PerspectiveCamera.
Свойства NearPlaneDistance и FarPlaneDistance камеры ProjectionCamera ограничивают диапазон проекции камеры. Поскольку камеры могут быть расположены в любом месте сцены, фактически можно расположить камеру внутри модели или очень близко от нее, что усложняет правильное распознавание объекта. Свойство NearPlaneDistance позволяет определить минимальное расстояние от камеры, за которым не будут располагаться объекты. И наоборот, свойство FarPlaneDistance позволяет задать расстояние от камеры, дальше которого объекты не будут нарисованы; это гарантирует, что объекты, расположенные слишком далеко для распознавания, не будут включены в сцену.
Позиция камеры
Камера OrthographicCamera указывает ортогональную проекцию модели 3-D на визуальную поверхность 2-D. Подобно другим камерам, она указывает позицию, направление просмотра и направление "вверх". Однако в отличие от камеры PerspectiveCamera, камера OrthographicCamera описывает проекцию, которая не включает ракурс перспективы. Другими словами, камера OrthographicCamera описывает призму, стороны которой параллельны, вместо призмы, стороны которой сходятся в точке камеры. На следующем рисунке показана одна модель, отображенная с использованием камер PerspectiveCamera и OrthographicCamera.
Перспективная и ортогональная проекции
В следующем коде показано несколько обычных параметров камеры.
' Defines the camera used to view the 3D object. In order to view the 3D object,
' the camera must be positioned and pointed such that the object is within view
' of the camera.
Dim myPCamera As New PerspectiveCamera()
' Specify where in the 3D scene the camera is.
myPCamera.Position = New Point3D(0, 0, 2)
' Specify the direction that the camera is pointing.
myPCamera.LookDirection = New Vector3D(0, 0, -1)
' Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60
' Asign the camera to the viewport
myViewport3D.Camera = myPCamera
// Defines the camera used to view the 3D object. In order to view the 3D object,
// the camera must be positioned and pointed such that the object is within view
// of the camera.
PerspectiveCamera myPCamera = new PerspectiveCamera();
// Specify where in the 3D scene the camera is.
myPCamera.Position = new Point3D(0, 0, 2);
// Specify the direction that the camera is pointing.
myPCamera.LookDirection = new Vector3D(0, 0, -1);
// Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60;
// Asign the camera to the viewport
myViewport3D.Camera = myPCamera;
Примитивы модели и сетки
Model3D — это абстрактный базовый класс, представляющий универсальный объект 3-D. Чтобы построить сцену 3-D, необходимо, чтобы некоторые объекты для отображения и объекты, составляющие граф сцены, наследовали от класса Model3D. В настоящее время приложение WPF поддерживает моделирование геометрических объектов с помощью класса GeometryModel3D. Свойство Geometry данной модели принимает примитив сетки.
Начните построение модели с создания примитива, или сетки. Примитив 3-D представляет собой набор вершин, образующих одну сущность 3-D. Большинство систем 3-D предоставляют примитивы, смоделированные на основе простейшей замкнутой фигуры: треугольника, определенного тремя вершинами. Поскольку три точки треугольника лежат в одной плоскости, можно добавлять треугольники для моделирования более сложных фигур, называемых сетками.
Текущая система 3-D приложения WPF предоставляет класс MeshGeometry3D, позволяющий определить любую геометрическую форму; в настоящее время не поддерживаются примитивы 3-D, такие как сферы или кубические формы. Начните создание класса MeshGeometry3D с определения списка вершин треугольников в качестве свойства Positions. Каждая вершина задается как свойство Point3D. (В Extensible Application Markup Language (XAML) укажите это свойство в виде списка чисел, сгруппированных тройками и представляющих координаты каждой вершины.) В зависимости от геометрического объекта, сетка может состоять из множества треугольников, некоторые из которых совместно используют общие углы (вершины). Чтобы нарисовать сетку правильно, приложению WPF требуются данные о том, какие вершины треугольников являются общими. Предоставить эти данные можно, указав список индексов треугольников в свойстве TriangleIndices. Этот список определяет порядок, в котором точки, указанные в списке Positions, будут определять треугольник.
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D
Positions="-1 -1 0 1 -1 0 -1 1 0 1 1 0"
Normals="0 0 1 0 0 1 0 0 1 0 0 1"
TextureCoordinates="0 1 1 1 0 0 1 0 "
TriangleIndices="0 1 2 1 3 2" />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<!-- Translate the plane. -->
<GeometryModel3D.Transform>
<TranslateTransform3D
OffsetX="2" OffsetY="0" OffsetZ="-1" >
</TranslateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
В предыдущем примере список Positions задает восемь вершин для определения сетки кубической формы. Свойство TriangleIndices указывает список двенадцати групп по три индекса. Каждое число в списке определяет смещение в списке Positions. Например, первыми тремя вершинами, заданными списком Positions, являются (1,1,0), (0,1,0) и (0,0,0). Первыми тремя индексами, заданными TriangleIndices, являются 0, 2 и 1, что соответствует первому, третьему и второму пунктам в списке Positions. В результате, первый треугольник, формирующий модель куба, будет составлен из вершин (1,1,0), (0,1,0) и (0,0,0), а оставшиеся одиннадцать треугольников будут определяться аналогичным образом.
Можно продолжить определение модели путем указания значений свойств Normals и TextureCoordinates. Для отображения поверхности модели графической системе требуются данные о том, какое направление поверхности является лицевым для любого данного треугольника. Система использует эти сведения для вычислений освещения модели: поверхности, обращенные к источнику освещения, отображаются ярче, чем поверхности, расположенные под углом к освещению. Хотя приложение WPF может определить векторы нормали по умолчанию, используя координаты позиции, можно задавать различные векторы нормали для аппроксимации вида кривых поверхностей.
Свойство TextureCoordinates указывает коллекцию объектов Point, сообщающую графической системе, каким образом сопоставлять координаты, определяющие отображение текстуры, с вершинами сетки. Свойства TextureCoordinates задаются как значение от нуля до 1 включительно. Также как и со свойством Normals, графическая система может вычислить координаты текстуры по умолчанию, но можно установить различные координаты текстуры, например, для управления отображением текстуры, содержащей часть повторяющегося узора. Дополнительные сведения о координатах текстуры можно найти в последующих разделах или в пакете Managed Direct3D SDK.
В следующем примере показано создание одной грани модели куба в процедурном коде. Обратите внимание, что можно нарисовать весь куб как один объект GeometryModel3D; в этом примере грань куба отображается как отдельная модель для того, чтобы далее применить отдельные текстуры для каждой грани.
Private side1Plane As New MeshGeometry3D()
MeshGeometry3D side1Plane = new MeshGeometry3D();
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))
side1Plane.TriangleIndices.Add(0)
side1Plane.TriangleIndices.Add(1)
side1Plane.TriangleIndices.Add(2)
side1Plane.TriangleIndices.Add(3)
side1Plane.TriangleIndices.Add(4)
side1Plane.TriangleIndices.Add(5)
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.TextureCoordinates.Add(New Point(1, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 0))
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
side1Plane.TriangleIndices.Add(0);
side1Plane.TriangleIndices.Add(1);
side1Plane.TriangleIndices.Add(2);
side1Plane.TriangleIndices.Add(3);
side1Plane.TriangleIndices.Add(4);
side1Plane.TriangleIndices.Add(5);
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.TextureCoordinates.Add(new Point(1, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 0));
Применение материалов к модели
Чтобы сетка выглядела как объект в трехмерном пространстве, к ней необходимо применить текстуру, которая покрывает поверхность, определенную ее вершинами и треугольниками. В этом случае можно осветить эту поверхность и создать ее проекцию с помощью камеры. В объектах 2-D для применения цветов, узоров, градиентов или другого визуального содержимого к участкам экрана можно использовать класс Brush. Однако вешний вид объектов 3-D является функцией модели освещения, а не только примененного к ним цвета или узора. Реальные объекты отражают свет неодинаково, в зависимости от качества поверхностей: гладкие и глянцевые поверхности выглядят иначе, чем неровные и матовые, также одни объекты поглощают свет, в то время как другие — отражают. К объектам 3-D можно применить те же кисти, что и к объектам 2-D, но применить их напрямую невозможно.
Для определения характеристик поверхности модели приложение WPF использует абстрактный класс Material. Конкретные подклассы класса "Material" определяют некоторые характеристики внешнего вида поверхности модели, и каждый из них предоставляет свойство "Brush", которому можно передать значение "SolidColorBrush", "TileBrush" или "VisualBrush".
Класс DiffuseMaterial определяет, что кисть будет применена к модели, как если бы она была освещена рассеянным светом. Использование класса "DiffuseMaterial" больше всего напоминает применение кистей непосредственно в моделях 2-D; поверхности модели не отражают свет, как блестящие поверхности.
Класс SpecularMaterial определяет, что кисть будет применена к модели, как если бы поверхность модели была твердой или блестящей, способной отражать блики. Можно установить степень гладкости или "глянца" текстуры, задав значение свойства SpecularPower.
Класс EmissiveMaterial позволяет указать, что текстура будет применена, как если бы модель излучала свет, эквивалентный цвету кисти. Это не делает модель светящейся; однако это иначе влияет на затенение, чем если бы текстура была создана с помощью класса "DiffuseMaterial" или "SpecularMaterial".
Для повышения производительности противоположные поверхности объекта GeometryModel3D (грани, которые невидимы, поскольку находятся на противоположной стороне модели относительно камеры) удаляются из сцены. Чтобы указать класс Material для применения к противоположной поверхности модели, например плоскости, задайте свойство BackMaterial модели.
Для достижения некоторых свойств поверхности, таких как свечение или эффект отражения, можно последовательно применить к модели несколько различных кистей. Можно применять и повторно использовать несколько материалов с помощью класса MaterialGroup. Дочерние элементы класса "MaterialGroup" применяются от первого к последнему в нескольких проходах отрисовки.
Следующий пример кода демонстрирует применение сплошного цвета и рисования с помощью кистей к модели 3-D.
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<DrawingBrush x:Key="patternBrush" Viewport="0,0,0.1,0.1" TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Geometry="M0,0.1 L0.1,0 1,0.9, 0.9,1z"
Brush="Gray" />
<GeometryDrawing Geometry="M0.9,0 L1,0.1 0.1,1 0,0.9z"
Brush="Gray" />
<GeometryDrawing Geometry="M0.25,0.25 L0.5,0.125 0.75,0.25 0.5,0.5z"
Brush="#FFFF00" />
<GeometryDrawing Geometry="M0.25,0.75 L0.5,0.875 0.75,0.75 0.5,0.5z"
Brush="Black" />
<GeometryDrawing Geometry="M0.25,0.75 L0.125,0.5 0.25,0.25 0.5,0.5z"
Brush="#FF0000" />
<GeometryDrawing Geometry="M0.75,0.25 L0.875,0.5 0.75,0.75 0.5,0.5z"
Brush="MediumBlue" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
Dim side5Material As New DiffuseMaterial(CType(Application.Current.Resources("patternBrush"), Brush))
DiffuseMaterial side5Material = new DiffuseMaterial((Brush)Application.Current.Resources["patternBrush"]);
Освещение сцены
Источники света в графике 3-D выполняют ту же роль, что и реальные источники света: они делают поверхности видимыми. Более того, источники света определяют, какая часть сцены будет включена в проекцию. Объекты источников света в приложении WPF создают различные эффекты света и тени. Они смоделированы на основе поведения различных реальных источников света. Сцена должна включать, как минимум, один источник света, иначе модели будут невидимыми.
Указанные ниже источники света являются производными от базового класса Light:
AmbientLight: создает рассеянное освещение, при котором все объекты освещены одинаково, независимо от их расположения или ориентации.
DirectionalLight: создает освещение, аналогичное удаленному источнику света. Направленные источники света имеют свойство Direction, которое указывается как объект Vector3D, но без заданного местоположения.
PointLight создает освещение, как от ближнего источника света. Источники света "PointLights" занимают определенное положение и испускают свет из этого положения. Объекты на сцене освещаются в зависимости от их положения и расстояния относительно источника света. PointLightBase предоставляет свойство Range, которое определяет расстояние, за пределами которого модели не будут освещены светом. Класс "PointLight" также предоставляет свойства затухания, определяющие интенсивность ослабления источника света в зависимости от расстояния. Можно указать константу, линейную или квадратичную интерполяцию затухания источника света.
Исключение SpotLight наследуется от исключения PointLight. Источники света "Spotlights" освещают сцену подобно источникам света PointLight и также имеют расположение и направление. Они проектируют свет в конусообразную область, задаваемую свойствами InnerConeAngle OuterConeAngle, значения которых указываются в градусах.
Источники света являются объектами Model3D, поэтому можно преобразовывать и анимировать свойства источников света, включая положение, цвет, направление и диапазон.
<ModelVisual3D.Content>
<AmbientLight Color="#333333" />
</ModelVisual3D.Content>
Private myDirLight As New DirectionalLight()
DirectionalLight myDirLight = new DirectionalLight();
myDirLight.Color = Colors.White
myDirLight.Direction = New Vector3D(-3, -4, -5)
myDirLight.Color = Colors.White;
myDirLight.Direction = new Vector3D(-3, -4, -5);
modelGroup.Children.Add(myDirLight)
modelGroup.Children.Add(myDirLight);
Преобразование моделей
При создании моделей они имеют определенное расположение в сцене. Для перемещения этих моделей внутри сцены, поворота или изменения размера нецелесообразно изменять вершины, определяющие сами модели. Вместо этого, как и в моделировании 2-D, применяются преобразования моделей.
Каждый объект модели имеет свойство Transform, с помощью которого можно перемещать модель, изменять ее направление или размер. При применении преобразования фактически смещаются все точки модели с помощью вектора или значения, заданного преобразованием. Другими словами, выполняется преобразование координатного пространства, в котором определена модель ("модельное пространство"), но значения, составляющие геометрию модели в системе координат всей сцены ("мировое пространство"), не изменяются.
Дополнительные сведения о преобразовании моделей см. в разделе Общие сведения о трехмерных преобразованиях.
Анимация моделей
Реализация модели 3-D в приложении WPF действует в той же системе анимации и времени, что и графика 2-D. Другими словами, для анимации трехмерной сцены анимируйте свойства ее моделей. Можно непосредственно анимировать свойства примитивов, но обычно проще анимировать преобразования, изменяющие позицию или внешний вид моделей. Поскольку преобразования можно применить к объектам Model3DGroup также как и к отдельным моделям, то возможно применение одного набора анимаций к дочернему элементу Model3DGroup, а другого набора — к группе дочерних объектов. Также можно добиться разнообразных визуальных эффектов, анимируя свойства элементов освещения сцены. Наконец, можно анимировать саму проекцию, изменяя положение камеры или поле зрения. Общие сведения о системе времени и анимации в приложении WPF см. в разделах Общие сведения об эффектах анимации, Общие сведения о Storyboard и Общие сведения об объектах класса Freezable.
Для анимации объекта в приложении WPF создайте временную шкалу, определите анимацию (которая изменяет значение некоторого свойства во времени) и укажите свойство, к которому применяется анимация. Поскольку все объекты в сцене 3-D являются дочерними элементами объекта Viewport3D, свойства, к которым применяется анимация, являются свойствами "Viewport3D".
Предположим, требуется создать качающуюся на месте модель. Можно применить свойство RotateTransform3D к модели и анимировать ее ось вращения от одного вектора к другому. В следующем примере кода показано применение объекта "Vector3DAnimation" к свойству "Axis" для "Rotation3D" преобразования, предполагая, что "RotateTransform3D" будет одним из нескольких преобразований, примененных к модели с помощью "TransformGroup".
'Define a rotation
Dim myRotateTransform As New RotateTransform3D(New AxisAngleRotation3D(New Vector3D(0, 1, 0), 1))
//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
Dim myVectorAnimation As New Vector3DAnimation(New Vector3D(-1, -1, -1), New Duration(TimeSpan.FromMilliseconds(5000)))
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever
Vector3DAnimation myVectorAnimation = new Vector3DAnimation(new Vector3D(-1, -1, -1), new Duration(TimeSpan.FromMilliseconds(5000)));
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever;
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation)
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation);
'Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform)
//Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform);
Добавление трехмерного содержимого к окну
Для отображения сцены добавьте модели и источники света к объекту Model3DGroup, затем задайте объект Model3DGroup как свойство Content объекта ModelVisual3D. Добавьте ModelVisual3D к коллекции Children объекта Viewport3D. Добавьте камеры к объекту Viewport3D, задав его свойство Camera.
Наконец, добавьте объект Viewport3D к окну. При включении объекта Viewport3D в качестве содержимого элемента макета, такого как "Canvas", укажите размер объекта "Viewport3D", задав его свойства Height и Width(наследуемые от объекта FrameworkElement).
<UserControl x:Class="HostingWpfUserControlInWf.UserControl1"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid>
<!-- Place a Label control at the top of the view. -->
<Label
HorizontalAlignment="Center"
TextBlock.TextAlignment="Center"
FontSize="20"
Foreground="Red"
Content="Model: Cone"/>
<!-- Viewport3D is the rendering surface. -->
<Viewport3D Name="myViewport" >
<!-- Add a camera. -->
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="20"
LookDirection="0,0,1"
UpDirection="0,1,0"
NearPlaneDistance="1"
Position="0,0,-3"
FieldOfView="45" />
</Viewport3D.Camera>
<!-- Add models. -->
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup >
<Model3DGroup.Children>
<!-- Lights, MeshGeometry3D and DiffuseMaterial objects are added to the ModelVisual3D. -->
<DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />
<!-- Define a red cone. -->
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D
Positions="0.293893 -0.5 0.404509 0.475528 -0.5 0.154509 0 0.5 0 0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 0.154509 0.475528 -0.5 -0.154509 0 0.5 0 0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 -0.154509 0.293893 -0.5 -0.404509 0 0.5 0 0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 0.293893 -0.5 -0.404509 0 -0.5 -0.5 0 0.5 0 0 -0.5 -0.5 0 0.5 0 0 0.5 0 0 -0.5 -0.5 -0.293893 -0.5 -0.404509 0 0.5 0 -0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 -0.293893 -0.5 -0.404509 -0.475528 -0.5 -0.154509 0 0.5 0 -0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 -0.154509 -0.475528 -0.5 0.154509 0 0.5 0 -0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 0.154509 -0.293892 -0.5 0.404509 0 0.5 0 -0.293892 -0.5 0.404509 0 0.5 0 0 0.5 0 -0.293892 -0.5 0.404509 0 -0.5 0.5 0 0.5 0 0 -0.5 0.5 0 0.5 0 0 0.5 0 0 -0.5 0.5 0.293893 -0.5 0.404509 0 0.5 0 0.293893 -0.5 0.404509 0 0.5 0 0 0.5 0 "
Normals="0.7236065,0.4472139,0.5257313 0.2763934,0.4472138,0.8506507 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 -0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.5308242,0.4294462,0.7306172 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.7236065,0.4472139,0.5257313 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.858892,0.429446,0.279071 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.8944269,0.4472139,0 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.858892,0.429446,-0.279071 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.7236065,0.4472139,-0.5257313 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.5308242,0.4294462,-0.7306172 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.2763934,0.4472138,-0.8506507 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.5308249,0.4294459,-0.7306169 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.7236068,0.4472141,-0.5257306 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8588922,0.4294461,-0.27907 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8944269,0.4472139,0 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.858892,0.429446,0.279071 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.7236065,0.4472139,0.5257313 0.858892,0.429446,0.279071 0.7236065,0.4472139,0.5257313 0.5308242,0.4294462,0.7306172 0.858892,0.429446,0.279071 " TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush
Color="Red"
Opacity="1.0"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</Model3DGroup.Children>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
</Grid>
</UserControl>
См. также
Ссылки
Основные понятия
Общие сведения о трехмерных преобразованиях
Достижение максимальной производительности WPF 3D
Обзор фигур и базовых средств рисования в приложении WPF
Рисование с помощью объектов Image, Drawing и Visual