Files
minecraft-dlss/README.md
T

260 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Wpyw DLSS — Minecraft Java 1.20.1 (Fabric)
在 Minecraft Java 版里接入 **NVIDIA DLSS 超分(Super Resolution)** 与 **帧生成(Frame Generation / 插帧)**。
> 工程名 `wpywdlss` / `MinecraftDLSS` 是**临时名**,随你改。
---
## 一、先讲清楚三个硬事实(省掉走弯路的成本)
### 1. DLSS 5 不是超分,也不是插帧
| | 超分 | 插帧 | 本质 |
|---|---|---|---|
| **DLSS 4** | ✅ Super Resolution | ✅ Multi Frame Generation(最高 6X) | 你要的就是这两个 |
| **DLSS 5** | ❌ | ❌ | **3D 引导神经渲染**:重建材质 / 光照 / 皮肤 / 阴影 / 反射 |
DLSS 5 于 2026-09-03 上线,**官方仅 RTX 50 系**,目前只有 NBA 2K27 一款游戏,集成走 **UE5 插件**路径。
在 **Streamline SDK 2.14.1 的 `include/` 与 `bin/x64/` 里不存在任何 dlssnr / 神经渲染的头文件或插件**——
即通用 Streamline 层根本没有 DLSS 5 的集成接口。
### 2. Minecraft Java 是 OpenGL,而 NGX 不支持 OpenGL
NGX / Streamline 只支持 **D3D11 / D3D12 / Vulkan**。所以 DLSS 进 MC Java 的唯一办法是:
游戏继续用 OpenGL 渲染,模组**内部再起一个 Vulkan 设备**,用外部内存/信号量把纹理零拷贝共享过去,
在 Vulkan 侧跑 NGX。
### 3. 真正的工程量在「运动矢量」
DLSS 超分必须吃 **运动矢量 + 深度 + 抖动投影矩阵**,而 Minecraft 的 OpenGL 管线**一个都不生产**。
这是本项目 80% 的工作量。在 **Iris + 光影包**环境下更难:Iris 接管整条管线、自己控制投影矩阵与 G-buffer,
且还有 Distant Horizons / Voxy 的 LOD 几何要算速度。
---
## 二、架构
```
┌─ Minecraft 1.20.1 (Java, OpenGL / LWJGL) ──────────────────────────┐
│ Fabric 模组 (本仓库 src/main/java) │
│ • Mixin 投影矩阵亚像素抖动 (jitter) │
│ • Mixin 渲染分辨率 → 低分渲染 world framebuffer │
│ • 导出 depth / motion vector 纹理 │
│ • 在 present 点调用原生桥接 │
└────────────────────────┬──────────────────────────────────────────┘
│ JNI
┌────────────────────────▼──────────────────────────────────────────┐
│ 自研原生桥接 DLL (C++ / MSVC) ← native/ 本项目核心 │
│ • 建 Vulkan 1.2+ 设备(同一块 GPU) │
│ • GL↔VK 外部内存互操作 │
│ GL_EXT_memory_object_win32 ↔ VK_KHR_external_memory_win32 │
│ GL_EXT_semaphore_win32 ↔ VK_KHR_external_semaphore_win32 │
│ • slInit / slSetVulkanDevice / slSetConstants │
│ • slDLSSSetOptions + slEvaluateFeature (超分) │
│ • slDLSSGSetOptions (帧生成) │
└────────────────────────┬──────────────────────────────────────────┘
│
┌───────────▼────────────┐
│ sl.interposer.dll │ ← 用户自备,不随模组分发
│ ├─ sl.dlss.dll │ → nvngx_dlss.dll 超分
│ ├─ sl.dlss_g.dll │ → nvngx_dlssg.dll 插帧
│ └─ NvLowLatencyVk.dll│ → Reflex(Vulkan)
└────────────────────────┘
```
---
## 三、NVIDIA 运行时:**绝不打包进模组**
`nvngx_dlss.dll` / `nvngx_dlssg.dll` / `sl.*.dll` 均为 NVIDIA 专有二进制,**不允许随模组再分发**。
本模组只提供**加载逻辑**,二进制由用户自行放置。
运行时查找顺序:
1. JVM 参数 `-Dwpywdlss.runtimeDir=<路径>`
2. `<gameDir>/ngx/`
3. `<gameDir>/config/ngx/`
需要的文件(全部来自 **Streamline SDK 2.14.1 的 `bin/x64/`**):
| 文件 | 大小 | 用途 |
|---|---|---|
| `sl.interposer.dll` | 652,928 | Streamline 核心 |
| `sl.common.dll` | 843,392 | 公共层 |
| `sl.dlss.dll` | 422,016 | 超分插件 |
| `sl.dlss_g.dll` | 636,032 | 帧生成插件 |
| `nvngx_dlss.dll` | 58,956,912 | DLSS 超分模型 (310.9.1.0) |
| `nvngx_dlssg.dll` | 7,460,976 | DLSS 帧生成模型 (310.9.1.0) |
| `NvLowLatencyVk.dll` | 57,840 | Vulkan Reflex(可选) |
> 若 NGX 因缺少 `applicationId` 拒绝加载,可改用 `bin/x64/development/` 下的开发版 DLL 做实验。
---
## 四、构建
### Java 侧(Fabric 模组)
```powershell
$env:JAVA_HOME = 'C:\Program Files\Java\jdk-21.0.10'
.\gradlew.bat build
```
产物:`build/libs/wpywdlss-0.1.0.jar`
版本组合(对齐 Fabric 官方 1.20.1 分支):
`minecraft 1.20.1` · `loader 0.19.5` · `loom 1.17-SNAPSHOT` · `fabric-api 0.92.12+1.20.1` · Mojang 官方映射
### 原生侧(C++ 桥接 DLL)
见 `native/`。使用 MSVC(VS2022 BuildTools 14.44.35207)+ CMake。
**不需要 Vulkan SDK**:Khronos 头文件取自 DLSS demo 自带的
`DLSS_Sample_App/donut/thirdparty/glfw/deps/vulkan/`,导入库由
`dumpbin /exports C:\Windows\System32\vulkan-1.dll` + `lib /def:` 自造。
---
## 五、路线图
| 阶段 | 目标 | 验证方式 |
|---|---|---|
| **P0 地基** | Fabric 工程可编译;原生桥接 DLL 可编译;JNI 打通;Vulkan 设备创建成功;GL↔VK 互操作往返 | 游戏内一张纹理经 GL→VK→GL 往返后画面一致 |
| **P1 数据源** | 深度纹理 + 抖动投影 + 运动矢量。**先在纯净版 / Sodium 下做** | 运动矢量可视化输出正确 |
| **P2 DLSS 超分** | 接 `sl.dlss`,出画面。applicationId 风险在此暴露 | 1080p→4K 提升且画质可接受 |
| **P3 HUD 原生分辨率** | 世界低分渲染、HUD/UI 保持原生清晰 | HUD 文字不糊 |
| **P4 帧生成** | 接 `sl.dlss_g`。最难一步(需接管 present 路径) | 输出帧率提升,伪影可接受 |
| **P5 Iris 兼容** | 在光影包环境下算运动矢量 | 主流光影包下不崩不糊 |
---
## 六、P0 实测结果(已跑通,非推演)
**环境**:RTX 5070 / 驱动 616.92 / Vulkan loader 1.4.341 / Win11 26100
**方式**:`tools/ProbeRunner.java` 独立加载桥接 DLL 调用 `nativeProbe()`,不启动游戏
**结论**:`nativeIsReady() = true`,exit code 0
| 检查项 | 实测结果 |
|---|---|
| Vulkan 实例 | ✅ `VK_SUCCESS`,loader 1.4.341 |
| 物理设备 | 2 个:**RTX 5070**(0x10de, DISCRETE, api 1.4.351)+ AMD 核显(0x1002, INTEGRATED, 1.4.315);自动选中 NVIDIA |
| 设备扩展(291 可用) | ✅ `VK_KHR_external_memory_win32` / `VK_KHR_external_semaphore_win32` / `VK_KHR_timeline_semaphore` / `dedicated_allocation` / `image_format_list` / `synchronization2` 全部可用 |
| 设备创建 | ✅ `VK_SUCCESS`(queue family 0,已启用 timeline semaphore) |
| 互操作函数指针 | ✅ `vkGetMemoryWin32HandleKHR` / `vkGetSemaphoreWin32HandleKHR` / `vkImportSemaphoreWin32HandleKHR` 经 `vkGetDeviceProcAddr` 全部取到 |
| **镜像导出(go/no-go)** | ✅ **`OPAQUE_WIN32`: exportable=YES, importable=YES, dedicatedOnly=no** |
| 信号量 | ✅ `OPAQUE_WIN32`: exportable=YES, importable=YES |
| 显存 | 11,943 MiB device-local |
### 两个必须记住的实测细节
1. **`D3D12_HEAP` / `D3D11_TEXTURE` 只能导入、不能导出**(`exportable=no`)。
这直接影响你那个 `rtx_vsr_host.dll`(只有 `NVSDK_NGX_D3D12_*` 接口):
它无法接收"OpenGL/Vulkan 分配、D3D12 导入"的纹理,**只能反过来由 D3D12 侧分配**再共享出来。
所以 VSR 超分和 DLSS 超分**不能复用同一条互操作管线**,这是两套东西。
2. **`dedicatedOnly=no`**:不强制专用分配,意味着我们可以在同一块 VkDeviceMemory 里规划输入/输出镜像,省一次分配和一次拷贝。
### 常用命令
```powershell
# 编原生桥接(自动处理 vulkan-1.lib)
.\native\tools\build_native.cmd
# 只重造 vulkan-1.lib
.\native\tools\make_vulkan_lib.cmd
# 跑 P0 探测(不需要启动游戏)
$env:JAVA_HOME='C:\Program Files\Java\jdk-21.0.10'
java -cp "build\classes\java\main" `
-Dwpywdlss.bridgePath=native\build\wpywdlss_bridge.dll `
tools\ProbeRunner.java
```
---
## 七、OpenGL 互操作实测结果(2026-09-16,已跑通)
**为什么这一个探测决定所有路线的生死**:OpenGL **只能导入、不能导出**内存和信号量。
所以分配方必须是 Vulkan/D3D12,GL 只负责导入对方给过来的 Win32 HANDLE。
`GL_EXT_external_objects*` 是**导入 Vulkan 对象的另一条路**,走 `OPAQUE_WIN32` 时**不需要**它 ——
把它当必需项会得出假阴性(我第一版就写错了,已修正)。
`nativeProbeOpenGL()` 创建一个**隐藏 WGL 上下文**实测:
| 检查 | 结果 |
|---|---|
| GL_RENDERER | `NVIDIA GeForce RTX 5070/PCIe/SSE2` |
| GL_VERSION | `4.6.0 NVIDIA 616.92` |
| GL 扩展总数 | 405 |
| **`GL_EXT_memory_object`** | ✅ |
| **`GL_EXT_memory_object_win32`** | ✅ |
| **`GL_EXT_semaphore`** | ✅ |
| **`GL_EXT_semaphore_win32`** | ✅ |
| `glCreateMemoryObjectsEXT` | ✅ |
| **`glImportMemoryWin32HandleEXT`** | ✅ |
| **`glTextureStorageMem2DEXT`** | ✅ |
| **`glImportSemaphoreWin32HandleEXT`** | ✅ |
| `glDeleteMemoryObjectsEXT` / `glDeleteSemaphoresEXT` | ✅ |
| `GL_EXT_external_objects*` | ❌(**不需要**,走 OPAQUE_WIN32 时用不到)|
| `glCreateSemaphoresEXT` | ❌(**不需要**,GL 只导入不导出)|
**判定:`VERDICT: the OpenGL transport is AVAILABLE on this machine.`**
两侧合起来的完整链路(能力层面已验证):
```
Vulkan/D3D12 分配镜像
│ vkGetMemoryWin32HandleKHR / D3D12 CreateSharedHandle
▼ (Win32 HANDLE)
OpenGL glCreateMemoryObjectsEXT → glImportMemoryWin32HandleEXT
→ glTextureStorageMem2DEXT (得到可渲染/可采样的 GL 纹理)
▲ (Win32 信号量 HANDLE)
glImportSemaphoreWin32HandleEXT
```
---
## 八、路线 C(ReShade 路线)落地清单
**先明确 C 在 OpenGL 下的天花板**(引自 DLSS5-Feeder 官方 Limitations):
> **DLAA contract, optional reduced work extent on D3D11** — render resolution still equals DLAA output
> resolution... **D3D12, Vulkan and OpenGL paths remain at 100%.** This is not jittered DLSS Super
> Resolution, and **a Quality/Balanced/Performance mode cannot be added**.
即:**OpenGL 下是纯 DLAA + DLSS 5 神经渲染观感,内部渲染分辨率不降 → 零帧率收益,拿不到超分,也没有插帧。**
另外官方承认 **"the UI is processed with the scene"** —— Minecraft 的物品栏/聊天/F3 会被一起处理而拖影。
### 需要的组件
| 组件 | 来源 | 状态 |
|---|---|---|
| ReShade 6.8+(**需 add-on 支持**),装成 `opengl32.dll`,API 选 **OpenGL** | reshade.me | 需你下载 |
| **Generic Depth add-on** 启用并**认到 Minecraft 的场景深度** | ReShade 自带 | ⚠️ 最大风险点,见下 |
| 神经消费者:**Deep Fried Chicken**(推荐)或 Krish 的 `renodx-dlss5.addon64` | 各自 Discord | 需你获取(Discord 门禁,我拿不到)|
| `nvngx_dlssnr.dll` | 已有 | ✅ GUI-DLSS5 包里 |
| `nvngx_dlss.dll`(放在游戏目录旁) | 已有 | ✅ Streamline SDK 里 |
| 运动矢量提供者:**LumeniteFX Kernel(=3,推荐)** | github.com/umar-afzaal/LumeniteFX | 需下载 |
| `dlss5-feed.addon64` + `DLSS5_Feed.fx` | DLSS5-Feeder release | 需下载 |
### Minecraft 特有的四个坑(我预判,待实测确认)
1. **深度缓冲**:ReShade 的 Generic Depth 必须正确识别 Minecraft 的场景深度。
Iris/光影会自建 FBO,Sodium 改了区块渲染 —— 识别很可能失败。
2. **GPU 选择**:这条路要求**渲染真的在 NVIDIA GPU 上**。你有 RTX 5070 + AMD 核显,
必须在 Windows「设置 ▸ 显示 ▸ 图形」里把 Java 强制到 NVIDIA,否则 DLSS 无从谈起。
3. **HUD 拖影**:官方明说 UI 与场景一起处理。要么忍受,要么自己加 UI 遮罩。
4. **驱动版本**:他们实测的坏组合是驱动 **616.56 / 616.64**(`nvngx_dlssnr.dll` 内部 fault)。
**你是 616.92,比他们测过的都新,未知。** 先跑他们的自检
`host64\dlss5-feed-host64.exe --test`(`300/300 evaluates succeeded` 才算 OK)。
---
## 九、许可与合规
- 本模组代码:MIT
- **NVIDIA 专有二进制一律不再分发**,仅由用户自备(同 Salt's Anti-Aliasing 等既有项目的做法)
- 参考但不复制任何现有模组代码;`Super Resolution`(GPL-3.0)与 `Salt's Anti-Aliasing`(MIT)
仅作为「这条路走得通」的存在性证据
- NGX `applicationId` 需向 NVIDIA 申请;在获批前 NVIDIA 目前为宽容放行(会打警告日志)