mirror of https://github.com/PCSX2/pcsx2.git
GS-hw: Further improve how we handle blend mix 1.
Compensate slightly for Cd*(As + 1) - Cs*As. Try to compensate a bit with substracting 1 (0.00392) * (Alpha + 1) from Cs. The initial factor we chose is 1 (0.00392) as that is the minimum color Cd can be, then we multiply by alpha to get the minimum blended value it can be.
This commit is contained in:
parent
8fbb1e5565
commit
abcbdc4a25
|
@ -778,8 +778,9 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
|
|||
|
||||
// As/Af clamp alpha for Blend mix
|
||||
// We shouldn't clamp blend mix with clr1 as we want alpha higher
|
||||
float C_clamped = C;
|
||||
if (PS_BLEND_MIX > 0 && PS_CLR_HW != 1)
|
||||
C = min(C, 1.0f);
|
||||
C_clamped = min(C_clamped, 1.0f);
|
||||
|
||||
if (PS_BLEND_A == PS_BLEND_B)
|
||||
Color.rgb = D;
|
||||
|
@ -791,9 +792,9 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
|
|||
// Based on the scripts at the above link, the ideal choice for Intel GPUs is 126/256, AMD 120/256. Nvidia is a lost cause.
|
||||
// 124/256 seems like a reasonable compromise, providing the correct answer 99.3% of the time on Intel (vs 99.6% for 126/256), and 97% of the time on AMD (vs 97.4% for 120/256).
|
||||
else if (PS_BLEND_MIX == 2)
|
||||
Color.rgb = ((A - B) * C + D) + (124.0f/256.0f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) + (124.0f / 256.0f);
|
||||
else if (PS_BLEND_MIX == 1)
|
||||
Color.rgb = ((A - B) * C + D) - (124.0f/256.0f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) - (124.0f / 256.0f);
|
||||
else
|
||||
Color.rgb = trunc(((A - B) * C) + D);
|
||||
|
||||
|
@ -811,6 +812,16 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
|
|||
float alpha_compensate = max(1.0f, min_color / 255.0f);
|
||||
As -= alpha_compensate;
|
||||
}
|
||||
else if (PS_CLR_HW == 2)
|
||||
{
|
||||
// Compensate slightly for Cd*(As + 1) - Cs*As.
|
||||
// The initial factor we chose is 1 (0.00392)
|
||||
// as that is the minimum color Cd can be,
|
||||
// then we multiply by alpha to get the minimum
|
||||
// blended value it can be.
|
||||
float color_compensate = 1.0f * (C + 1.0f);
|
||||
Color.rgb -= (float3)color_compensate;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -721,8 +721,9 @@ void ps_blend(inout vec4 Color, inout float As)
|
|||
|
||||
// As/Af clamp alpha for Blend mix
|
||||
// We shouldn't clamp blend mix with clr1 as we want alpha higher
|
||||
float C_clamped = C;
|
||||
#if PS_BLEND_MIX > 0 && PS_CLR_HW != 1
|
||||
C = min(C, 1.0f);
|
||||
C_clamped = min(C_clamped, 1.0f);
|
||||
#endif
|
||||
|
||||
#if PS_BLEND_A == PS_BLEND_B
|
||||
|
@ -735,9 +736,9 @@ void ps_blend(inout vec4 Color, inout float As)
|
|||
// Based on the scripts at the above link, the ideal choice for Intel GPUs is 126/256, AMD 120/256. Nvidia is a lost cause.
|
||||
// 124/256 seems like a reasonable compromise, providing the correct answer 99.3% of the time on Intel (vs 99.6% for 126/256), and 97% of the time on AMD (vs 97.4% for 120/256).
|
||||
#elif PS_BLEND_MIX == 2
|
||||
Color.rgb = ((A - B) * C + D) + (124.0f/256.0f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) + (124.0f/256.0f);
|
||||
#elif PS_BLEND_MIX == 1
|
||||
Color.rgb = ((A - B) * C + D) - (124.0f/256.0f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) - (124.0f/256.0f);
|
||||
#else
|
||||
Color.rgb = trunc((A - B) * C + D);
|
||||
#endif
|
||||
|
@ -755,6 +756,14 @@ void ps_blend(inout vec4 Color, inout float As)
|
|||
float min_color = min(min(Color.r, Color.g), Color.b);
|
||||
float alpha_compensate = max(1.0f, min_color / 255.0f);
|
||||
As -= alpha_compensate;
|
||||
#elif PS_CLR_HW == 2
|
||||
// Compensate slightly for Cd*(As + 1) - Cs*As.
|
||||
// The initial factor we chose is 1 (0.00392)
|
||||
// as that is the minimum color Cd can be,
|
||||
// then we multiply by alpha to get the minimum
|
||||
// blended value it can be.
|
||||
float color_compensate = 1.0f * (C + 1.0f);
|
||||
Color.rgb -= vec3(color_compensate);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
|
|
@ -1053,8 +1053,9 @@ void ps_blend(inout vec4 Color, inout float As)
|
|||
|
||||
// As/Af clamp alpha for Blend mix
|
||||
// We shouldn't clamp blend mix with clr1 as we want alpha higher
|
||||
float C_clamped = C;
|
||||
#if PS_BLEND_MIX > 0 && PS_CLR_HW != 1
|
||||
C = min(C, 1.0f);
|
||||
C_clamped = min(C_clamped, 1.0f);
|
||||
#endif
|
||||
|
||||
#if PS_BLEND_A == PS_BLEND_B
|
||||
|
@ -1067,9 +1068,9 @@ void ps_blend(inout vec4 Color, inout float As)
|
|||
// Based on the scripts at the above link, the ideal choice for Intel GPUs is 126/256, AMD 120/256. Nvidia is a lost cause.
|
||||
// 124/256 seems like a reasonable compromise, providing the correct answer 99.3% of the time on Intel (vs 99.6% for 126/256), and 97% of the time on AMD (vs 97.4% for 120/256).
|
||||
#elif PS_BLEND_MIX == 2
|
||||
Color.rgb = ((A - B) * C + D) + (124.0f/256.0f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) + (124.0f/256.0f);
|
||||
#elif PS_BLEND_MIX == 1
|
||||
Color.rgb = ((A - B) * C + D) - (124.0f/256.0f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) - (124.0f/256.0f);
|
||||
#else
|
||||
Color.rgb = trunc((A - B) * C + D);
|
||||
#endif
|
||||
|
@ -1087,6 +1088,14 @@ void ps_blend(inout vec4 Color, inout float As)
|
|||
float min_color = min(min(Color.r, Color.g), Color.b);
|
||||
float alpha_compensate = max(1.0f, min_color / 255.0f);
|
||||
As -= alpha_compensate;
|
||||
#elif PS_CLR_HW == 2
|
||||
// Compensate slightly for Cd*(As + 1) - Cs*As.
|
||||
// The initial factor we chose is 1 (0.00392)
|
||||
// as that is the minimum color Cd can be,
|
||||
// then we multiply by alpha to get the minimum
|
||||
// blended value it can be.
|
||||
float color_compensate = 1.0f * (C + 1.0f);
|
||||
Color.rgb -= vec3(color_compensate);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
|
|
@ -2914,6 +2914,12 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
|||
// DSB output will always be used.
|
||||
m_conf.ps.no_color1 = false;
|
||||
}
|
||||
else if (m_conf.ps.blend_a == m_conf.ps.blend_d)
|
||||
{
|
||||
// Compensate slightly for Cd*(As + 1) - Cs*As.
|
||||
// Try to compensate a bit with subtracting 1 (0.00392) * (Alpha + 1) from Cs.
|
||||
m_conf.ps.clr_hw = 2;
|
||||
}
|
||||
|
||||
m_conf.ps.blend_a = 0;
|
||||
m_conf.ps.blend_b = 2;
|
||||
|
|
|
@ -835,8 +835,9 @@ struct PSMain
|
|||
|
||||
// As/Af clamp alpha for Blend mix
|
||||
// We shouldn't clamp blend mix with clr1 as we want alpha higher
|
||||
float C_clamped = C;
|
||||
if (PS_BLEND_MIX > 0 && PS_CLR_HW != 1)
|
||||
C = min(C, 1.f);
|
||||
C_clamped = min(C_clamped, 1.f);
|
||||
|
||||
if (PS_BLEND_A == PS_BLEND_B)
|
||||
Color.rgb = D;
|
||||
|
@ -848,9 +849,9 @@ struct PSMain
|
|||
// Based on the scripts at the above link, the ideal choice for Intel GPUs is 126/256, AMD 120/256. Nvidia is a lost cause.
|
||||
// 124/256 seems like a reasonable compromise, providing the correct answer 99.3% of the time on Intel (vs 99.6% for 126/256), and 97% of the time on AMD (vs 97.4% for 120/256).
|
||||
else if (PS_BLEND_MIX == 2)
|
||||
Color.rgb = ((A - B) * C + D) + (124.f/256.f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) + (124.f/256.f);
|
||||
else if (PS_BLEND_MIX == 1)
|
||||
Color.rgb = ((A - B) * C + D) - (124.f/256.f);
|
||||
Color.rgb = ((A - B) * C_clamped + D) - (124.f/256.f);
|
||||
else
|
||||
Color.rgb = trunc((A - B) * C + D);
|
||||
|
||||
|
@ -868,6 +869,16 @@ struct PSMain
|
|||
float alpha_compensate = max(1.f, min_color / 255.f);
|
||||
As -= alpha_compensate;
|
||||
}
|
||||
else if (PS_CLR_HW == 2)
|
||||
{
|
||||
// Compensate slightly for Cd*(As + 1) - Cs*As.
|
||||
// The initial factor we chose is 1 (0.00392)
|
||||
// as that is the minimum color Cd can be,
|
||||
// then we multiply by alpha to get the minimum
|
||||
// blended value it can be.
|
||||
float color_compensate = 1.f * (C + 1.f);
|
||||
Color.rgb -= float3(color_compensate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue