Files
UnrealEngineUWP/Engine/Shaders/Private/ColorDeficiency.ush
benjamin rouveyrol 2aff3c61c3 Fix color deficiency filter (CDF) with HDR
The current problem is that the CDF is not taking into account PLATFORM_SUPPORTS_RENDERTARGET_WRITE_MASK and was only applying the filter to the UI rendertarget.

If the fix was applied inside FSlatePostProcessor::ColorDeficiency, we'd have to add support for PLATFORM_SUPPORTS_RENDERTARGET_WRITE_MASK, call FRenderTargetWriteMask::Decode, and add additional copies in order to apply the filter to both the HDR and SDR targets.

Since we apply the color deficiency filter at the end of FSlateRHIRenderingPolicy::DrawElements, we can apply the CDF inside the composition pass in HDR instead. We need to be careful to apply it to the whole screen now instead of relying on CompositeUIMask, but it's still cheaper and simpler than doing all the copies / processing I mentionned above

#preflight 633483c53041fbb5662179d5 6334aaafb946208fc1c009d8 6334aad31b5c12202432c6ba
#rb eric.renaudhoude
#jira UE-165414

[CL 22260598 by benjamin rouveyrol in ue5-main branch]
2022-09-29 20:26:27 -04:00

253 lines
7.3 KiB
Plaintext

// CDV tables comes from:
// A Model for Simulation of Color Vision Deficiency and A Color Contrast Enhancement Technique for Dichromats
// - Gustavo M. Machado (2010)
static const float3 RGB_2_Protanomaly[11 * 3] =
{
// Severity - 0
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
// Severity - 1
float3(0.856167, 0.182038, -0.038205),
float3(0.029342, 0.955115, 0.015544),
float3(-0.002880, -0.001563, 1.004443),
// Severity - 2
float3(0.734766, 0.334872, -0.069637),
float3(0.051840, 0.919198, 0.028963),
float3(-0.004928, -0.004209, 1.009137),
// Severity - 3
float3(0.630323, 0.465641, -0.095964),
float3(0.069181, 0.890046, 0.040773),
float3(-0.006308, -0.007724, 1.014032),
// Severity - 4
float3(0.539009, 0.579343, -0.118352),
float3(0.082546, 0.866121, 0.051332),
float3(-0.007136, -0.011959, 1.019095),
// Severity - 5
float3(0.458064, 0.679578, -0.137642),
float3(0.092785, 0.846313, 0.060902),
float3(-0.007494, -0.016807, 1.024301),
// Severity - 6
float3(0.385450, 0.769005, -0.154455),
float3(0.100526, 0.829802, 0.069673),
float3(-0.007442, -0.022190, 1.029632),
// Severity - 7
float3(0.319627, 0.849633, -0.169261),
float3(0.106241, 0.815969, 0.077790),
float3(-0.007025, -0.028051, 1.035076),
// Severity - 8
float3(0.259411, 0.923008, -0.182420),
float3(0.110296, 0.804340, 0.085364),
float3(-0.006276, -0.034346, 1.040622),
// Severity - 9
float3(0.203876, 0.990338, -0.194214),
float3(0.112975, 0.794542, 0.092483),
float3(-0.005222, -0.041043, 1.046265),
// Severity - 10
float3(0.152286, 1.052583, -0.204868),
float3(0.114503, 0.786281, 0.099216),
float3(-0.003882, -0.048116, 1.051998)
};
static const float3 RGB_2_Deuteranomaly[11 * 3] =
{
// Severity - 0
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
// Severity - 1
float3(0.866435, 0.177704, -0.044139),
float3(0.049567, 0.939063, 0.011370),
float3(-0.003453, 0.007233, 0.996220),
// Severity - 2
float3(0.760729, 0.319078, -0.079807),
float3(0.090568, 0.889315, 0.020117),
float3(-0.006027, 0.013325, 0.992702),
// Severity - 3
float3(0.675425, 0.433850, -0.109275),
float3(0.125303, 0.847755, 0.026942),
float3(-0.007950, 0.018572, 0.989378),
// Severity - 4
float3(0.605511, 0.528560, -0.134071),
float3(0.155318, 0.812366, 0.032316),
float3(-0.009376, 0.023176, 0.986200),
// Severity - 5
float3(0.547494, 0.607765, -0.155259),
float3(0.181692, 0.781742, 0.036566),
float3(-0.010410, 0.027275, 0.983136),
// Severity - 6
float3(0.498864, 0.674741, -0.173604),
float3(0.205199, 0.754872, 0.039929),
float3(-0.011131, 0.030969, 0.980162),
// Severity - 7
float3(0.457771, 0.731899, -0.189670),
float3(0.226409, 0.731012, 0.042579),
float3(-0.011595, 0.034333, 0.977261),
// Severity - 8
float3(0.422823, 0.781057, -0.203881),
float3(0.245752, 0.709602, 0.044646),
float3(-0.011843, 0.037423, 0.974421),
// Severity - 9
float3(0.392952, 0.823610, -0.216562),
float3(0.263559, 0.690210, 0.046232),
float3(-0.011910, 0.040281, 0.971630),
// Severity - 10
float3(0.367322, 0.860646, -0.227968),
float3(0.280085, 0.672501, 0.047413),
float3(-0.011820, 0.042940, 0.968881)
};
static const float3 RGB_2_Tritanomaly[11 * 3] =
{
// Severity - 0
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
// Severity - 1
float3(0.926670, 0.092514, -0.019184),
float3(0.021191, 0.964503, 0.014306),
float3(0.008437, 0.054813, 0.936750),
// Severity - 2
float3(0.895720, 0.133330, -0.029050),
float3(0.029997, 0.945400, 0.024603),
float3(0.013027, 0.104707, 0.882266),
// Severity - 3
float3(0.905871, 0.127791, -0.033662),
float3(0.026856, 0.941251, 0.031893),
float3(0.013410, 0.148296, 0.838294),
// Severity - 4
float3(0.948035, 0.089490, -0.037526),
float3(0.014364, 0.946792, 0.038844),
float3(0.010853, 0.193991, 0.795156),
// Severity - 5
float3(1.017277, 0.027029, -0.044306),
float3(-0.006113, 0.958479, 0.047634),
float3(0.006379, 0.248708, 0.744913),
// Severity - 6
float3(1.104996, -0.046633, -0.058363),
float3(-0.032137, 0.971635, 0.060503),
float3(0.001336, 0.317922, 0.680742),
// Severity - 7
float3(1.193214, -0.109812, -0.083402),
float3(-0.058496, 0.979410, 0.079086),
float3(-0.002346, 0.403492, 0.598854),
// Severity - 8
float3(1.257728, -0.139648, -0.118081),
float3(-0.078003, 0.975409, 0.102594),
float3(-0.003316, 0.501214, 0.502102),
// Severity - 9
float3(1.278864, -0.125333, -0.153531),
float3(-0.084748, 0.957674, 0.127074),
float3(-0.000989, 0.601151, 0.399838),
// Severity - 10
float3(1.255528, -0.076749, -0.178779),
float3(-0.078411, 0.930809, 0.147602),
float3(0.004733, 0.691367, 0.303900)
};
#define CDV_NormalVision 0
#define CDV_Deuteranope 1
#define CDV_Protanope 2
#define CDV_Tritanope 3
float3 ConvertSourceRGBToDeficientRGB(float3 SourceRGB, float ColorVisionDeficiencySeverity, float ColorVisionDeficiencyType)
{
float3 DeficientRGB = SourceRGB;
int Index = (int)ColorVisionDeficiencySeverity * 3;
if (ColorVisionDeficiencyType == CDV_Deuteranope)
{
float3x3 Mat = float3x3(RGB_2_Deuteranomaly[Index], RGB_2_Deuteranomaly[Index + 1], RGB_2_Deuteranomaly[Index + 2]);
DeficientRGB = mul(Mat, SourceRGB);
}
else if (ColorVisionDeficiencyType == CDV_Protanope)
{
float3x3 Mat = float3x3(RGB_2_Protanomaly[Index], RGB_2_Protanomaly[Index + 1], RGB_2_Protanomaly[Index + 2]);
DeficientRGB = mul(Mat, SourceRGB);
}
else if (ColorVisionDeficiencyType == CDV_Tritanope)
{
float3x3 Mat = float3x3(RGB_2_Tritanomaly[Index], RGB_2_Tritanomaly[Index + 1], RGB_2_Tritanomaly[Index + 2]);
DeficientRGB = mul(Mat, SourceRGB);
}
return DeficientRGB;
}
// http://www.daltonize.org
static const float3x3 RGB_DALTONIZE_MAT =
{
0.0, 0.7, 0.7,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
};
static const float3x3 RGB_DALTONIZE_RED_BLIND =
{
0.5, 1.0, 1.0,
0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
};
static const float3x3 RGB_DALTONIZE_GREEN_BLIND =
{
0.5, 0.0, 0.5,
1.0, 0.0, 1.0,
0.5, 0.0, 0.5,
};
static const float3x3 RGB_DALTONIZE_BLUE_BLIND =
{
0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
1.0, 1.0, 0.5,
};
#define USE_RGB_SPACE_CDV_CORRECTION 1
#define USE_SINGLE_DALTONIZE_MATRIX 0
float3 ColorDeficiency(float3 SourceRGB, float ColorVisionDeficiencyType, float ColorVisionDeficiencySeverity, float bCorrectDeficiency, float bSimulateCorrectionWithDeficiency)
{
float3 DeficientRGB = ConvertSourceRGBToDeficientRGB(SourceRGB, ColorVisionDeficiencySeverity, ColorVisionDeficiencyType);
float3 OutRGB = DeficientRGB;
if (bCorrectDeficiency == 1)
{
#if USE_RGB_SPACE_CDV_CORRECTION
//
float3 ErrorRGB = (SourceRGB - DeficientRGB);
#if USE_SINGLE_DALTONIZE_MATRIX
//
float3 CorrectionRGB = mul(RGB_DALTONIZE_MAT, ErrorRGB);
#else
float3 CorrectionRGB = float3(0.0, 0.0, 0.0);
if (ColorVisionDeficiencyType == CDV_Deuteranope)
{
CorrectionRGB = mul(RGB_DALTONIZE_GREEN_BLIND, ErrorRGB);
}
else if (ColorVisionDeficiencyType == CDV_Protanope)
{
CorrectionRGB = mul(RGB_DALTONIZE_RED_BLIND, ErrorRGB);
}
else if (ColorVisionDeficiencyType == CDV_Tritanope)
{
CorrectionRGB = mul(RGB_DALTONIZE_BLUE_BLIND, ErrorRGB);
}
#endif
//
OutRGB = SourceRGB + CorrectionRGB;
#endif
if (bSimulateCorrectionWithDeficiency == 1)
{
OutRGB = ConvertSourceRGBToDeficientRGB(OutRGB, ColorVisionDeficiencySeverity, ColorVisionDeficiencyType);
}
}
return OutRGB;
}