diff options
| author | 3gg <3gg@shellblade.net> | 2025-12-27 12:03:39 -0800 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-12-27 12:03:39 -0800 |
| commit | 5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch) | |
| tree | 8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli | |
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli')
| -rw-r--r-- | contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli b/contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli new file mode 100644 index 0000000..ba32e0c --- /dev/null +++ b/contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli | |||
| @@ -0,0 +1,236 @@ | |||
| 1 | #include "D3D12_Shader_Common.hlsli" | ||
| 2 | |||
| 3 | Texture2D texture0 : register(t0); | ||
| 4 | Texture2D texture1 : register(t1); | ||
| 5 | Texture2D texture2 : register(t2); | ||
| 6 | SamplerState sampler0 : register(s0); | ||
| 7 | |||
| 8 | struct PixelShaderInput | ||
| 9 | { | ||
| 10 | float4 pos : SV_POSITION; | ||
| 11 | float2 tex : TEXCOORD0; | ||
| 12 | float4 color : COLOR0; | ||
| 13 | }; | ||
| 14 | |||
| 15 | // These should mirror the definitions in SDL_render_d3d12.c | ||
| 16 | static const float TONEMAP_NONE = 0; | ||
| 17 | static const float TONEMAP_LINEAR = 1; | ||
| 18 | static const float TONEMAP_CHROME = 2; | ||
| 19 | |||
| 20 | static const float TEXTURETYPE_NONE = 0; | ||
| 21 | static const float TEXTURETYPE_RGB = 1; | ||
| 22 | static const float TEXTURETYPE_NV12 = 2; | ||
| 23 | static const float TEXTURETYPE_NV21 = 3; | ||
| 24 | static const float TEXTURETYPE_YUV = 4; | ||
| 25 | |||
| 26 | static const float INPUTTYPE_UNSPECIFIED = 0; | ||
| 27 | static const float INPUTTYPE_SRGB = 1; | ||
| 28 | static const float INPUTTYPE_SCRGB = 2; | ||
| 29 | static const float INPUTTYPE_HDR10 = 3; | ||
| 30 | |||
| 31 | cbuffer Constants : register(b1) | ||
| 32 | { | ||
| 33 | float scRGB_output; | ||
| 34 | float texture_type; | ||
| 35 | float input_type; | ||
| 36 | float color_scale; | ||
| 37 | |||
| 38 | float tonemap_method; | ||
| 39 | float tonemap_factor1; | ||
| 40 | float tonemap_factor2; | ||
| 41 | float sdr_white_point; | ||
| 42 | |||
| 43 | float4 Yoffset; | ||
| 44 | float4 Rcoeff; | ||
| 45 | float4 Gcoeff; | ||
| 46 | float4 Bcoeff; | ||
| 47 | }; | ||
| 48 | |||
| 49 | static const float3x3 mat709to2020 = { | ||
| 50 | { 0.627404, 0.329283, 0.043313 }, | ||
| 51 | { 0.069097, 0.919541, 0.011362 }, | ||
| 52 | { 0.016391, 0.088013, 0.895595 } | ||
| 53 | }; | ||
| 54 | |||
| 55 | static const float3x3 mat2020to709 = { | ||
| 56 | { 1.660496, -0.587656, -0.072840 }, | ||
| 57 | { -0.124547, 1.132895, -0.008348 }, | ||
| 58 | { -0.018154, -0.100597, 1.118751 } | ||
| 59 | }; | ||
| 60 | |||
| 61 | float sRGBtoLinear(float v) | ||
| 62 | { | ||
| 63 | if (v <= 0.04045) { | ||
| 64 | v = (v / 12.92); | ||
| 65 | } else { | ||
| 66 | v = pow(abs(v + 0.055) / 1.055, 2.4); | ||
| 67 | } | ||
| 68 | return v; | ||
| 69 | } | ||
| 70 | |||
| 71 | float sRGBfromLinear(float v) | ||
| 72 | { | ||
| 73 | if (v <= 0.0031308) { | ||
| 74 | v = (v * 12.92); | ||
| 75 | } else { | ||
| 76 | v = (pow(abs(v), 1.0 / 2.4) * 1.055 - 0.055); | ||
| 77 | } | ||
| 78 | return v; | ||
| 79 | } | ||
| 80 | |||
| 81 | float3 PQtoLinear(float3 v) | ||
| 82 | { | ||
| 83 | const float c1 = 0.8359375; | ||
| 84 | const float c2 = 18.8515625; | ||
| 85 | const float c3 = 18.6875; | ||
| 86 | const float oo_m1 = 1.0 / 0.1593017578125; | ||
| 87 | const float oo_m2 = 1.0 / 78.84375; | ||
| 88 | |||
| 89 | float3 num = max(pow(abs(v), oo_m2) - c1, 0.0); | ||
| 90 | float3 den = c2 - c3 * pow(abs(v), oo_m2); | ||
| 91 | return (10000.0 * pow(abs(num / den), oo_m1) / sdr_white_point); | ||
| 92 | } | ||
| 93 | |||
| 94 | float3 ApplyTonemap(float3 v) | ||
| 95 | { | ||
| 96 | if (tonemap_method == TONEMAP_LINEAR) { | ||
| 97 | v *= tonemap_factor1; | ||
| 98 | } else if (tonemap_method == TONEMAP_CHROME) { | ||
| 99 | if (input_type == INPUTTYPE_SCRGB) { | ||
| 100 | // Convert to BT.2020 colorspace for tone mapping | ||
| 101 | v = mul(mat709to2020, v); | ||
| 102 | } | ||
| 103 | |||
| 104 | float vmax = max(v.r, max(v.g, v.b)); | ||
| 105 | if (vmax > 0.0) { | ||
| 106 | float scale = (1.0 + tonemap_factor1 * vmax) / (1.0 + tonemap_factor2 * vmax); | ||
| 107 | v *= scale; | ||
| 108 | } | ||
| 109 | |||
| 110 | if (input_type == INPUTTYPE_SCRGB) { | ||
| 111 | // Convert to BT.709 colorspace after tone mapping | ||
| 112 | v = mul(mat2020to709, v); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | return v; | ||
| 116 | } | ||
| 117 | |||
| 118 | float4 GetInputColor(PixelShaderInput input) | ||
| 119 | { | ||
| 120 | float4 rgba; | ||
| 121 | |||
| 122 | if (texture_type == TEXTURETYPE_NONE) { | ||
| 123 | rgba = 1.0; | ||
| 124 | } else if (texture_type == TEXTURETYPE_RGB) { | ||
| 125 | rgba = texture0.Sample(sampler0, input.tex); | ||
| 126 | } else if (texture_type == TEXTURETYPE_NV12) { | ||
| 127 | float3 yuv; | ||
| 128 | yuv.x = texture0.Sample(sampler0, input.tex).r; | ||
| 129 | yuv.yz = texture1.Sample(sampler0, input.tex).rg; | ||
| 130 | |||
| 131 | yuv += Yoffset.xyz; | ||
| 132 | rgba.r = dot(yuv, Rcoeff.xyz); | ||
| 133 | rgba.g = dot(yuv, Gcoeff.xyz); | ||
| 134 | rgba.b = dot(yuv, Bcoeff.xyz); | ||
| 135 | rgba.a = 1.0; | ||
| 136 | } else if (texture_type == TEXTURETYPE_NV21) { | ||
| 137 | float3 yuv; | ||
| 138 | yuv.x = texture0.Sample(sampler0, input.tex).r; | ||
| 139 | yuv.yz = texture1.Sample(sampler0, input.tex).gr; | ||
| 140 | |||
| 141 | yuv += Yoffset.xyz; | ||
| 142 | rgba.r = dot(yuv, Rcoeff.xyz); | ||
| 143 | rgba.g = dot(yuv, Gcoeff.xyz); | ||
| 144 | rgba.b = dot(yuv, Bcoeff.xyz); | ||
| 145 | rgba.a = 1.0; | ||
| 146 | } else if (texture_type == TEXTURETYPE_YUV) { | ||
| 147 | float3 yuv; | ||
| 148 | yuv.x = texture0.Sample(sampler0, input.tex).r; | ||
| 149 | yuv.y = texture1.Sample(sampler0, input.tex).r; | ||
| 150 | yuv.z = texture2.Sample(sampler0, input.tex).r; | ||
| 151 | |||
| 152 | yuv += Yoffset.xyz; | ||
| 153 | rgba.r = dot(yuv, Rcoeff.xyz); | ||
| 154 | rgba.g = dot(yuv, Gcoeff.xyz); | ||
| 155 | rgba.b = dot(yuv, Bcoeff.xyz); | ||
| 156 | rgba.a = 1.0; | ||
| 157 | } else { | ||
| 158 | // Error! | ||
| 159 | rgba.r = 1.0; | ||
| 160 | rgba.g = 0.0; | ||
| 161 | rgba.b = 0.0; | ||
| 162 | rgba.a = 1.0; | ||
| 163 | } | ||
| 164 | return rgba; | ||
| 165 | } | ||
| 166 | |||
| 167 | float4 GetOutputColor(float4 rgba) | ||
| 168 | { | ||
| 169 | float4 output; | ||
| 170 | |||
| 171 | output.rgb = rgba.rgb * color_scale; | ||
| 172 | output.a = rgba.a; | ||
| 173 | |||
| 174 | return output; | ||
| 175 | } | ||
| 176 | |||
| 177 | float3 GetOutputColorFromSRGB(float3 rgb) | ||
| 178 | { | ||
| 179 | float3 output; | ||
| 180 | |||
| 181 | if (scRGB_output) { | ||
| 182 | rgb.r = sRGBtoLinear(rgb.r); | ||
| 183 | rgb.g = sRGBtoLinear(rgb.g); | ||
| 184 | rgb.b = sRGBtoLinear(rgb.b); | ||
| 185 | } | ||
| 186 | |||
| 187 | output.rgb = rgb * color_scale; | ||
| 188 | |||
| 189 | return output; | ||
| 190 | } | ||
| 191 | |||
| 192 | float3 GetOutputColorFromLinear(float3 rgb) | ||
| 193 | { | ||
| 194 | float3 output; | ||
| 195 | |||
| 196 | output.rgb = rgb * color_scale; | ||
| 197 | |||
| 198 | if (!scRGB_output) { | ||
| 199 | output.r = sRGBfromLinear(output.r); | ||
| 200 | output.g = sRGBfromLinear(output.g); | ||
| 201 | output.b = sRGBfromLinear(output.b); | ||
| 202 | output.rgb = saturate(output.rgb); | ||
| 203 | } | ||
| 204 | |||
| 205 | return output; | ||
| 206 | } | ||
| 207 | |||
| 208 | float4 AdvancedPixelShader(PixelShaderInput input) | ||
| 209 | { | ||
| 210 | float4 rgba = GetInputColor(input); | ||
| 211 | float4 output; | ||
| 212 | |||
| 213 | if (input_type == INPUTTYPE_HDR10) { | ||
| 214 | rgba.rgb = PQtoLinear(rgba.rgb); | ||
| 215 | } | ||
| 216 | |||
| 217 | if (tonemap_method != TONEMAP_NONE) { | ||
| 218 | rgba.rgb = ApplyTonemap(rgba.rgb); | ||
| 219 | } | ||
| 220 | |||
| 221 | if (input_type == INPUTTYPE_SRGB) { | ||
| 222 | output.rgb = GetOutputColorFromSRGB(rgba.rgb); | ||
| 223 | output.a = rgba.a; | ||
| 224 | } else if (input_type == INPUTTYPE_SCRGB) { | ||
| 225 | output.rgb = GetOutputColorFromLinear(rgba.rgb); | ||
| 226 | output.a = rgba.a; | ||
| 227 | } else if (input_type == INPUTTYPE_HDR10) { | ||
| 228 | rgba.rgb = mul(mat2020to709, rgba.rgb); | ||
| 229 | output.rgb = GetOutputColorFromLinear(rgba.rgb); | ||
| 230 | output.a = rgba.a; | ||
| 231 | } else { | ||
| 232 | output = GetOutputColor(rgba); | ||
| 233 | } | ||
| 234 | |||
| 235 | return output * input.color; | ||
| 236 | } | ||
