You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET MAUI中使用ThreeLib NuGet包实现3D模型展示

在MAUI中使用ThreeLib实现3D功能的解决方案

核心认知纠正

ThreeLib是Three.js的C#对象模型绑定,本身不提供MAUI的3D渲染能力——它的作用是用C#代码构建Three.js兼容的场景结构并导出JSON,最终需要配合能渲染Three.js的容器(如MAUI的WebView)或原生3D渲染层才能显示。你之前尝试直接将THREE.Scene添加到MAUI的Grid中,会因为Scene不是IView类型报错,这是本质认知偏差导致的。


推荐实现方案:WebView + Three.js渲染(新手友好、易落地)

利用ThreeLib生成场景JSON,通过MAUI的WebView加载本地HTML页面,用Three.js完成最终渲染和模型加载,是最快速的实现路径。

步骤1:修正C#场景生成代码

先完善你的Graphics3d.cs,确保相机、灯光配置正确,并保留导出JSON的逻辑:

using Newtonsoft.Json;
using THREE;
using THREE.Cameras;
using THREE.Lights;
using THREE.Math;

namespace ThreeLib3D.Graphics
{
    public static class Graphics3d
    {
        public static string CreateSceneJson() 
        {
            var scene = new Scene
            {
                Background = new Color(255, 255, 0).ToInt(),
                Name = "CarScene"
            };

            // 配置相机(给相机命名方便前端获取)
            var perspectiveCamera = new PerspectiveCamera()
            {
                Name = "MainCamera",
                Fov = 45.0f,
                Aspect = 16/9f, // 初始宽高比
                Position = new Vector3(2.0f, 1.0f, 4.0f),
                Rotation = new Euler(-8.0f * (float)Math.PI/180, 30.0f * (float)Math.PI/180, 0), // 转弧度
            };
            scene.Add(perspectiveCamera);

            // 添加环境光
            var ambientLight = new AmbientLight(0xffffff, 0.6f)
            {
                Position = new Vector3(2.0f, 1.0f, 4.0f)
            };
            scene.Add(ambientLight);

            // 返回场景JSON
            return scene.ToJSON(true);
        }
    }
}

步骤2:创建Three.js渲染的HTML页面

在MAUI项目中新建wwwroot文件夹,添加3d-viewer.html文件(设置为Content,并勾选"复制到输出目录"):

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body, html { margin:0; padding:0; width:100%; height:100%; overflow:hidden; }
        #container { width:100%; height:100%; }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/examples/js/loaders/GLTFLoader.js"></script>
</head>
<body>
    <div id="container"></div>
    <script>
        window.init3D = function(sceneJson, modelUrl) {
            const container = document.getElementById('container');
            // 初始化渲染器
            const renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(container.clientWidth, container.clientHeight);
            renderer.setPixelRatio(window.devicePixelRatio);
            container.appendChild(renderer.domElement);

            // 解析C#传递的场景JSON
            const scene = new THREE.ObjectLoader().parse(sceneJson);
            const camera = scene.getObjectByName('MainCamera');

            // 加载汽车模型(支持.glb/.gltf)
            const loader = new THREE.GLTFLoader();
            loader.load(modelUrl, (gltf) => {
                const car = gltf.scene;
                // 调整模型姿态(和你之前的配置一致)
                car.position.set(0, 0, 0);
                car.scale.set(0.004, 0.004, 0.004);
                car.rotation.x = -Math.PI/2;
                scene.add(car);
            });

            // 渲染循环
            function animate() {
                requestAnimationFrame(animate);
                renderer.render(scene, camera);
            }
            animate();

            // 响应窗口大小变化
            window.addEventListener('resize', () => {
                renderer.setSize(container.clientWidth, container.clientHeight);
                camera.aspect = container.clientWidth / container.clientHeight;
                camera.updateProjectionMatrix();
            });
        }
    </script>
</body>
</html>

步骤3:MAUI页面集成WebView

修改MainPage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThreeLib3D.MainPage">
    <Grid>
        <WebView x:Name="ThreeDWebView" Source="wwwroot/3d-viewer.html" />
    </Grid>
</ContentPage>

修改MainPage.xaml.cs,在WebView加载完成后传递场景JSON和模型路径:

using ThreeLib3D.Graphics;

namespace ThreeLib3D
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            ThreeDWebView.Navigated += OnWebViewNavigated;
        }

        private async void OnWebViewNavigated(object sender, WebNavigatedEventArgs e)
        {
            if (e.Result == WebNavigationResult.Success)
            {
                var sceneJson = Graphics3d.CreateSceneJson();
                // 模型路径:假设汽车模型放在wwwroot下,名为car.glb
                var modelUrl = "car.glb";
                await ThreeDWebView.EvaluateJavaScriptAsync($"init3D({sceneJson}, '{modelUrl}')");
            }
        }
    }
}

解决你的三个具体问题

  1. 导入3D模型:
    上面的方案通过前端Three.js的GLTFLoader直接加载模型,无需通过ThreeLib的GUID方式。如果坚持用C#加载,需确认ThreeLib是否提供对应加载器(如GLTFLoader),加载后将模型对象添加到Scene再导出JSON。

  2. 展示THREE.Scene:
    THREE.Scene不是MAUI的可视化控件,必须通过WebView渲染(推荐)或自定义原生平台Handler(难度高)。WebView方案无需深入原生3D开发,适合新手。

  3. 加载器与渲染器:

    • 加载器:Three.js提供GLTFLoader/OBJLoader等,直接在前端使用更灵活;ThreeLib若有对应加载器,可在C#中加载模型到Scene。
    • 渲染器:必须用Three.js的WebGLRenderer,在WebView的HTML中初始化并执行渲染循环。

关于自定义Handler的补充(进阶方案)

如果追求原生性能,需针对各平台写自定义Handler:

  • Android:绑定GLSurfaceView,用OpenGL ES实现Three.js风格的渲染
  • iOS:绑定MTKView,用Metal渲染
  • Windows:绑定SwapChainPanel,用DirectX渲染
    但该方案需要深厚的原生3D开发经验,不适合刚接触MAUI的开发者。

内容的提问来源于stack exchange,提问作者Ishan Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:15:59