一个 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 中大约多出两个单位的蓝色。注释里有一个 测量值,是在冻结昼夜相位时取的。
Camera.Far = 1300f 不是为舒服选的整数。
有两样东西必须装进去:天空盒半程是 450 米,所以朝角落的最长射线
大约是 779 米;而海是 1400 米见方,所以最远的钳制相机位置离最远
的海角大约 1240 米。更小的远平面会在天空盒顶部切出一条,或在底部
露出接缝。视野是 MathF.PI * 13 / 36f
— 65 度。
一个 enum Mode { Show, Play, Edit, Debug } 决定
哪些面板可见。它默认是 Play,更新循环每帧读
它,而不是重建任何东西。
| 模式 | 它显示什么 |
|---|---|
Show | UI 让开的场景 — 截图用的。 |
Play | 方向键、技能按钮、设置、AI 按钮。默认。 |
Edit | 对象拾取器和绘制调色板,用于放置资产。 |
Debug | Views 面板: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 队列加载,而不是阻塞第一帧。
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。