forked from doodlum/skyrim-community-shaders
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ISHDR.hlsl
145 lines (119 loc) · 4.16 KB
/
ISHDR.hlsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "Common/Color.hlsli"
#include "Common/DICETonemapper.hlsli"
#include "Common/DummyVSTexCoord.hlsl"
#include "Common/FrameBuffer.hlsli"
typedef VS_OUTPUT PS_INPUT;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
};
#if defined(PSHADER)
SamplerState ImageSampler : register(s0);
# if defined(DOWNSAMPLE)
SamplerState AdaptSampler : register(s1);
# elif defined(BLEND)
SamplerState BlendSampler : register(s1);
# endif
SamplerState AvgSampler : register(s2);
Texture2D<float4> ImageTex : register(t0);
# if defined(DOWNSAMPLE)
Texture2D<float4> AdaptTex : register(t1);
# elif defined(BLEND)
Texture2D<float4> BlendTex : register(t1);
# endif
Texture2D<float4> AvgTex : register(t2);
cbuffer PerGeometry : register(b2)
{
float4 Flags : packoffset(c0);
float4 TimingData : packoffset(c1);
float4 Param : packoffset(c2);
float4 Cinematic : packoffset(c3);
float4 Tint : packoffset(c4);
float4 Fade : packoffset(c5);
float4 BlurScale : packoffset(c6);
float4 BlurOffsets[16] : packoffset(c7);
};
float GetTonemapFactorReinhard(float luminance)
{
return (luminance * (luminance * Param.y + 1)) / (luminance + 1);
}
float GetTonemapFactorHejlBurgessDawson(float luminance)
{
float tmp = max(0, luminance - 0.004);
return Param.y *
pow(((tmp * 6.2 + 0.5) * tmp) / (tmp * (tmp * 6.2 + 1.7) + 0.06), Color::GammaCorrectionValue);
}
PS_OUTPUT main(PS_INPUT input)
{
PS_OUTPUT psout;
# if defined(DOWNSAMPLE)
float3 downsampledColor = 0;
for (int sampleIndex = 0; sampleIndex < DOWNSAMPLE; ++sampleIndex) {
float2 texCoord = BlurOffsets[sampleIndex].xy * BlurScale.xy + input.TexCoord;
[branch] if (Flags.x > 0.5)
{
texCoord = FrameBuffer::GetDynamicResolutionAdjustedScreenPosition(texCoord);
}
float3 imageColor = ImageTex.Sample(ImageSampler, texCoord).xyz;
# if defined(RGB2LUM)
imageColor = Color::RGBToLuminance(imageColor);
# elif (defined(LUM) || defined(LUMCLAMP)) && !defined(DOWNADAPT)
imageColor = imageColor.x;
# endif
downsampledColor += imageColor * BlurOffsets[sampleIndex].z;
}
# if defined(DOWNADAPT)
float2 adaptValue = AdaptTex.Sample(AdaptSampler, input.TexCoord).xy;
if (isnan(downsampledColor.x) || isnan(downsampledColor.y) || isnan(downsampledColor.z)) {
downsampledColor.xy = adaptValue;
} else {
float2 adaptDelta = downsampledColor.xy - adaptValue;
downsampledColor.xy =
sign(adaptDelta) * clamp(abs(Param.wz * adaptDelta), 0.00390625, abs(adaptDelta)) +
adaptValue;
}
downsampledColor = max(asfloat(0x00800000), downsampledColor); // Black screen fix
# endif
psout.Color = float4(downsampledColor, BlurScale.z);
# elif defined(BLEND)
float2 uv = FrameBuffer::GetDynamicResolutionAdjustedScreenPosition(input.TexCoord);
float3 inputColor = BlendTex.Sample(BlendSampler, uv).xyz;
float3 bloomColor = 0;
if (Flags.x > 0.5) {
bloomColor = ImageTex.Sample(ImageSampler, uv).xyz;
} else {
bloomColor = ImageTex.Sample(ImageSampler, input.TexCoord.xy).xyz;
}
float2 avgValue = AvgTex.Sample(AvgSampler, input.TexCoord.xy).xy;
// Vanilla tonemapping and post-processing
float3 gameSdrColor = 0.0;
float3 ppColor = 0.0;
{
float luminance = max(1e-5, Color::RGBToLuminance(inputColor));
float exposureAdjustedLuminance = (avgValue.y / avgValue.x) * luminance;
float blendFactor;
if (Param.z > 0.5) {
blendFactor = GetTonemapFactorHejlBurgessDawson(exposureAdjustedLuminance);
} else {
blendFactor = GetTonemapFactorReinhard(exposureAdjustedLuminance);
}
float3 blendedColor = inputColor * (blendFactor / luminance);
blendedColor += saturate(Param.x - blendFactor) * bloomColor;
gameSdrColor = blendedColor;
float blendedLuminance = Color::RGBToLuminance(blendedColor);
float3 linearColor = Cinematic.w * lerp(lerp(blendedLuminance, float4(blendedColor, 1), Cinematic.x), blendedLuminance * Tint, Tint.w).xyz;
linearColor = lerp(avgValue.x, linearColor, Cinematic.z);
gameSdrColor = max(0, gameSdrColor);
ppColor = max(0, linearColor);
}
// HDR tonemapping
float3 srgbColor = RangeCompress(ppColor, 0.5);
# if defined(FADE)
srgbColor = lerp(srgbColor, Fade.xyz, Fade.w);
# endif
srgbColor = FrameBuffer::ToSRGBColor(srgbColor);
psout.Color = float4(srgbColor, 1.0);
# endif
return psout;
}
#endif