WPF – HelixToolkit VS HelixToolkit.SharpDX 성능비교와 SharpDX 사용법

이 Post 에서는 WPF 상에서 HelixToolkit 과 HelixToolkit.SharpDX 의 성능을 비교해 보고, 월등한 성능의 SharpDX 를 사용하는 방법을 확인 합니다.

영상을 보시면 아시겠지만, HelixToolkit SharpDX 가 월등히 성능이 좋습니다.
레퍼런스가 더 많고, 접근성이 좋아 HelixToolkit 을 사용하는 경우가 훨씬 많지만 많은 3D 객체를 랜더링 하거나 실시간 상호작용이 필요한 경우에는 HelixToolkit SharpDX 를 사용하는 편이 좋습니다.

WPF, .NET Core 8.0 에서 테스트 했습니다.

0. 패키지

Nuget 에서 HelixToolkit.SharpDX.Core.Wpf 을 검색하여 설치 합니다.
.Net Framework 를 사용 하신다면 Core 가 붙지 않은 패키지를 설치 하시면 됩니다.

1. MainWIndow.xaml

<Window x:Class="HelixToolkitTest00_01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HelixToolkitTest00_01"
		xmlns:hx="http://helix-toolkit.org/wpf/SharpDX"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
	<Grid>
		<hx:Viewport3DX x:Name="viewPort"
                Background="Black"
				BackgroundColor="Black"
				ShowCoordinateSystem="True"
				ZoomAroundMouseDownPoint="True"
				RotateAroundMouseDownPoint="True">
			<hx:Viewport3DX.InputBindings>
				<MouseBinding Command="hx:ViewportCommands.Rotate" Gesture="LeftClick"/>
				<MouseBinding Command="hx:ViewportCommands.Pan" Gesture="RightClick"/>
			</hx:Viewport3DX.InputBindings>
			<hx:AmbientLight3D Color="#808080"/>
			<hx:DirectionalLight3D Color="White" Direction="-1,-1,-1" />
		</hx:Viewport3DX>
		<TextBlock Text="Helix Toolkit SharpDX 1000 Sphere" 
		   HorizontalAlignment="Center" 
		   VerticalAlignment="Top" 
		   Margin="0,10,0,0" 
		   FontSize="40"
		   Foreground="White"/>
	</Grid>
</Window>

7: HelixToolkit 의 namespace 를 지정 합니다.
11: Viewport3DX 추가
18~19: 마우스 왼쪽에 Rotate, 마우스 오른쪽에 Pan 을 연결 합니다. 이 설정을 안해주면 마우스 우측이 Rotate, 마우스 가운데 버튼을 누르면 Pan 으로 동작 합니다.
기본 설정이 좀 어색할 수 있지만, 사실 3D 객체를 클릭해서 어떤 액션을 취하거나 이벤트를 받기 위해서는 기본 설정이 더 낫습니다.
여기서는 딱히 3D 객체에 어떤 액션을 취할것이 아니기 때문에 익숙한 설정으로 변경 합니다.
21, 22: 기본 Light 를 설정 합니다. HelixToolkit 에서는 DefalutLight 로 퉁 쳤었지만 SharpDX 에서는 설정해 줘야 합니다.

2. MainWindow.xaml.cs – 초기화

using HelixToolkit.SharpDX.Core;
using HelixToolkit.Wpf.SharpDX;
using SharpDX;
using System.Windows;

public MainWindow()
{
	InitializeComponent();

	viewPort.EffectsManager = new DefaultEffectsManager();
	viewPort.Camera = new PerspectiveCamera
	{
		Position = new System.Windows.Media.Media3D.Point3D(100, 100, 100),
		LookDirection = new System.Windows.Media.Media3D.Vector3D(-3, -3, -3),
		UpDirection = new System.Windows.Media.Media3D.Vector3D(0, 1, 0),
		FarPlaneDistance = 500
	};

	this.Loaded += MainWindow_Loaded;
}

10: 랜더링 효과를 관리하는 매니저를 초기화 합니다.
11: 카메라를 설정 합니다.

3. MainWindow.xaml.cs – 구 그리기

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
	Random random = new Random(Guid.NewGuid().GetHashCode() + DateTime.Now.Millisecond);

	for (int i = 0; i < 1000; i++)
	{
		CreateSphere(
			random.Next(1, 100),
			random.Next(1, 100),
			random.Next(1, 100));
	}

	MessageBox.Show("구 생성 완료");
}

private void CreateSphere(float x, float y, float z, double radius = 1, int thetaDiv = 32, int phiDiv = 32)
{
	var builder = new MeshBuilder();
	builder.AddSphere(new Vector3(x, y, z), radius, thetaDiv, phiDiv);
	
	var sphere = new MeshGeometryModel3D
	{
		Geometry = builder.ToMeshGeometry3D(),
		Material = PhongMaterials.Red,
	};

	viewPort.Items.Add(sphere);
}

실제 구를 생성하는 부분입니다.
CreateSphere 에서 구를 생성하고 그걸 1000 회 반복 합니다.
구 하나는 위도 경도에 따라 기본적으로 32×32 개의 사각형을 가지게 됩니다.
사각형 하나는 두개의 폴리곤으로 구성이 되므로 2048 개의 폴리곤을 가지게 됩니다.
thetaDiv 나 phiDiv 를 줄이면 부하를 줄일 수 있지만 원의 모양은 점점 각이져 보이게 됩니다.

4. 사각형의 경우

private void CreateCube()
{
	var builder = new MeshBuilder();
	builder.AddBox(new Vector3(0, 0, 0), 1, 1, 1); // 중심(0,0,0)에, 각 변의 길이 1

	var cube = new MeshGeometryModel3D
	{
		Geometry = builder.ToMeshGeometry3D(),
		Material = DiffuseMaterials.Green,
	};

	viewPort.Items.Add(cube);
}

사각형 또한 다음과 같이 간단히 생성 할 수 있습니다.

기존에 개인적으로 실시간 3D 산점도 차트를 HelixToolkit 으로 만들려다가 부하 때문에 실패 했었습니다.

다른 라이브러리를 알아보다가 HelixToolkit.SharpDX 를 확인하게 되었는데, 상당히 만족스럽습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤