MIT 许可证 NuGet

首页 / 示例 / Apps/Engine

Apps/Engine

一个 1920×1080 的岛屿,每个渲染特性都打开、每个旋钮都暴露。 这是截图来自的应用,也是这些指南大多数都是读它写出来的应用。

它如何配置自己

整个初始化就是一个构造函数。两个质量默认值被覆盖,相机被设置; 其他一切都是引擎默认。

internal App()
{
    Title = "SeasonEngine";
    StorageService.DirectoryBase = "SeasonEngine";
    BackgroundColor = Season.Basic.Colors.White;
    BasicResolution = new Vector2(1920, 1080);

    RenderQuality.DefaultGlobalIllumination = GiMode.Ddgi;
    RenderQuality.DefaultAerialIntensity = 12f;

    ResetCamera();
}

两个覆盖在源码里都带有一段推理。12 的空气透视强度是最值得读的: 它是一个 lerp 权重而不是乘数,物理值是 1,而在 1 时,一个只有几百米 宽的世界里,远处的山在 255 中大约多出两个单位的蓝色。注释里有一个 测量值,是在冻结昼夜相位时取的。

为什么远平面是 1300

Camera.Far = 1300f 不是为舒服选的整数。 有两样东西必须装进去:天空盒半程是 450 米,所以朝角落的最长射线 大约是 779 米;而海是 1400 米见方,所以最远的钳制相机位置离最远 的海角大约 1240 米。更小的远平面会在天空盒顶部切出一条,或在底部 露出接缝。视野是 MathF.PI * 13 / 36f — 65 度。

四种模式

一个 enum Mode { Show, Play, Edit, Debug } 决定 哪些面板可见。它默认是 Play,更新循环每帧读 它,而不是重建任何东西。

模式它显示什么
ShowUI 让开的场景 — 截图用的。
Play方向键、技能按钮、设置、AI 按钮。默认。
Edit对象拾取器和绘制调色板,用于放置资产。
DebugViews 面板:compute 输出作为精灵显示在屏幕上。
编辑模式,一个对象被拾取器选中并描边 编辑
调试模式,多张 compute 输出纹理作为精灵显示 调试

场景,逐面板

Create() 按加载顺序添加面板。每个都是 Apps/Engine/Panels 里自成一体的类,每个都是 一个引擎特性的完整示例。

面板它做什么它演示的特性
CelestialLighting驱动太阳和月亮、环境光、天气和 SH 环境光更新。昼夜循环、SceneLighting
Sky天空盒与程序化天空选择。SkyMode、大气
Ground、Sea草地和道路,以及一个程序化海面。自定义网格、材质
Rocks从一个 glb 中取出的十五种岩石变体,散布在东海岸,有些半埋。InstancedMesh3D、后台加载
Mountains一圈由四种变体组成的背景山,留下一个东西向的缺口,让日出和日落可见。远距离实例化
Robots两列十个机器人播放不同剪辑,头顶有对话气泡。InstancedModel 动画、MSDF 文本
Birds二十只海鸥,有直线和盘旋行为、鸟群分离、避障和一个俯仰翻滚姿态解算器。由模拟驱动的实例化动画
Player、Direction、Skill一个角色、一个带世界和角色移动模式的方向键,以及一个带抛物线弧和碰撞的跳远。模型动画、输入、相机装备
House、Room、StreetLight、Ball、Sphere单个道具和一个室内。glTF 加载、点光源、PBR
Painting一个底部工具栏,预览一个 glb、把它锚定到光标、点击时放进场景。屏幕到世界的放置
Setting、SettingPanel一个按钮和它后面的运行时设置屏幕。RenderQuality.Current、WorldSettings
Views按名字绑定到 compute 输出纹理的调试模式精灵。ComputeEffect 输出
Logo、AIButton品牌,以及 AI 面板的入口。叠加控件

Apps/Engine/Management 装着两个不是面板的行为: PlayerCollider 和 OcclusionFade,后者淡出挡在相机和玩家之间的 几何体。Rocks 和 Mountains 通过引擎的 RequestLoad 队列加载,而不是阻塞第一帧。

十个 compute 效果,按顺序

RegisterEffects() 在 Create() 里最先运行。注册顺序就是相位内的执行 顺序,所以这张表也是帧。

PlasmaEffect          // FrameStart  - compute baseline smoke test
SceneColorCopyEffect  // AfterScene  - downsampled scene colour
TaaEffect             // AfterScene  - must precede bloom
BloomEffect           // AfterScene
DepthViewEffect       // AfterScene  - debug view
GtaoEffect            // AfterScene  - publishes FrameSchedule.AoTexture
VelocityViewEffect    // AfterScene  - debug view
Sdf3DViewEffect       // FrameStart  - slices a 3D volume for display
DdgiEffect            // AfterScene  - probe and SDF volumes
SkyAtmosphereEffect   // FrameStart  - sky, cloud noise and aerial LUTs

这每一个都用返回值外的 if 注册,而会显示它 输出的调试控件只在注册成功时才添加。这是要抄的模式:在没有着色器 源码的后端上,效果就简单地缺席,其他一切不变。见 Compute 效果。

设置屏幕

SettingPanel 是应用里最大的类,如果你在构建 自己的设置 UI,它也是最值得读的一个。它直接绑定到 RenderQuality.Current 和 WorldSettings.Current,并在变更时写入。

运行时暴露:模式、移动模式、视野、昼夜速度和起始时刻、移动步长、 抗锯齿模式、DDGI 开关、级联阴影参数、GTAO,以及阴影法线偏移。 启动后不能改变的值不给滑块 — 这是一条值得抄的规则,因为一个 直到下次启动才默默生效的控件,比一个缺席的控件更糟。

因为 RenderQuality.Current 住在持久化设置里, 这里改的一切都能活过重启。见渲染质量。

拾取与编辑

ObjectPicker 面板用两个列表配置 — 单个控件 的 Targets 和实例化控件的 InstancedTargets — 并自己处理射线投射、 描边和变换读数。结合 Painting,那就是整个应用内 编辑循环:点击选中、读数字、在光标处放一个新资产。

这是对「没有编辑器」的回答。它不是编辑器 — 但它把「猜一个坐标、 重建、看」变成「点那个东西、读它的坐标」。见 拾取、高亮与编辑。

构建它,诚实地

这个项目不能从干净克隆构建

Engine.csproj 带着一条无条件的 <ProjectReference Include="..\..\..\SeasonAI\SeasonAI.csproj" />, 而 AI 项目不在本仓库里。它自己对 Season.csproj 的引用被注释掉了,所以引擎 通过那条引用传递进来 — 这意味着删掉 AI 引用不是一行改动。还有 一个构建后 target,在 Windows 上从兄弟 cudacudnn-runtime 目录复制 ONNX Runtime 二进制。

今天要跑点什么:Samples/Creator 从全新克隆构建, 没有外部依赖;或者从下载拿打包好的 Windows 构建。 要构建这个,恢复 Season.csproj 引用,并删掉 AI 引用以及 Create() 里的 AIButton 和 AIPanel 使用 — 面板本身已经通过一个 Compile Remove 被排除在编译之外。

Windows 上的打包是 MSIX,SelfContained 和 WindowsAppSDKSelfContained 都为真,这就是 Store 构建很大、以及它不需要安装运行时的原因。目标框架是 net10.0、 net10.0-android、 net10.0-ios、 net10.0-maccatalyst,以及在 Windows 主机上的 net10.0-windows10.0.19041.0。