Skip to content

feat(oncehuman): add HDR addon for Once Human (NeoX, DX11 + DX12)#578

Open
NatsumeLS wants to merge 17 commits into
clshortfuse:mainfrom
NatsumeLS:feat/oncehuman-hdr
Open

feat(oncehuman): add HDR addon for Once Human (NeoX, DX11 + DX12)#578
NatsumeLS wants to merge 17 commits into
clshortfuse:mainfrom
NatsumeLS:feat/oncehuman-hdr

Conversation

@NatsumeLS

@NatsumeLS NatsumeLS commented Jun 6, 2026

Copy link
Copy Markdown

Overview

A RenoDX addon that converts Once Human (NetEase NeoX engine, Steam AppID 2139460) from SDR to HDR on both DirectX 11 and DirectX 12.

What it does

  • Swapchain + buffer upgrade — the r8g8b8a8_unorm swapchain → HDR10 (r10g10b10a2_unorm) and the game's r8 intermediate render targets → r16g16b16a16_float (via view cloning) so HDR values survive to output.
  • Tonemap injection — replaces the game's baked SDR tonemap/LUT with renodx::tonemap (RenoDRT): HDR is re-derived from the pre-LUT scene signal and the game's grade is re-applied non-destructively via ToneMapPass, then RenderIntermediatePass so the scene tracks Game Brightness (diffuse) independently of UI Brightness (graphics) through the swapchain proxy.
  • Effect sliders — Vignette / Chromatic Aberration / Bloom strengths are multiplied in at each effect's source in the tonemap shaders (0% = off, 100% = vanilla).

Dual-API design

DX11 DX12
Game shaders sm5.0 (DXBC, FXC) sm6 (DXIL, DXC)
Proxy .ps_5_x/.vs_5_x → sm5.0 DXBC same source → sm5.1 DXBC
Injection cbuffer register(b13) register(b13, space50)

Each shader hash matches only on its own API (the sm5 and sm6 bytecode of "the same" pass hash differently), so both sets are registered in one custom_shaders list and selected automatically by device API.

Shaders injected

DX11 (sm5) DX12 (sm6) Role
0x97189CC3, 0x9CBB8C92 0x80419ACE, 0x2FC428AF, 0xCCAD619A tonemap + color grade — gameplay
0x0FAF8922, 0x0C0D9DB1 0xEC5A7D52, 0x4506D824 tonemap + color grade — menu / inventory
0x6AEF81FE 0x51731F8B post sharpen / AA → swapchain; saturate() ceiling removed so HDR survives

Key fixes that made DX12 work

  • No d3d12 proxySwapchainProxyPass(no clone) every frame. Registered a d3d12 proxy; the proxy source is dual-target .ps_5_x/.vs_5_x, compiling to sm5.1 DXBC which D3D12 accepts for our standalone proxy pipeline.
  • CopyBufferToTexture(mismatched) crash — the r8g8b8a8_unorm → fp16 upgrade upgraded in place, so the r8 staging buffer no longer matched the fp16 texture. Fixed with use_resource_view_cloning (the original stays r8; RT writes / SRV reads go through an fp16 clone) — mirrors the existing typeless upgrade target.

Reviewer notes

  • sm6 channels are plain RGB — no .yzx swizzle. The DX11 (B,R,G) rotation was a 3DMigoto decompiler artifact; the DXC SSA output shows true RGB order.
  • The sm6 tonemappers are the verbatim DXC decompile with two edits only: the effect-strength sliders at each effect source, and the display-gamma tail replaced with RenderIntermediatePass(ToneMapPass(untonemapped, graded)). Vanilla output is kept as a reference comment.
  • Per-variant quirks: gameplay 0x2FC428AF/0xCCAD619A and menu 0xEC5A7D52/0x4506D824 have varying chromatic aberration and bloom implementation specifics.
  • shared.h binds the injection cbuffer at b13,space50 for sm5.1+/sm6 and b13 for sm5.0, switched on __SHADER_TARGET_MAJOR/MINOR.
  • Peak Brightness reset snaps to the display's detected peak (OnInitSwapchain + GetPeakNits).
  • Exposure default is internal 2.0 (Once Human's LUT sits dark vs RenoDRT neutral), shown as 1.0 to the user via parse.

Verified

Working in gameplay, menu/inventory, and first-person photo mode on both DX11 and DX12.

NatsumeLS and others added 3 commits June 6, 2026 02:19
RenoDX HDR addon for Once Human (NetEase NeoX engine, Steam AppID
2139460). DirectX 11.

- Upgrades the r8g8b8a8_unorm swapchain and the game's r8 intermediate
  render targets to r16g16b16a16_float so HDR values survive the pipeline.
- Replaces the game's baked SDR tonemap/LUT output with renodx::tonemap
  (RenoDRT), re-deriving HDR from the pre-LUT scene and re-applying the
  game's grade non-destructively, then RenderIntermediatePass so the scene
  follows Game Brightness (diffuse) independently of UI Brightness.

Injected passes (identified by live render-target tracing):
- 0x94D5C191 - tonemap + color grade (gameplay / photo mode)
- 0x24C65B31 - tonemap + color grade (menu / inventory variant)
- 0x6AEF81FE - post sharpen/AA; saturate() clamp removed so HDR survives

Verified in gameplay, inventory, and first-person photo mode.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tion

Add an "Effects" section exposing Vignette, Chromatic Aberration, and
Bloom strength, wired as multipliers into both tonemappers (0x94D5C191
and 0x24C65B31). Defaults are 100% = vanilla, so the look is unchanged
until adjusted (Vignette/CA 0-100%, Bloom 0-200%).

Also replace the About section with the endfield-style credits + build
timestamp (__DATE__/__TIME__) and drop the now-unused date.hpp include.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The addon now serves DirectX 11 (sm5) and DirectX 12 (sm6) from one binary.
The earlier "NeoX D3D12 device-hangs on injection" conclusion was a misdiagnosis:
live diagnosis showed injection succeeds (NeoX root signatures are small, so the
b13 range fits well under the 64-dword cap) and the real blockers were swapchain-side.

- Register a d3d12 swapchain proxy: proxy shaders are now dual-target
  .ps_5_x/.vs_5_x (sm5.0 DXBC for d3d11, sm5.1 DXBC for d3d12).
- Fix the CopyBufferToTexture crash: the r8g8b8a8_unorm -> fp16 upgrade now uses
  view cloning, so the original r8 resource is kept and buffer uploads still match.
- Add sm6 (DXIL) tonemap + sharpen shaders: tonemap 0x749C84C9 / 0xB01E4700
  (gameplay), 0xCFEC26F0 / 0xCCD56442 (menu/inventory), sharpen 0x51731F8B.
  Each hash matches only on its own API.
- Inject the effect-strength sliders (vignette / CA / bloom) at each effect's
  source in the sm6 tonemappers, matching DX11.
- shared.h: bind the injection cbuffer at b13,space50 for sm5.1+/sm6, b13 for sm5.0.
- About: build timestamp via renodx::utils::date::ISO_DATE_TIME.

sm6 channels are plain RGB (no .yzx swizzle; the DX11 (B,R,G) rotation was a
3DMigoto decompiler artifact). Verified working in gameplay and menu/inventory
on both APIs with live sliders.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new RenoDX game addon for Once Human to enable HDR output on both DX11 and DX12 by upgrading the swapchain/intermediate targets and injecting replacement tonemap/sharpen shaders that preserve HDR ranges through to final presentation.

Changes:

  • Introduces a Once Human addon (addon.cpp) that configures shader replacement hooks, swapchain proxy shaders, resource upgrades, and an in-game settings UI (tone mapping + effect strength sliders).
  • Adds DX11 (sm5) and DX12 (sm6) tonemap shader replacements that feed renodx::draw::ToneMapPass + RenderIntermediatePass, plus sharpen shaders with the HDR-clamping removed.
  • Adds shared injection bindings (shared.h), swapchain proxy shaders, and game metadata (metadata.json).

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/games/oncehuman/addon.cpp Registers shader replacements, swapchain upgrades/proxy shaders, and exposes HDR/effect controls via settings.
src/games/oncehuman/shared.h Defines the injection constant buffer + RenoDX macro bindings for both DX11 and DX12 targets.
src/games/oncehuman/metadata.json Adds Once Human addon metadata (id/title/status/Steam AppID).
src/games/oncehuman/swap_chain_proxy_vertex_shader.vs_5_x.hlsl Fullscreen triangle vertex shader for the swapchain proxy pass.
src/games/oncehuman/swap_chain_proxy_pixel_shader.ps_5_x.hlsl Swapchain proxy pixel shader calling renodx::draw::SwapChainPass.
src/games/oncehuman/tonemap_0x94D5C191.ps_5_0.hlsl DX11 gameplay tonemap+grade replacement using RenoDX tonemapping.
src/games/oncehuman/tonemap_0x24C65B31.ps_5_0.hlsl DX11 menu/inventory tonemap+grade variant using RenoDX tonemapping.
src/games/oncehuman/tonemap_0x749C84C9.ps_6_0.hlsl DX12 gameplay tonemap+grade replacement using RenoDX tonemapping.
src/games/oncehuman/tonemap_0xB01E4700.ps_6_0.hlsl DX12 gameplay tonemap+grade variant using RenoDX tonemapping.
src/games/oncehuman/tonemap_0xCFEC26F0.ps_6_0.hlsl DX12 menu/inventory tonemap+grade replacement using RenoDX tonemapping.
src/games/oncehuman/tonemap_0xCCD56442.ps_6_0.hlsl DX12 menu/inventory tonemap+grade variant using RenoDX tonemapping.
src/games/oncehuman/sharpen_0x6AEF81FE.ps_5_0.hlsl DX11 sharpen/AA resolve updated to avoid clamping HDR highlights.
src/games/oncehuman/sharpen_0x51731F8B.ps_6_0.hlsl DX12 sharpen/AA resolve updated to avoid clamping HDR highlights.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/games/oncehuman/addon.cpp Outdated
Comment thread src/games/oncehuman/addon.cpp Outdated
Comment thread src/games/oncehuman/addon.cpp Outdated
Comment thread src/games/oncehuman/addon.cpp Outdated
- Replace the fragile PEAK_BRIGHTNESS_INDEX positional lookup with a captured
  peak_brightness_setting* pointer (per maintainer; cf. wobblylife mod).
- Replace the 6-option "Encoding" picker with a simple "Output Mode" {SDR, HDR}
  toggle (per maintainer; cf. Starfield). A SyncSwapChainOutput() helper keeps the
  live encoding fields + SetUseHDR10/use_resize_buffer in sync on change; the
  tooltip notes that switching the swapchain container itself needs a restart.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comment thread src/games/oncehuman/addon.cpp Outdated
Comment thread src/games/oncehuman/addon.cpp Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Comment thread src/games/oncehuman/addon.cpp
Comment thread src/games/oncehuman/addon.cpp Outdated
Comment thread src/games/oncehuman/addon.cpp
Comment thread src/games/oncehuman/addon.cpp
Comment thread src/games/oncehuman/addon.cpp

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Comment thread src/games/oncehuman/addon.cpp Outdated
Comment thread src/games/oncehuman/shared.h Outdated
NatsumeLS and others added 3 commits July 3, 2026 06:37
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… to fix inventory freezing"

This reverts commit 1182124.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants