WPF 3D графика

Все исходники /  Язык программирования C# /  OS Windows /  Desktop /  WPF программирование / WPF 3D графика

Трехмерный API WPF

Трехмерный API WPF

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

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

Почти любой компьютер, работающий под управлением различных по возрасту версий Windows, сможет отобразить трехмерное содержимое. Когда возможностей видеокарты будет недостаточно, приложение WPF переключится на программную визуализацию. 3D API WPF является идеальным решением для приложений, в которых необходимо сочетать трехмерную графику с двумерным пользовательским интерфейсом.

Компоненты 3D рендеринга

Создать 3D рендеринг в WPF приложении очень просто, гораздо проще чем инициализация "настоящей" среды DirectX. Но несмотря на упрощение, всё же основные принципы трехмерного пространства в приложениях WPF необходимо соблюдать.

Плоскость просмотра

Какие бы трехмерные вычисления процессоры не выполняли, 3D изображение проецируется на двумерную плоскость, называемую областью (или окном) просмотра. Трехмерная сцена в WPF приложениях проецируется на плоскость, определяемую элементом Viewport3D. Данный элемент является и базовым контейнером для всех 3D объектов. Для управления размерами 3D сцены в окне приложения, Viewport3D можно добавить в другой контейнер, например Grid.

Точка наблюдения

Добавив область просмотра трехмерной сцены Viewport3D в ней уже можно размещать трехмерные объекты. Но 3D пространство в окне приложения как окружающий нас мир - оно бесконечно. Для того чтобы увидеть созданные объекты необходимо выбрать положение в пространстве, из которого будем наблюдать за объектами. В 3D терминологии эта точка наблюдения называется камерой.

Материал объектов

Любой объект в виртуальном программном 3D мире это только набор координат, его размерность. Чтобы предмет стал "осязаемым" его надо изготовить из какого-нибудь материала. Материалом в программном смысле может быть цвет или текстура в виде наложенной на предмет картинки. Теперь объект в пространстве становится видимым. Но что же это: мы его одели в цветной материал, а объект по какой-то причине черного цвета.

Источники света

Дело в том, что хотя область просмотра может иметь любой фоновый цвет, все объекты в 3D сцене находятся в полной темноте. Любой наблюдаемый предмет будет черного цвета. Для того чтобы увидеть предметы в цвете материала их необходимо осветить. 3D рендеринг требует наличие источников света. Количество источников света определяет сюжет трехмерной сцены. Отдельный источник света может освещать все объекты, только один объект или его часть. Большей частью именно освещение создаёт объемность предметов.

Система 3D координат в WPF

Система координат 3D графики WPF

В WPF для 3D программирования принята правосторонняя система координат. В данной координатной системе ось Х положительна вправо, ось Y положительна вверх, ось Z положительна по направлению к наблюдателю. Значения координат выражаются в относительных величинах. Точка с координатами -1,5,-2 смещена влево на одну единицу, вверх на пять единиц, вглубь пространства на две единицы.

Абсолютные величины, содержащиеся в относительных, определяют размерность сюжета 3D сцены. Например: создаётся трехмерное изображение внутренней части дома 10х10 метров, за одну единицу принимается 1 метр. Тогда абсолютная размерность пространства будет -5 м <= X <= 5 м, -5 м <= Y <= 5 м, -5 м <= Z <= 5 м. Это так называемые мировые координаты. В пределах мировых координат размещаются все 3D предметы виртуального дома.

Инициализация 3D среды

Соблюдая теоретические основы описанные выше можно создать структуру разметки XAML для инициализации трехмерного виртуального пространства:
<!-- Плоскость просмотра, контейнер для 3D объектов -->
<Viewport3D>
	<Viewport3D.Camera>
		<!-- Камера - точка наблюдения -->
	</Viewport3D.Camera>
	
	<ModelVisual3D>
		<ModelVisual3D.Content>
			<!-- Источник света -->
		</ModelVisual3D.Content>
	</ModelVisual3D>

	<ModelVisual3D>
		<ModelVisual3D.Content>
			<GeometryModel3D >
				<GeometryModel3D.Geometry>
					<!-- Сетчатый объемный предмет -->
				</GeometryModel3D.Geometry>
				<GeometryModel3D.Material>
					<!-- Материал которым покрывается предмет -->
				</GeometryModel3D.Material>
			</GeometryModel3D>
		</ModelVisual3D.Content>
	</ModelVisual3D>
</Viewport3D>

Универсальный ModelVisual3D

Из структуры XAML кода видно, что трехмерные объекты, принадлежащие Viewport3D, являются родственными по классу ModelVisual3D. Источник света, сетчатый объект обертываются разметкой элемента ModelVisual3D. И даже создавая собственный класс для визуализации 3D предметов придётся наследовать его от ModelVisual3D. Окно просмотра Viewport3D может содержать в себе любой трехмерный объект, наследуемый от абстрактного класса Visual3D.

Создание 3D объектов

Координаты трехмерных объектов WPF 3D

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

Координаты размещения сетчатых объектов выражаются относительными величинами, например: по оси Х от -1 до 1, аналогично и по другим осям. Вместо единиц могут быть и другие значения, в зависимости от принятого размера 3D сцены. Координаты вершин треугольников в правосторонней системе координат перечисляются против часовой стрелки. Тогда у треугольника будет видна передняя часть фигуры с назначенным материалом. Не воспрещается перечислять точки фигуры по часовой стрелке, но только тогда будет видна задняя часть треугольника.

Построение трехмерного прямоугольника

Инициализация 3D графики WPF

Основываясь на вышеописанном и обладая некоторыми знаниями 3D программирования создадим из четырех базовых фигур прямоугольник. Определять вершины треугольников будем в направлении против часовой стрелки.

Создать трехмерный прямоугольник можно одним экземпляром MeshGeometry3D, тогда материал и координаты будут целостными для всех треугольников входящих в состав прямоугольника. Или же каждый треугольник определить отдельным экземпляром MeshGeometry3D, тогда можно применять трансформацию и материалы к каждому треугольнику отдельно. Строить простейшие объекты удобнее в XAML файле, но более сложные трехмерные объекты проще писать программным кодом.

Листинг разметки XAML построения трехмерного, цветного прямоугольника. Каждый треугольник имеет материал собственного цвета.
<Viewport3D>
    <Viewport3D.Camera>
        <OrthographicCamera Position="0,0,1" LookDirection="0,0,-1" 
                UpDirection="0,1,0" Width="5"></OrthographicCamera>
    </Viewport3D.Camera>
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <AmbientLight Color="White" ></AmbientLight>
        </ModelVisual3D.Content>
    </ModelVisual3D>

    <ModelVisual3D>
        <ModelVisual3D.Content>
            <GeometryModel3D >
                <GeometryModel3D.Geometry>
                    <MeshGeometry3D Positions="-1.4,-0.8,0 1.4,-0.8,0 0,0,0" />
                </GeometryModel3D.Geometry>
                <GeometryModel3D.Material>
                    <DiffuseMaterial Brush="Red"></DiffuseMaterial>
                </GeometryModel3D.Material>
            </GeometryModel3D>
        </ModelVisual3D.Content>
    </ModelVisual3D>
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <GeometryModel3D >
                <GeometryModel3D.Geometry>
                    <MeshGeometry3D Positions="1.4,-0.8,0 1.4,0.8,0 0,0,0" />
                </GeometryModel3D.Geometry>
                <GeometryModel3D.Material>
                    <DiffuseMaterial Brush="Blue"></DiffuseMaterial>
                </GeometryModel3D.Material>
            </GeometryModel3D>
        </ModelVisual3D.Content>
    </ModelVisual3D>
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <GeometryModel3D >
                <GeometryModel3D.Geometry>
                    <MeshGeometry3D Positions="-1.4,0.8,0 0,0,0 1.4,0.8,0" />
                </GeometryModel3D.Geometry>
                <GeometryModel3D.Material>
                    <DiffuseMaterial Brush="Green"></DiffuseMaterial>
                </GeometryModel3D.Material>
            </GeometryModel3D>
        </ModelVisual3D.Content>
    </ModelVisual3D>
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <GeometryModel3D >
                <GeometryModel3D.Geometry>
                    <MeshGeometry3D Positions="-1.4,-0.8,0 0,0,0 -1.4,0.8,0" />
                </GeometryModel3D.Geometry>
                <GeometryModel3D.Material>
                    <DiffuseMaterial Brush="Yellow"></DiffuseMaterial>
                </GeometryModel3D.Material>
            </GeometryModel3D>
        </ModelVisual3D.Content>
    </ModelVisual3D>
</Viewport3D>

Программный код создания трехмерного прямоугольника

Среда программирования MS Visual Studio 2019 версии 16.8. .NET 5.0. Код полностью написан на языке разметки XAML.

Скачать исходник