Skip to content

Commit c9cbe93

Browse files
committed
Always quantize HDR textures alphas (fixes Jak games shadows)
1 parent 9cd54fd commit c9cbe93

File tree

1 file changed

+51
-28
lines changed
  • bin/resources/shaders/dx11

1 file changed

+51
-28
lines changed

bin/resources/shaders/dx11/tfx.fx

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#undef PS_HDR
9090
#define PS_HDR 1
9191
#endif
92+
#define HDR_ALPHA 1
9293

9394
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
9495
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
@@ -275,12 +276,28 @@ float4 sampleLUTWithExtrapolation(Texture2D<float4> lut, float unclampedU)
275276
return clampedSample;
276277
}
277278

279+
float4 DecodeTex(float4 C)
280+
{
281+
#if PS_HDR
282+
C.a = round(C.a * 255.0f) / 255.0f;
283+
#endif
284+
return C;
285+
}
286+
287+
float4 EncodeTex(float4 C)
288+
{
289+
#if PS_HDR
290+
C.a = round(C.a * 255.0f) / 255.0f;
291+
#endif
292+
return C;
293+
}
294+
278295
float4 sample_c(float2 uv, float uv_w)
279296
{
280297
#if PS_TEX_IS_FB == 1
281-
return RtTexture.Load(int3(int2(uv * WH.zw), 0));
298+
return DecodeTex(RtTexture.Load(int3(int2(uv * WH.zw), 0)));
282299
#elif PS_REGION_RECT == 1
283-
return Texture.Load(int3(int2(uv), 0));
300+
return DecodeTex(Texture.Load(int3(int2(uv), 0)));
284301
#else
285302
if (PS_POINT_SAMPLER)
286303
{
@@ -310,7 +327,7 @@ float4 sample_c(float2 uv, float uv_w)
310327
#endif
311328

312329
#if PS_AUTOMATIC_LOD == 1
313-
return Texture.Sample(TextureSampler, uv);
330+
return DecodeTex(Texture.Sample(TextureSampler, uv));
314331
#elif PS_MANUAL_LOD == 1
315332
// FIXME add LOD: K - ( LOG2(Q) * (1 << L))
316333
float K = LODParams.x;
@@ -323,9 +340,9 @@ float4 sample_c(float2 uv, float uv_w)
323340
//float lod = max(min(gs_lod, max_lod) - bias, 0.0f);
324341
float lod = min(gs_lod, max_lod) - bias;
325342

326-
return Texture.SampleLevel(TextureSampler, uv, lod);
343+
return DecodeTex(Texture.SampleLevel(TextureSampler, uv, lod));
327344
#else
328-
return Texture.SampleLevel(TextureSampler, uv, 0); // No lod
345+
return DecodeTex(Texture.SampleLevel(TextureSampler, uv, 0)); // No lod
329346
#endif
330347
#endif
331348
}
@@ -478,7 +495,7 @@ ctype4 sample_4_index(float4 uv, float uv_w)
478495
i = ctype4(c * 255.5f); // Denormalize value (so that 254.5 to 255 map to the last texel)
479496
}
480497
#else
481-
i = c * (PS_RTA_SRC_CORRECTION ? NEUTRAL_ALPHA : 255.0f);
498+
i = c * (PS_RTA_SRC_CORRECTION ? NEUTRAL_ALPHA : 255.0f); //TODO1 HDR_ALPHA?
482499
#endif
483500

484501
// Remap coordinates for the current palette size (range)
@@ -524,25 +541,25 @@ float4x4 sample_4p(ctype4 u)
524541
int fetch_raw_depth(int2 xy)
525542
{
526543
#if PS_TEX_IS_FB == 1
527-
float4 col = RtTexture.Load(int3(xy, 0));
544+
float4 col = DecodeTex(RtTexture.Load(int3(xy, 0)));
528545
#else
529-
float4 col = Texture.Load(int3(xy, 0));
546+
float4 col = DecodeTex(Texture.Load(int3(xy, 0)));
530547
#endif
531548
return (int)(col.r * exp2(32.0f));
532549
}
533550

534551
float4 fetch_raw_color(int2 xy)
535552
{
536553
#if PS_TEX_IS_FB == 1
537-
return RtTexture.Load(int3(xy, 0));
554+
return DecodeTex(RtTexture.Load(int3(xy, 0)));
538555
#else
539-
return Texture.Load(int3(xy, 0));
556+
return DecodeTex(Texture.Load(int3(xy, 0)));
540557
#endif
541558
}
542559

543560
float4 fetch_c(int2 uv)
544561
{
545-
return Texture.Load(int3(uv, 0));
562+
return DecodeTex(Texture.Load(int3(uv, 0)));
546563
}
547564

548565
//////////////////////////////////////////////////////////////////////
@@ -744,7 +761,7 @@ float4 fetch_gXbY(int2 xy)
744761
{
745762
float4 rt_float = fetch_raw_color(xy) * 255.0f;
746763
#if PS_HDR
747-
rt_float = min(round(rt_float), 255.0f);
764+
rt_float = min(round(rt_float), 255.0f) + 0.5f;
748765
#endif
749766
int4 rt = (int4)rt_float;
750767
int green = (rt.g >> ChannelShuffle.w) & ChannelShuffle.z;
@@ -755,7 +772,7 @@ float4 fetch_gXbY(int2 xy)
755772

756773
float4 sample_color(float2 st, float uv_w)
757774
{
758-
#if PS_TCOFFSETHACK
775+
#if PS_TCOFFSETHACK
759776
st += TC_OffsetHack.xy;
760777
#endif
761778

@@ -831,14 +848,14 @@ float4 sample_color(float2 st, float uv_w)
831848

832849
if (PS_AEM_FMT == FMT_32 && PS_PAL_FMT == 0 && PS_RTA_SRC_CORRECTION)
833850
{
834-
if (PS_HDR == 0)
851+
if (PS_HDR == 0 || HDR_ALPHA)
835852
t.a *= (NEUTRAL_ALPHA + 0.5) / 255.0f; // Add 0.5 for int rounding
836853
else
837854
t.a *= NEUTRAL_ALPHA / 255.0f;
838855
}
839856

840857
t *= 255.0f;
841-
if (!PS_HDR)
858+
if (PS_HDR == 0 || HDR_ALPHA)
842859
{
843860
t = trunc(t + 0.05f);
844861
}
@@ -857,6 +874,10 @@ float4 tfx(float4 T, float4 C)
857874
{
858875
FxT = trunc(FxT);
859876
}
877+
else if (HDR_ALPHA)
878+
{
879+
FxT.a = trunc(FxT.a);
880+
}
860881

861882
// Modulate
862883
// Multiplies texture by vertex (can generate HDR brightnesses)
@@ -935,7 +956,7 @@ float4 shuffle(float4 C, bool true_read_false_write)
935956
{
936957
//TODO1: allow float? or int. It'd be very hard... (same around all other PS_SHUFFLE code)
937958
#if PS_HDR
938-
C = min(round(C), 255.0f);
959+
C = min(round(C), 255.0f) + 0.5f;
939960
#endif
940961
uint4 denorm_c_before = uint4(C);
941962
if (PS_PROCESS_BA & (true_read_false_write ? SHUFFLE_READ : SHUFFLE_WRITE))
@@ -1028,7 +1049,7 @@ void ps_fbmask(inout float4 C, float2 pos_xy)
10281049
#if 1 //TODO1: test!
10291050
if (PS_HDR && !PS_COLCLIP_HW) // Don't do this in colclip hw mode as it can't output "HDR"
10301051
{
1031-
float4 RT = RtTexture.Load(int3(pos_xy, 0)) * 255.0f;
1052+
float4 RT = DecodeTex(RtTexture.Load(int3(pos_xy, 0))) * 255.0f;
10321053
bool4 hi_bit = (FbMask & 0x80) != 0;
10331054
RT = hi_bit ? RT : min(RT, 255.0f);
10341055
C = hi_bit ? min(C, 255.0f) : C;
@@ -1041,7 +1062,7 @@ void ps_fbmask(inout float4 C, float2 pos_xy)
10411062
#endif
10421063
{
10431064
float multi = PS_COLCLIP_HW ? 65535.0f : 255.0f;
1044-
float4 RT = trunc(RtTexture.Load(int3(pos_xy, 0)) * multi + RT_COLOR_OFFSET);
1065+
float4 RT = trunc(DecodeTex(RtTexture.Load(int3(pos_xy, 0))) * multi + RT_COLOR_OFFSET);
10451066
C = (float4)(((uint4)C & ~FbMask) | ((uint4)RT & FbMask));
10461067
}
10471068
}
@@ -1146,15 +1167,15 @@ void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy)
11461167
As_rgba.rgb = (float3)1.0f;
11471168
}
11481169

1149-
float4 RT = SW_BLEND_NEEDS_RT ? RtTexture.Load(int3(pos_xy, 0)) : (float4)0.0f;
1170+
float4 RT = SW_BLEND_NEEDS_RT ? DecodeTex(RtTexture.Load(int3(pos_xy, 0))) : (float4)0.0f;
11501171

11511172
if (PS_SHUFFLE && SW_BLEND_NEEDS_RT)
11521173
{
11531174
RT = shuffle(RT, false);
11541175
}
11551176

11561177
float Ad = (RT.a * (PS_RTA_CORRECTION ? NEUTRAL_ALPHA : 255.0f) + RT_COLOR_OFFSET) / NEUTRAL_ALPHA;
1157-
if (PS_HDR == 0)
1178+
if (PS_HDR == 0 || HDR_ALPHA)
11581179
{
11591180
Ad = trunc(Ad);
11601181
}
@@ -1316,8 +1337,8 @@ PS_OUTPUT ps_main(PS_INPUT input)
13161337
float4 alpha_blend = (float4)0.0f;
13171338
if (SW_AD_TO_HW)
13181339
{
1319-
float RTa = RtTexture.Load(int3(input.p.xy, 0)).a * (PS_RTA_CORRECTION ? NEUTRAL_ALPHA : 255.0f) + RT_COLOR_OFFSET;
1320-
if (PS_HDR == 0)
1340+
float RTa = DecodeTex(RtTexture.Load(int3(input.p.xy, 0))).a * (PS_RTA_CORRECTION ? NEUTRAL_ALPHA : 255.0f) + RT_COLOR_OFFSET;
1341+
if (PS_HDR == 0 || HDR_ALPHA)
13211342
{
13221343
RTa = trunc(RTa);
13231344
}
@@ -1374,7 +1395,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
13741395
if (!PS_SHUFFLE_SAME && !PS_READ16_SRC && !(PS_PROCESS_BA == SHUFFLE_READWRITE && PS_PROCESS_RG == SHUFFLE_READWRITE))
13751396
{
13761397
#if PS_HDR
1377-
C = min(round(C), 255.0f);
1398+
C = min(round(C), 255.0f) + 0.5f;
13781399
#endif
13791400
uint4 denorm_c_after = uint4(C);
13801401
if (PS_PROCESS_BA & SHUFFLE_READ)
@@ -1393,7 +1414,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
13931414
if (PS_SHUFFLE_SAME)
13941415
{
13951416
#if PS_HDR
1396-
C = min(round(C), 255.0f);
1417+
C = min(round(C), 255.0f) + 0.5f;
13971418
#endif
13981419
uint4 denorm_c = uint4(C);
13991420

@@ -1406,7 +1427,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
14061427
else if (PS_READ16_SRC)
14071428
{
14081429
#if PS_HDR
1409-
C = min(round(C), 255.0f);
1430+
C = min(round(C), 255.0f) + 0.5f;
14101431
#endif
14111432
uint4 denorm_c = uint4(C);
14121433
uint2 denorm_TA = uint2(float2(TA.xy) * 255.0f + 0.5f);
@@ -1454,14 +1475,16 @@ PS_OUTPUT ps_main(PS_INPUT input)
14541475
#endif
14551476

14561477
#if !PS_NO_COLOR
1478+
#if PS_HDR && HDR_ALPHA
1479+
C.a = round(C.a);
1480+
#endif
14571481
output.c0.a = PS_RTA_CORRECTION ? (C.a / NEUTRAL_ALPHA) : (C.a / 255.0f); //TODO1: force disable/enable RTA correction for HDR?
14581482
output.c0.rgb = PS_COLCLIP_HW ? (C.rgb / 65535.0f) : (C.rgb / 255.0f);
1459-
1460-
#if PS_HDR //TODO1: here and below
1483+
#if PS_HDR //TODO1: here and below and above
14611484
//output.c0.a = clamp(output.c0.a, 0.f, 1.f); // Probably not needed as alpha is never touched
14621485
//output.c0.rgb = clamp(output.c0.rgb, 0.f, 1.f);
14631486
//output.c0 = round(output.c0 * 255.0f) / 255.0f;
1464-
output.c0.a = round(output.c0.a * 255.0f) / 255.0f;
1487+
//output.c0.a = round(output.c0.a * 255.0f) / 255.0f;
14651488
#endif
14661489
#if PS_COLCLIP_HW && 0 //TODO: test... It's not recursive...
14671490
// Pre wrap negative values as we can't store negative colors in colclip hw textures!

0 commit comments

Comments
 (0)