如何在.NET MAUI应用中离线集成交互式3D模型(无需Evergine/WebView)
适用于.NET MAUI的离线3D模型集成方案
针对你的需求,推荐两个无需新增独立项目、支持离线运行的方案,均能实现旋转、缩放、车门交互等功能,适配你现有的.glb/.gltf模型格式。
方案1:SharpGLTF + MAUI GraphicsView(轻量易用)
SharpGLTF是一个.NET生态的3D模型加载库,可直接嵌入MAUI项目,无需额外依赖,适合中等复杂度的3D展示需求。
步骤1:安装依赖
通过NuGet安装以下包:
Install-Package SharpGLTF.Core Install-Package SharpGLTF.Toolkit
步骤2:配置模型资源
将你的.glb/.gltf模型文件添加到MAUI项目的Resources/Raw目录,设置生成操作为MauiAsset,确保文件能被离线访问。
步骤3:自定义3D交互视图
创建继承自GraphicsView的自定义视图,实现模型加载、渲染和交互:
using Microsoft.Maui.Graphics; using SharpGLTF.Scenes; using SharpGLTF.Materials; using System.Numerics; namespace CarMonitorApp; public class Car3DView : GraphicsView { private SceneModel? _carScene; private float _rotX = 0f; private float _rotY = 0f; private float _scale = 1.0f; private PointF _lastTouchPos; public Car3DView() { LoadCarModel(); AddGestureRecognizers(); } private void LoadCarModel() { // 从项目资源加载模型 var modelPath = "Resources/Raw/car_model.glb"; using var stream = FileSystem.OpenAppPackageFileAsync(modelPath).Result; _carScene = SceneModel.Load(stream); } private void AddGestureRecognizers() { // 单指旋转 var panGesture = new PanGestureRecognizer(); panGesture.PanUpdated += (s, e) => { if (e.StatusType == GestureStatus.Running) { _rotY += (e.TotalX - _lastTouchPos.X) * 0.5f; _rotX += (e.TotalY - _lastTouchPos.Y) * 0.5f; _lastTouchPos = new PointF(e.TotalX, e.TotalY); Invalidate(); } else if (e.StatusType == GestureStatus.Started) { _lastTouchPos = new PointF(e.TotalX, e.TotalY); } }; // 双指缩放 var pinchGesture = new PinchGestureRecognizer(); pinchGesture.PinchUpdated += (s, e) => { if (e.StatusType == GestureStatus.Running) { _scale *= e.Scale; _scale = Math.Clamp(_scale, 0.5f, 3.0f); Invalidate(); } }; GestureRecognizers.Add(panGesture); GestureRecognizers.Add(pinchGesture); } protected override void Draw(ICanvas canvas, RectF dirtyRect) { base.Draw(canvas, dirtyRect); if (_carScene == null) return; // 设置渲染中心 canvas.SaveState(); canvas.Translate(dirtyRect.Center.X, dirtyRect.Center.Y); canvas.Scale(_scale); canvas.RotateX(_rotX); canvas.RotateY(_rotY); // 遍历模型节点渲染(简化版,可扩展支持纹理、光照) foreach (var node in _carScene.RootNode.VisualChildren) { if (node.Mesh == null) continue; foreach (var primitive in node.Mesh.Primitives) { var material = primitive.Material; canvas.FillColor = Color.FromRgb( material.BaseColorFactor.R, material.BaseColorFactor.G, material.BaseColorFactor.B ); // 获取顶点数据并绘制三角形 var positions = primitive.VertexAccessors["POSITION"].AsVector3Array(); for (int i = 0; i < positions.Count; i += 3) { canvas.DrawPolygon( new PointF(positions[i].X, positions[i].Y), new PointF(positions[i+1].X, positions[i+1].Y), new PointF(positions[i+2].X, positions[i+2].Y) ); } } } canvas.RestoreState(); } // 车门切换方法(需匹配模型中车门节点的名称) public void ToggleDoor(string doorNodeName) { if (_carScene == null) return; var doorNode = _carScene.RootNode.FindNode(doorNodeName); if (doorNode == null) return; // 切换车门旋转角度(0° ↔ 90°) var currentRot = doorNode.LocalTransform.Rotation; var newYaw = currentRot.Y < MathHelper.DegreesToRadians(90) ? MathHelper.DegreesToRadians(90) : 0f; doorNode.LocalTransform = doorNode.LocalTransform.WithRotation( Quaternion.FromYawPitchRoll(newYaw, 0f, 0f) ); Invalidate(); } }
步骤4:在XAML中使用视图
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:CarMonitorApp" x:Class="CarMonitorApp.MainPage"> <Grid> <local:Car3DView x:Name="Car3DDisplay" /> <Button Text="切换左前门" Clicked="OnToggleDoorClicked" HorizontalOptions="Center" VerticalOptions="End" Margin="20"/> </Grid> </ContentPage>
后台代码绑定按钮事件
namespace CarMonitorApp; public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } private void OnToggleDoorClicked(object sender, EventArgs e) { // 替换为你模型中左前门节点的实际名称 Car3DDisplay.ToggleDoor("FrontLeftDoor"); } }
方案2:OpenTK.Maui(复杂3D渲染)
如果需要更专业的3D效果(如光照、纹理、阴影),可以使用OpenTK的MAUI绑定,它提供完整的OpenGL渲染能力,同样无需额外项目。
核心步骤
- 安装NuGet包:
OpenTK.Maui - 创建继承自
OpenGLView的自定义视图,在OnLoad中加载模型、编译着色器,在OnRenderFrame中完成渲染 - 手势识别和车门交互逻辑与方案1类似,通过修改模型节点变换实现
注意事项
- 模型节点名称需与Blender等建模工具中定义的名称一致,可通过SharpGLTF的调试工具查看节点层级
- 可根据需求优化渲染逻辑,比如添加纹理映射、光照计算
- 确保模型文件的生成操作设置正确,避免离线加载失败
内容的提问来源于stack exchange,提问作者Ishan Sharma
相关产品推荐
相关产品推荐

