255 lines
7.3 KiB
HLSL
255 lines
7.3 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
// 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;
|
|
}
|