Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 36 additions & 29 deletions Shaders/Borderlands GOTY Enhanced/BL_Video_0x0E97A4A0.ps_5_0.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
// paper white.
// Kept conservative (videos are low-bitrate, highlight compression artifacts blow up if pushed hard).

#include "../Includes/Common.hlsl"
// clang-format off
#include "Includes/Common.hlsl" // game-local: pulls GameCBuffers (VideoAutoHDR* fields) BEFORE shared Settings
// clang-format on

// Light AutoHDR on videos (0 = off → flat SDR at paper white). Peak kept low on purpose.
#ifndef ENABLE_VIDEO_AUTO_HDR
Expand All @@ -19,10 +21,10 @@

cbuffer _Globals : register(b0)
{
float4 cmatrix[4] : packoffset(c0);
float4 alpha_mult : packoffset(c4);
float4 hdr : packoffset(c5);
float4 ctcp : packoffset(c6);
float4 cmatrix[4] : packoffset(c0);
float4 alpha_mult : packoffset(c4);
float4 hdr : packoffset(c5);
float4 ctcp : packoffset(c6);
}

SamplerState YTexSampler_s : register(s0);
Expand All @@ -31,35 +33,40 @@ Texture2D<float4> YTex : register(t0);
Texture2D<float4> CrCbTex : register(t1);

void main(
float2 v0 : TEXCOORD0,
float4 v1 : SV_Position0,
out float4 o0 : SV_Target0)
float2 v0 : TEXCOORD0,
float4 v1 : SV_Position0,
out float4 o0 : SV_Target0)
{
float4 r0, r1;
float4 r0, r1;

r0.x = YTex.Sample(YTexSampler_s, v0.xy).x;
r0.yz = CrCbTex.Sample(CrCbTexSampler_s, v0.xy).xy;
r1.xyz = cmatrix[0].xyz * r0.yyy;
r0.xyw = r0.xxx * cmatrix[3].xyz + r1.xyz;
r0.xyz = r0.zzz * cmatrix[1].xyz + r0.xyw;
r0.xyz = cmatrix[2].xyz + r0.xyz;
r0.w = 1;
o0.xyzw = alpha_mult.xyzw * r0.xyzw;
o0.rgb = saturate(o0.rgb); // restore the vanilla 8-bit backbuffer clamp (kills YUV overshoot + negatives)
r0.x = YTex.Sample(YTexSampler_s, v0.xy).x;
r0.yz = CrCbTex.Sample(CrCbTexSampler_s, v0.xy).xy;
r1.xyz = cmatrix[0].xyz * r0.yyy;
r0.xyw = r0.xxx * cmatrix[3].xyz + r1.xyz;
r0.xyz = r0.zzz * cmatrix[1].xyz + r0.xyw;
r0.xyz = cmatrix[2].xyz + r0.xyz;
r0.w = 1;
o0.xyzw = alpha_mult.xyzw * r0.xyzw;
o0.rgb = saturate(o0.rgb); // restore the vanilla 8-bit backbuffer clamp (kills YUV overshoot + negatives)

// Work in linear: AutoHDR (optional) and the paper-white pre-scale both belong in linear space. The
// composition decodes gamma then multiplies by UIPaperWhite (linear), so the pre-scale must pre-compensate
// that linear multiply BEFORE re-encoding — applying it in gamma space diverges for GamePaperWhite!=UIPaperWhite.
float3 lin = gamma_to_linear(o0.rgb);
// Work in linear: AutoHDR (optional) and the paper-white pre-scale both belong in linear space. The
// composition decodes gamma then multiplies by UIPaperWhite (linear), so the pre-scale must pre-compensate
// that linear multiply BEFORE re-encoding — applying it in gamma space diverges for GamePaperWhite!=UIPaperWhite.
float3 lin = gamma_to_linear(o0.rgb);
#if ENABLE_VIDEO_AUTO_HDR
// Video is gamma-encoded SDR; expand highlights mildly for HDR.
lin = PumboAutoHDR(lin, VIDEO_AUTO_HDR_PEAK_NITS, LumaSettings.GamePaperWhiteNits);
// Video is gamma-encoded SDR; expand highlights mildly for HDR. Runtime-gated (ImGui "Video AutoHDR"):
// boost 0 = peak at paper white -> PumboAutoHDR no-ops (off); 1 = full VIDEO_AUTO_HDR_PEAK_NITS.
if (LumaSettings.GameSettings.VideoAutoHDREnable > 0.5)
{
const float peakNits = lerp(sRGB_WhiteLevelNits, VIDEO_AUTO_HDR_PEAK_NITS, saturate(LumaSettings.GameSettings.VideoAutoHDRBoost));
lin = PumboAutoHDR(lin, peakNits, LumaSettings.GamePaperWhiteNits);
}
#endif
#if UI_DRAW_TYPE >= 2
// Match the tonemap pass (linear pre-scale, see Luma_BL_Tonemap.hlsl): land full-screen movies at the same
// brightness as in-game after the composition's UIPaperWhite rescale, when UIPaperWhite != GamePaperWhite.
lin *= LumaSettings.GamePaperWhiteNits / max(LumaSettings.UIPaperWhiteNits, 1.0);
// Match the tonemap pass (linear pre-scale, see Luma_BL_Tonemap.hlsl): land full-screen movies at the same
// brightness as in-game after the composition's UIPaperWhite rescale, when UIPaperWhite != GamePaperWhite.
lin *= LumaSettings.GamePaperWhiteNits / max(LumaSettings.UIPaperWhiteNits, 1.0);
#endif
o0.rgb = linear_to_gamma(lin); // re-encode for the gamma post buffer
return;
o0.rgb = linear_to_gamma(lin); // re-encode for the gamma post buffer
return;
}
38 changes: 20 additions & 18 deletions Shaders/Borderlands GOTY Enhanced/Includes/GameCBuffers.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,26 @@
// Mirrors c++ name spaces.
namespace CB
{
// User-facing grade controls, drawn in DrawImGuiSettings (main.cpp) and read in Luma_BL_Tonemap.hlsl.
// All apply only on the HDR tonemap path. SMAA metrics are passed via a dedicated CB at b1, not here.
struct LumaGameSettings
{
float Exposure; // exposure multiplier (1 = vanilla). Applied scene-referred, pre-grade.
float Saturation; // 1 = vanilla. Oklab saturation multiplier on the final HDR color.
float HighlightDechroma; // 0 = off (default; keep color, only mandatory gamut desat applies); higher = bright sources fade to white sooner. Optional perceptual taste.
float BloomIntensity; // 1 = vanilla. Scales the game's bloom contribution in the scene mix.
float Contrast; // 1 = vanilla. Slope contrast around 18% mid-gray on the final HDR color.
float Dithering; // 0/1 toggle. Animated triangular dither at output to break gradient banding.
float FlareOut; // 1 = vanilla. Scales the additive lens-flare/glare overlay (pass 0x010371F2).
};
// User-facing grade controls, drawn in DrawImGuiSettings (main.cpp) and read in Luma_BL_Tonemap.hlsl.
// All apply only on the HDR tonemap path. SMAA metrics are passed via a dedicated CB at b1, not here.
struct LumaGameSettings
{
float Exposure; // exposure multiplier (1 = vanilla). Applied scene-referred, pre-grade.
float Saturation; // 1 = vanilla. Oklab saturation multiplier on the final HDR color.
float HighlightDechroma; // 0 = off (default; keep color, only mandatory gamut desat applies); higher = bright sources fade to white sooner. Optional perceptual taste.
float BloomIntensity; // 1 = vanilla. Scales the game's bloom contribution in the scene mix.
float Contrast; // 1 = vanilla. Slope contrast around 18% mid-gray on the final HDR color.
float Dithering; // 0/1 toggle. Animated triangular dither at output to break gradient banding.
float FlareOut; // 1 = vanilla. Scales the additive lens-flare/glare overlay (pass 0x010371F2).
float VideoAutoHDREnable; // 0/1. Light AutoHDR on Bink movies (HDR only; pass 0x0E97A4A0). 0 = flat SDR at paper white.
float VideoAutoHDRBoost; // 0..1 highlight-expansion strength. 0 = off (peak == paper white); 1 = full VIDEO_AUTO_HDR_PEAK_NITS.
};

// Game specific cbuffer (instance/pass) data.
struct LumaGameData
{
float Dummy; // hlsl doesn't support empty structs
};
}
// Game specific cbuffer (instance/pass) data.
struct LumaGameData
{
float Dummy; // hlsl doesn't support empty structs
};
} // namespace CB

#endif // LUMA_GAME_CB_STRUCTS
Loading
Loading