(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序

本文详述了从最简单的.NET Core控制台应用出发,逐步改造成UWP程序的过程,包括修改csproj文件、编写AppxManifest和AssemblyInfo.cs,以及解决部署和运行中的问题。通过这一实践,作者揭示了UWP项目的基本组成和启动流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每次使用 Visual Studio 的模板创建一个 UWP 程序,我们会在项目中发现大量的项目文件、配置、应用启动流程代码和界面代码。然而这些文件在 UWP 程序中到底是如何工作起来的?

我从零开始创建了一个 UWP 程序,用于探索这些文件的用途,了解 UWP 程序的启动流程。


本文分为两个部分:

本文将一个普通项目改造成 UWP 项目,重点在了解 UWP 的项目文件组成。

从最简单的项目模板开始

虽然可以从零开始写一个 csproj 文件,不过这并没有什么技术含量,因为新的 csproj 文件实在是非常简单。参见:

于是,我创建一个 .NET Core 控制台应用。当然,其它简单的如 .NET Standard 库都是一样的,反正最后都会被我改得面目全非。

创建 .NET Core 控制台应用

于是我得到了一个 csproj 项目文件和包含有应用程序入口的 Program.cs 文件。

两个文件

其中 csproj 文件内容非常简单:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>
</Project>

Program.cs 文件也是:

// using System;

namespace Walterlv.Demo.ZeroUwp
{
   
   
    class Program
    {
   
   
        static void Main(string[] args)
        {
            // 这一句需要删除,因为 UWP 程序中不能使用控制台。
            // Console.WriteLine("Hello World!");
        }
    }
}

不过,这两个文件都会被改掉的,已经无所谓里面是什么内容了。

将项目改造成 UWP 项目

UWP 程序的输出类型是 AppContainerExe,而不是一般的 Library 或者 Exe。

另外,基于 Microsoft.NET.Sdk 的新 csproj 格式不支持 UWP 应用程序。所以我希望借助第三方的 MSBuild.Sdk.Extras 来编译 UWP 的项目。参见 新 csproj 对 WPF/UWP 支持不太好?有第三方 SDK 可以用!MSBuild.Sdk.Extras

然而实际情况也不容乐观,因为此第三方 Sdk 只支持 UWP 的库程序,而不支持应用程序容器。所以即便修改为以下方式,最终也因为缺少 Visual Studio RunCommand 的支持,而导致无法启动。

<Project Sdk="MSBuild.Sdk.Extras/1.6.41">

  <PropertyGroup>
    <OutputType>AppContainerExe</OutputType>
    <TargetFrameworks>uap10.0.17134</TargetFrameworks>
  </PropertyGroup>

</Project>

使用以上新 Sdk 的 csproj 格式,我完整地写完了整个 csproj 文件和后续步骤,依然无法解决下面这个错误提示框:

RunCommand Property is not defined
▲ 无法启动

所以我们依然只能使用传统的 csproj 文件格式。里面大部分的内容从模板中复制而来。事实上,我寻找了很多资料,都没有找到让支持 Sdk 的新 csproj 格式支持 UWP 的主程序。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProjectGuid>{09A58639-DC50-41C1-8BCE-A2217A1D3327}</ProjectGuid>
    <OutputType>AppContainerExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Walterlv.Demo.ZeroUwp</RootNamespace>
    <AssemblyName>Walterlv.Demo.ZeroUwp</AssemblyName>
    <DefaultLanguage>en-US</DefaultLanguage>
    <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
    <TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.17134.0</TargetPlatformVersion>
    <TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>
    <MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\x86\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>x86</PlatformTarget>
    <UseVSHostingProcess>false
<think>好的,我现在需要帮助用户了解如何在HoloLens上从零开始创建一个工程并渲染三维高斯场景。用户之前已经询问过大致步骤,现在他们希望得到一个更详细的逐步指南,从创建工程开始,一直到设置部署。我需要确保我的回答详细且易于跟随,适合可能有UnityHoloLens开发经验的用户,但可能对具体步骤不太熟悉。 首先,用户的需求是从创建工程开始,逐步设置工程。之前的回复已经涵盖了关键步骤,但可能不够详细。我需要拆解每个步骤,确保用户能够按部就班地进行操作。可能需要包括安装必要的软件、配置Unity项目、导入MRTK、设置场景、编写脚本、优化性能等。 用户可能对HoloLens开发不太熟悉,所以需要解释清楚每个步骤的目的操作方法。例如,如何安装Unity的正确版本,如何通过Package Manager导入MRTK,如何配置相机场景设置,如何编写生成高斯点云的脚本,以及如何配置着色器优化性能。此外,部署到HoloLens设备的具体步骤也需要详细说明,包括构建设置远程调试。 我还需要考虑用户可能遇到的常见问题,比如性能优化、空间映射、交互功能等,并在步骤中提前给出解决方案或提示。例如,在性能优化部分,可能需要提到GPU实例化LOD技术,以及如何在Unity中实现这些。 另外,用户可能希望有一个完整的示例项目结构,包括脚本着色器代码,所以需要提供具体的代码示例,并解释每部分代码的作用。同时,确保代码的准确性兼容性,比如使用C#脚本Unity的Shader语言,并适配HoloLens的硬件限制。 在组织内容时,应该分步骤进行,每个步骤都有明确的标题子步骤,使用户能够逐步跟随。可能还需要使用列表、代码块强调部分来突出重点。同时,语言要简洁明了,避免技术术语过于复杂,或者在必要时进行解释。 最后,需要验证所有步骤的正确性,确保用户按照指南操作能够成功创建工程并运行示例。可能需要参考微软官方文档Unity的最佳实践,以确保信息的准确性。如果有不确定的部分,应该进行标注或建议用户查阅更多资源。</think>以下是从零开始创建 HoloLens 项目并渲染三维高斯场景的详细分步指南: --- ### **第一步:开发环境搭建** #### **1. 安装必要软件** 1. **Unity Hub** - 从 [Unity 官网](https://unity.com/) 下载并安装 Unity Hub。 - 在 Unity Hub 中安装 **Unity 2021.3 LTS**(兼容 HoloLens 2 的最新稳定版本)。 2. **Visual Studio 2022** - 安装时勾选以下组件: - **使用 C++ 的桌面开发** - **通用 Windows 平台开发 (UWP)** - **Windows 10 SDK (10.0.19041.0 或更高版本)** 3. **Windows SDK** - 确保安装 **Windows 10 SDK (10.0.19041.0)**(与 HoloLens 2 兼容)。 --- ### **第二步:创建 Unity 项目** 1. **新建项目** - 在 Unity Hub 中选择 **3D Core 模板**,命名为 `HoloLensGaussianScene`。 - 设置项目路径(建议路径不含中文或空格)。 2. **切换构建平台** - 点击菜单栏 **File > Build Settings**。 - 选择 **Universal Windows Platform**,点击 **Switch Platform**。 - 确认 **Architecture** 为 **ARM64**,**Target Device** 为 **HoloLens**。 --- ### **第三步:导入 MRTK 混合现实工具包** 1. **通过 Package Manager 安装 MRTK** - 点击菜单栏 **Window > Package Manager**。 - 点击左上角 **+** 选择 **Add package from Git URL**,输入: ``` https://github.com/microsoft/MixedRealityToolkit-Unity.git?path=/Assets/MRTK ``` - 等待下载完成。 2. **配置 MRTK 项目设置** - 点击菜单栏 **Mixed Reality > Toolkit > Utilities > Configure Unity Project**。 - 勾选所有选项(如 Spatial Awareness、Input System 等),点击 **Apply**。 3. **添加 MRTK 到场景** - 在 Hierarchy 窗口右键,选择 **Mixed Reality Toolkit > Add to Scene and Configure**。 --- ### **第四步:设置场景基础** #### **1. 配置主相机** - 删除默认的 **Main Camera**。 - 在 MRTK 预制体中找到 **MRTK XR Rig**,拖入场景中。 #### **2. 创建空物体作为高斯场景容器** - 右键 Hierarchy 窗口,创建空物体 **GaussianScene**。 - 添加脚本 `GaussianPointGenerator.cs`(后续步骤编写)。 --- ### **第五步:生成高斯点云数据** #### **1. 创建点预制体** - 右键 Project 窗口,选择 **Create > Prefab**,命名为 `GaussianPointPrefab`。 - 拖入一个 **Sphere** 到场景中,调整缩放为 `(0.1, 0.1, 0.1)`,拖回 Project 窗口保存为预制体。 #### **2. 编写点云生成脚本** - 在 Project 窗口右键 **Create > C# Script**,命名为 `GaussianPointGenerator`。 - 双击打开并替换为以下代码: ```csharp using UnityEngine; public class GaussianPointGenerator : MonoBehaviour { public int numPoints = 1000; // 点数量 public float radius = 2.0f; // 分布半径 public GameObject pointPrefab; // 预制体 void Start() { for (int i = 0; i < numPoints; i++) { // 生成三维高斯分布坐标 Vector3 position = new Vector3( GaussianRandom(0, radius), GaussianRandom(0, radius), GaussianRandom(0, radius) ); GameObject point = Instantiate(pointPrefab, position, Quaternion.identity); point.transform.parent = transform; // 挂载到父物体 } } // 高斯随机数生成(Box-Muller 变换) private float GaussianRandom(float mean, float stdDev) { float u1 = 1.0f - Random.value; float u2 = 1.0f - Random.value; float randStdNormal = Mathf.Sqrt(-2.0f * Mathf.Log(u1)) * Mathf.Sin(2.0f * Mathf.PI * u2); return mean + stdDev * randStdNormal; } } ``` #### **3. 绑定脚本** - 将 `GaussianPointGenerator` 脚本拖到 **GaussianScene** 物体上。 - 在 Inspector 窗口中将 `pointPrefab` 字段赋值为之前创建的 `GaussianPointPrefab`。 --- ### **第六步:编写透明高斯着色器** #### **1. 创建自定义着色器** - 右键 Project 窗口,选择 **Create > Shader > Unlit Shader**,命名为 `GaussianPointShader`。 - 双击打开并替换为以下代码: ```glsl Shader "Custom/GaussianPoint" { Properties { _MainColor ("Color", Color) = (1,1,1,1) _FadeDistance ("Fade Distance", Range(0.1, 5)) = 1.0 } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_instancing // 启用 GPU Instancing #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float size : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; UNITY_INSTANCING_BUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(float4, _MainColor) UNITY_DEFINE_INSTANCED_PROP(float, _FadeDistance) UNITY_INSTANCING_BUFFER_END(Props) v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); // Billboard 效果:始终面向相机 float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; float3 viewDir = normalize(_WorldSpaceCameraPos - worldPos); float3 up = UNITY_MATRIX_V[1].xyz; float3 right = normalize(cross(viewDir, up)); // 根据距离动态调整大小 float distance = length(_WorldSpaceCameraPos - worldPos); float scale = distance * UNITY_ACCESS_INSTANCED_PROP(Props, _FadeDistance); right *= scale; up *= scale; // 计算最终顶点位置 float3 finalPos = worldPos + v.vertex.x * right + v.vertex.y * up; o.pos = mul(UNITY_MATRIX_VP, float4(finalPos, 1.0)); o.size = scale; return o; } fixed4 frag (v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); // 圆形透明度衰减 float alpha = exp(-i.size * i.size * 2.0); fixed4 col = UNITY_ACCESS_INSTANCED_PROP(Props, _MainColor); col.a *= alpha; return col; } ENDCG } } } ``` #### **2. 应用材质到预制体** - 右键 Project 窗口,创建 **Material**,命名为 `GaussianMaterial`。 - 将 Shader 设置为 `Custom/GaussianPoint`,调整颜色 `Fade Distance`。 - 将材质赋给 `GaussianPointPrefab` 预制体。 --- ### **第七步:性能优化** #### **1. 启用 GPU Instancing** - 在 `GaussianMaterial` 的 Inspector 窗口中勾选 **Enable GPU Instancing**。 #### **2. 添加 LOD Group** - 修改 `GaussianPointGenerator.cs`,在生成点时动态添加 LOD: ```csharp // 在 Instantiate 之后添加: LODGroup lod = point.AddComponent<LODGroup>(); lod.SetLODs(new LOD[] { new LOD(0.5f, new Renderer[]{ point.GetComponent<Renderer>() }), new LOD(0.1f, new Renderer[0]) // 远处时消失 }); ``` #### **3. 空间分区加载** - 创建 `SpatialPartitionManager.cs` 脚本,根据用户位置动态加载/卸载点云区块。 --- ### **第八步:部署到 HoloLens** #### **1. 构建设置** - 点击 **File > Build Settings**,确保: - **Target Device**: HoloLens - **Architecture**: ARM64 - **Build Type**: D3D Project - 勾选 **Unity C# Projects** #### **2. 生成 Visual Studio 工程** - 点击 **Build**,选择输出文件夹(如 `Build/UWP`)。 - 等待 Unity 完成导出。 #### **3. 使用 Visual Studio 部署** - 打开生成的 `.sln` 文件。 - 选择 **Release** 配置 **ARM64** 平台。 - 右键项目选择 **Deploy**(需通过 Wi-Fi 或 USB 连接 HoloLens)。 --- ### **第九步:调试与交互** #### **1. 手势交互(MRTK)** - 在 MRTK 配置文件中启用 **Hand Tracking**。 - 添加以下代码实现手势缩放: ```csharp // 在 GaussianScene 物体上添加脚本 public class ScaleHandler : MonoBehaviour { void Update() { if (HandJointUtils.TryGetJointPose(TrackedHandJoint.Palm, Handedness.Right, out MixedRealityPose pose)) { float pinchStrength = HandPoseUtils.CalculatePinchStrength(Handedness.Right); transform.localScale = Vector3.one * (1 + pinchStrength * 2); } } } ``` #### **2. 空间映射** - 在 MRTK 配置中启用 **Spatial Awareness System**。 - 设置 `SpatialAwarenessMeshLevelOfDetail` 为 **Low** 以减少性能消耗。 --- ### **最终效果验证** 1. 佩戴 HoloLens 启动应用。 2. 通过手势(空中点击)调整点云缩放。 3. 观察高斯点云在真实环境中的稳定渲染(透明球体按高斯分布衰减)。 --- ### **常见问题解决** - **问题 1:点云闪烁或穿透现实物体** **解决**:在材质中设置 `ZWrite Off`,并调整渲染队列为 `"Queue"="Transparent+100"`。 - **问题 2:帧率低于 30 FPS** **解决**: 1. 减少 `numPoints` 至 500 以下。 2. 在着色器中移除复杂的 Billboard 计算。 3. 使用 MRTK 的性能分析工具(**Mixed Reality Toolkit > Diagnostics > Profiler**)。 --- 通过以上步骤,你可以完成从零到 HoloLens 设备上渲染三维高斯场景的全流程。如需更高级功能(如动态更新高斯参数),可进一步集成 Compute Shader 或 Azure 空间锚点服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值