#version 300 es #extension GL_OES_EGL_image_external_essl3: require #define PI 3.1415926535897932384626433832795 #define EULER 2.7182818284590452353602874713527 #define BACK 1 uniform samplerExternalOES cameraBack;///min:n;mag:n;s:c;t:c; #define mirror mat2(\ -1, 0,\ 0, 1\ ) precision highp float; precision highp int; uniform vec2 resolution; uniform mat2 cameraOrientation; uniform float time; #ifdef BACK #define orient cameraOrientation #define cam cameraBack #endif #ifdef FRONT #define orient mirror*cameraOrientation #define cam cameraFront #endif out vec4 gl_FragColor; /* * Structures */ // Parameters for transfer characteristics (gamma curves) struct transfer { // Exponent used to linearize the signal vec3 power; // Offset from 0.0 for the exponential curve vec3 off; // Slope of linear segment near 0 vec3 slope; // Values below this are divided by slope during linearization vec3 cutoffToLinear; // Values below this are multiplied by slope during gamma correction vec3 cutoffToGamma; }; // Parameters for a colorspace struct rgb_space { // Chromaticity coordinates (xyz) for Red, Green, and Blue primaries mat3 primaries; // Chromaticity coordinates (xyz) for white point vec3 white; // Linearization and gamma correction parameters transfer trc; }; /* * Preprocessor 'functions' that help build colorspaces as constants */ // Turns 6 chromaticity coordinates into a 3x3 matrix #define Primaries(r1, r2, g1, g2, b1, b2)\ mat3(\ (r1), (r2), 1.0 - (r1) - (r2),\ (g1), (g2), 1.0 - (g1) - (g2),\ (b1), (b2), 1.0 - (b1) - (b2)) // Creates a whitepoint's xyz chromaticity coordinates from the given xy coordinates #define White(x, y)\ vec3((x), (y), 1.0 - (x) - (y)) // Rescale so that the Y channel is 1.0 #define Bright(w)\ ((w)/(w).y) // Creates a scaling matrix using a vec3 to set the xyz scalars #define diag(v)\ mat3(\ (v).x, 0.0, 0.0,\ 0.0, (v).y, 0.0,\ 0.0, 0.0, (v).z) // Creates a conversion matrix that turns RGB colors into XYZ colors #define rgbToXyz(space)\ (space).primaries*diag(inverse((space).primaries)*Bright((space).white)) // Creates a conversion matrix that turns XYZ colors into RGB colors #define xyzToRgb(space)\ inverse(rgbToXyz(space)) // White balance using LMS instead of XYZ /*#define whiteBalance(fw, tw, wbm)\ inverse(wbm)*diag((wbm*fw)/(wbm*tw))*wbm*/ // Creates a conversion matrix converts linear RGB colors from one colorspace to another /*#define conversionMatrix(f, t, sw, dw, wbm)\ xyzToRgb(t)*whiteBalance(sw, dw, wbm)*rgbToXyz(f)*/ // Creates a conversion matrix converts linear RGB colors from one colorspace to another #define conversionMatrix(f, t)\ xyzToRgb(t)*rgbToXyz(f) // Automatically calculate the slope and cutoffs for transfer characteristics #define Transfer(po, of)\ transfer(\ (po),\ (of),\ (pow(1.0 + (of), (po))*pow((po) - 1.0, (po) - 1.0))/(pow((of), (po) - 1.0)*pow((po), (po))),\ (of)/((po) - 1.0),\ (of)/((po) - 1.0)*(pow(1.0 + (of), (po))*(pow((of), (po) - 1.0)*pow((po), (po)))/pow((po) - 1.0, (po) - 1.0))\ ) // Calculate inverse slope line of a white point's CCT #define SlpLin(white)\ (((white).x - 0.3320)/((white).y - 0.1858)) // Calculate a white point's correlated color temperature #define Cct(white)\ dot(\ vec4(pow(SlpLin(white), 3.0), pow(SlpLin(white), 2.0), SlpLin(white), 1.0),\ vec4(-449.0, 3525.0, 6823.3, 5520.33)) /* * RGB -> YUV matrices */ // YUV matrix for BT.601 const mat3 BT601 = mat3( 0.299, -299.0/1772.0, 0.5, 0.587, -587.0/1772.0, -587.0/1402.0, 0.114, 0.5, -57.0/701.0 ); // YUV matrix for BT.709 const mat3 BT709 = mat3( 0.2126, -1063.0/9278.0, 0.5, 0.7152, -1788.0/4639.0, -1788.0/3937.0, 0.0722, 0.5, -361.0/7874.0 ); // Inverse of the YUV matrix for BT.601 const mat3 BT601_INV = mat3( 1, 1, 1, 0, -25251.0/73375.0, 1.772, 1.402, -209599.0/293500.0, 0 ); // Inverse of the YUV matrix for BT.709 const mat3 BT709_INV = mat3( 1, 1, 1, 0, -167.4679/894.0, 1.8556, 1.5748, -418.5031/894.0, 0 ); // YUV matrix for BT.601 const mat3 BT601_NEW = mat3( 0.299, -32591.0/221500.0, 0.615, 0.587, -63983.0/221500.0, -72201.0/140200.0, 0.114, 0.436, -7011.0/70100.0 ); // YUV matrix for BT.709 const mat3 BT709_NEW = mat3( 0.2126, -115867.0/1159750.0, 0.615, 0.7152, -194892.0/579875.0, -54981.0/98425.0, 0.0722, 0.436, -44403.0/787400.0 ); // Inverse of the YUV matrix for BT.601 const mat3 BT601_NEW_INV = mat3( 1, 1, 1, 0, -25251.0/63983.0, 443.0/218.0, 701.0/615.0, -209599.0/361005.0, 0 ); // Inverse of the YUV matrix for BT.709 const mat3 BT709_NEW_INV = mat3( 1, 1, 1, 0, -1674679.0/7795680.0, 4639.0/2180.0, 3937.0/3075.0, -4185031.0/10996200.0, 0 ); /* * XYZ -> LMS matrices */ // Hunt-Pointer-Estevez transformation matrix, used by the Hunt and RLAB color // appearance models, and originally used with the von Kries method const mat3 HUNT = mat3( 0.38971, -0.22981, 0, 0.68898, 1.1834, 0, -0.07868, 0.04641, 1 ); // Used by the 1997 CIE Color Appearance Model. Also known as the Bradford // transfsormation matrix. This matrix represents 'spectrally sharpened' cone // fundamentals, and was meant to use a slightly non-linear S channel const mat3 CIECAM97_1 = mat3( 0.8951, -0.7502, 0.0389, 0.2664, 1.7135, -0.0685, -0.1614, 0.0367, 1.0296 ); // Revised 1997 CIE CAM matrix, removing the dependency on non-linear blues const mat3 CIECAM97_2 = mat3( 0.8562, -0.836, 0.0357, 0.3372, 1.8327, -0.0469, -0.1934, 0.0033, 1.0112 ); // Used by the 2002 CIE Color Appearance Model. This is the successor to the // above two matrices, and is very widely used const mat3 CIECAM02 = mat3( 0.7328, -0.7036, 0.003, 0.4296, 1.6975, 0.0136, -0.1624, 0.0061, 0.9834 ); /* * Two camera matrices of each type, each for a * different white point. * * 1: D65 * 2: A */ // Camera native colorspace transformation matrix const mat3 cameraMat1 = mat3( 92.0/128.0, -72.0/128.0, -29.0/128.0, -25.0/128.0, 173.0/128.0, 40.0/128.0, -11.0/128.0, 21.0/128.0, 69.0/128.0 ); const mat3 cameraMat2 = mat3( 135.0/128.0, -72.0/128.0, -7.0/128.0, -39.0/128.0, 212.0/128.0, 25.0/128.0, -35.0/128.0, -15.0/128.0, 76.0/128.0 ); const mat3 cameraCal1 = diag(vec3(127.0/128.0, 1, 124.0/128.0)); const mat3 cameraCal2 = diag(vec3(126.0/128.0, 1, 124.0/128.0)); const mat3 cameraFor1 = mat3( 85.0/128.0, 33.0/128.0, 12.0/128.0, 30.0/128.0, 112.0/128.0, -39.0/128.0, 8.0/128.0, -17.0/128.0, 133.0/128.0 ); const mat3 cameraFor2 = mat3( 85.0/128.0, 26.0/128.0, -1.0/128.0, 1.0/128.0, 85.0/128.0, -65.0/128.0, 37.0/128.0, 18.0/128.0, 172.0/128.0 ); const vec3 lut[256] = vec3[256]( vec3(0.00000000, 0.00000000, 0.00000000), vec3(0.00479441, 0.00455458, 0.00534472), vec3(0.00947921, 0.00901145, 0.01050410), vec3(0.01405810, 0.01337370, 0.01548750), vec3(0.01853470, 0.01764440, 0.02030390), vec3(0.02291230, 0.02182630, 0.02496150), vec3(0.02719420, 0.02592210, 0.02946810), vec3(0.03138350, 0.02993460, 0.03383080), vec3(0.03548310, 0.03386620, 0.03805900), vec3(0.03950300, 0.03772400, 0.04217240), vec3(0.04346390, 0.04152980, 0.04619020), vec3(0.04738110, 0.04529840, 0.05012600), vec3(0.05126060, 0.04903620, 0.05398720), vec3(0.05510080, 0.05274870, 0.05778140), vec3(0.05890820, 0.05644060, 0.06152200), vec3(0.06269220, 0.06012240, 0.06523120), vec3(0.06647310, 0.06380800, 0.06893090), vec3(0.07026770, 0.06751660, 0.07263180), vec3(0.07407940, 0.07126000, 0.07633810), vec3(0.07790060, 0.07503470, 0.08005280), vec3(0.08172950, 0.07883130, 0.08377420), vec3(0.08556030, 0.08264410, 0.08750050), vec3(0.08938360, 0.08646500, 0.09122830), vec3(0.09319140, 0.09028900, 0.09495620), vec3(0.09698120, 0.09411290, 0.09868160), vec3(0.10075500, 0.09793580, 0.10240800), vec3(0.10451900, 0.10175700, 0.10614000), vec3(0.10827400, 0.10558400, 0.10987900), vec3(0.11202600, 0.10942100, 0.11363600), vec3(0.11578000, 0.11327700, 0.11741700), vec3(0.11954100, 0.11715800, 0.12122100), vec3(0.12330600, 0.12106700, 0.12504200), vec3(0.12707400, 0.12499900, 0.12888100), vec3(0.13083500, 0.12894500, 0.13272800), vec3(0.13459400, 0.13289500, 0.13658300), vec3(0.13834600, 0.13684500, 0.14043600), vec3(0.14209000, 0.14078500, 0.14428900), vec3(0.14582300, 0.14471000, 0.14813500), vec3(0.14953800, 0.14861100, 0.15197000), vec3(0.15323200, 0.15248300, 0.15579000), vec3(0.15689800, 0.15632200, 0.15958400), vec3(0.16052900, 0.16012000, 0.16334800), vec3(0.16412500, 0.16387500, 0.16708100), vec3(0.16768700, 0.16758700, 0.17078900), vec3(0.17122500, 0.17127400, 0.17447400), vec3(0.17474400, 0.17494400, 0.17813500), vec3(0.17824000, 0.17860100, 0.18178700), vec3(0.18172000, 0.18225500, 0.18543000), vec3(0.18519200, 0.18591100, 0.18906600), vec3(0.18865800, 0.18957900, 0.19271400), vec3(0.19213800, 0.19327600, 0.19637800), vec3(0.19564000, 0.19700500, 0.20006500), vec3(0.19917000, 0.20077100, 0.20378800), vec3(0.20274200, 0.20458800, 0.20755100), vec3(0.20636700, 0.20845700, 0.21135400), vec3(0.21004700, 0.21237700, 0.21519600), vec3(0.21378200, 0.21634500, 0.21908500), vec3(0.21757000, 0.22035600, 0.22302300), vec3(0.22141200, 0.22441000, 0.22699200), vec3(0.22530700, 0.22848100, 0.23098500), vec3(0.22924500, 0.23256900, 0.23501000), vec3(0.23322800, 0.23667100, 0.23906000), vec3(0.23725900, 0.24078000, 0.24312400), vec3(0.24132600, 0.24489200, 0.24720300), vec3(0.24542400, 0.24900900, 0.25129900), vec3(0.24955400, 0.25312300, 0.25539100), vec3(0.25370100, 0.25721800, 0.25946400), vec3(0.25783800, 0.26129200, 0.26352100), vec3(0.26196600, 0.26535000, 0.26756200), vec3(0.26608400, 0.26939000, 0.27157900), vec3(0.27019000, 0.27340200, 0.27557300), vec3(0.27428200, 0.27739000, 0.27954200), vec3(0.27835700, 0.28135600, 0.28349300), vec3(0.28241900, 0.28531200, 0.28743000), vec3(0.28647400, 0.28925200, 0.29133300), vec3(0.29051000, 0.29316600, 0.29519800), vec3(0.29451800, 0.29705900, 0.29904000), vec3(0.29850700, 0.30093300, 0.30286300), vec3(0.30247700, 0.30479400, 0.30667700), vec3(0.30643600, 0.30864800, 0.31047900), vec3(0.31038800, 0.31249000, 0.31426400), vec3(0.31432800, 0.31633200, 0.31805100), vec3(0.31827600, 0.32018300, 0.32184000), vec3(0.32223200, 0.32404300, 0.32563400), vec3(0.32619900, 0.32791700, 0.32943200), vec3(0.33018300, 0.33180600, 0.33323500), vec3(0.33418300, 0.33571500, 0.33705300), vec3(0.33820400, 0.33966000, 0.34089000), vec3(0.34224400, 0.34364200, 0.34474500), vec3(0.34630300, 0.34766100, 0.34861900), vec3(0.35038200, 0.35171900, 0.35251200), vec3(0.35447300, 0.35581400, 0.35641600), vec3(0.35856500, 0.35993400, 0.36032400), vec3(0.36265300, 0.36407500, 0.36424300), vec3(0.36673700, 0.36823900, 0.36816900), vec3(0.37081700, 0.37242700, 0.37210200), vec3(0.37489400, 0.37663400, 0.37604300), vec3(0.37896000, 0.38083900, 0.37998500), vec3(0.38300700, 0.38503600, 0.38392300), vec3(0.38703700, 0.38922100, 0.38785600), vec3(0.39105500, 0.39340200, 0.39179100), vec3(0.39507100, 0.39759800, 0.39573900), vec3(0.39910100, 0.40181100, 0.39970300), vec3(0.40313800, 0.40599900, 0.40366900), vec3(0.40715900, 0.41015300, 0.40760700), vec3(0.41116200, 0.41428400, 0.41152000), vec3(0.41515900, 0.41840000, 0.41542200), vec3(0.41915100, 0.42249400, 0.41932000), vec3(0.42313000, 0.42656600, 0.42321200), vec3(0.42709400, 0.43062000, 0.42709900), vec3(0.43104500, 0.43464600, 0.43098400), vec3(0.43497700, 0.43864400, 0.43486000), vec3(0.43888400, 0.44263000, 0.43872600), vec3(0.44278200, 0.44661100, 0.44260000), vec3(0.44667800, 0.45056300, 0.44648700), vec3(0.45055900, 0.45448900, 0.45036700), vec3(0.45442100, 0.45838900, 0.45423800), vec3(0.45826400, 0.46226400, 0.45810000), vec3(0.46208700, 0.46610700, 0.46195600), vec3(0.46588500, 0.46992800, 0.46579400), vec3(0.46966600, 0.47373100, 0.46961900), vec3(0.47343600, 0.47751000, 0.47343400), vec3(0.47719100, 0.48126300, 0.47723100), vec3(0.48093800, 0.48499400, 0.48101000), vec3(0.48468400, 0.48870200, 0.48477000), vec3(0.48842900, 0.49238800, 0.48851000), vec3(0.49217400, 0.49605000, 0.49223100), vec3(0.49591900, 0.49969100, 0.49593100), vec3(0.49966200, 0.50331500, 0.49961200), vec3(0.50340500, 0.50693600, 0.50327500), vec3(0.50714100, 0.51055600, 0.50691400), vec3(0.51087400, 0.51417600, 0.51053600), vec3(0.51460300, 0.51779600, 0.51414100), vec3(0.51832900, 0.52141700, 0.51773000), vec3(0.52205000, 0.52503500, 0.52130500), vec3(0.52576200, 0.52865300, 0.52486600), vec3(0.52945700, 0.53227300, 0.52841300), vec3(0.53313800, 0.53589800, 0.53194900), vec3(0.53680400, 0.53952200, 0.53548100), vec3(0.54045800, 0.54314800, 0.53900200), vec3(0.54410300, 0.54677300, 0.54251600), vec3(0.54774200, 0.55039700, 0.54602500), vec3(0.55137600, 0.55402000, 0.54952800), vec3(0.55500200, 0.55764200, 0.55302000), vec3(0.55862000, 0.56126500, 0.55650300), vec3(0.56223400, 0.56489100, 0.55998300), vec3(0.56585000, 0.56853600, 0.56346300), vec3(0.56948900, 0.57220500, 0.56695700), vec3(0.57314800, 0.57589000, 0.57047300), vec3(0.57681600, 0.57958800, 0.57400600), vec3(0.58049200, 0.58330500, 0.57754100), vec3(0.58418300, 0.58704000, 0.58108200), vec3(0.58788300, 0.59079100, 0.58463300), vec3(0.59158800, 0.59454900, 0.58819700), vec3(0.59529100, 0.59830800, 0.59176700), vec3(0.59899100, 0.60207500, 0.59533800), vec3(0.60269800, 0.60585800, 0.59890900), vec3(0.60642700, 0.60966000, 0.60248700), vec3(0.61018100, 0.61348800, 0.60608300), vec3(0.61396400, 0.61734800, 0.60969900), vec3(0.61777400, 0.62123300, 0.61333500), vec3(0.62160000, 0.62514100, 0.61699500), vec3(0.62543800, 0.62906000, 0.62066500), vec3(0.62928000, 0.63298100, 0.62434300), vec3(0.63312300, 0.63690700, 0.62802800), vec3(0.63696500, 0.64084000, 0.63171100), vec3(0.64080200, 0.64477500, 0.63539100), vec3(0.64463200, 0.64870600, 0.63906700), vec3(0.64844600, 0.65264100, 0.64273600), vec3(0.65225200, 0.65659100, 0.64640000), vec3(0.65605400, 0.66056800, 0.65006700), vec3(0.65986400, 0.66457300, 0.65374900), vec3(0.66368200, 0.66860200, 0.65745300), vec3(0.66750900, 0.67261300, 0.66118700), vec3(0.67132700, 0.67659800, 0.66495300), vec3(0.67512200, 0.68055800, 0.66874300), vec3(0.67889400, 0.68450500, 0.67251800), vec3(0.68265100, 0.68844700, 0.67626800), vec3(0.68640300, 0.69240000, 0.67999600), vec3(0.69015900, 0.69636700, 0.68370600), vec3(0.69393800, 0.70034100, 0.68740700), vec3(0.69774000, 0.70432900, 0.69111500), vec3(0.70156000, 0.70833700, 0.69484100), vec3(0.70540100, 0.71236000, 0.69858600), vec3(0.70926700, 0.71639400, 0.70235000), vec3(0.71315500, 0.72042900, 0.70614100), vec3(0.71706600, 0.72446300, 0.70995200), vec3(0.72099300, 0.72850500, 0.71377800), vec3(0.72493400, 0.73255900, 0.71761900), vec3(0.72889300, 0.73663600, 0.72146800), vec3(0.73287100, 0.74074600, 0.72532500), vec3(0.73688100, 0.74488700, 0.72919600), vec3(0.74092800, 0.74905700, 0.73307700), vec3(0.74501600, 0.75324600, 0.73698100), vec3(0.74914300, 0.75743600, 0.74091600), vec3(0.75329600, 0.76162700, 0.74488100), vec3(0.75744700, 0.76581800, 0.74887600), vec3(0.76159500, 0.77001800, 0.75289600), vec3(0.76574400, 0.77422200, 0.75691400), vec3(0.76990400, 0.77842700, 0.76093000), vec3(0.77406700, 0.78263500, 0.76494300), vec3(0.77822800, 0.78684500, 0.76896000), vec3(0.78239100, 0.79104700, 0.77298300), vec3(0.78655600, 0.79524300, 0.77700000), vec3(0.79070900, 0.79943500, 0.78102000), vec3(0.79485500, 0.80360900, 0.78505000), vec3(0.79900100, 0.80772700, 0.78909000), vec3(0.80313900, 0.81179200, 0.79314700), vec3(0.80724400, 0.81582200, 0.79723000), vec3(0.81131400, 0.81983000, 0.80134200), vec3(0.81536100, 0.82381600, 0.80544600), vec3(0.81939900, 0.82778200, 0.80953200), vec3(0.82342900, 0.83172600, 0.81360900), vec3(0.82745100, 0.83565200, 0.81770100), vec3(0.83147000, 0.83958200, 0.82181500), vec3(0.83549000, 0.84352200, 0.82594900), vec3(0.83952500, 0.84747200, 0.83009300), vec3(0.84357700, 0.85142900, 0.83424400), vec3(0.84764700, 0.85539900, 0.83840900), vec3(0.85173300, 0.85938300, 0.84259000), vec3(0.85583800, 0.86336900, 0.84678800), vec3(0.85995900, 0.86736000, 0.85100500), vec3(0.86407900, 0.87136500, 0.85524600), vec3(0.86820100, 0.87538400, 0.85950800), vec3(0.87233500, 0.87940200, 0.86376700), vec3(0.87647500, 0.88340600, 0.86802800), vec3(0.88060900, 0.88740400, 0.87230600), vec3(0.88473300, 0.89140100, 0.87660100), vec3(0.88885600, 0.89537400, 0.88090300), vec3(0.89297300, 0.89933200, 0.88520900), vec3(0.89708100, 0.90327700, 0.88953800), vec3(0.90119000, 0.90721800, 0.89387200), vec3(0.90530400, 0.91115800, 0.89820400), vec3(0.90942500, 0.91509600, 0.90253600), vec3(0.91354900, 0.91903500, 0.90687900), vec3(0.91768400, 0.92297300, 0.91123700), vec3(0.92182500, 0.92690600, 0.91560300), vec3(0.92597000, 0.93083200, 0.91998000), vec3(0.93010900, 0.93474700, 0.92437200), vec3(0.93424000, 0.93864100, 0.92876400), vec3(0.93835500, 0.94252700, 0.93315800), vec3(0.94246900, 0.94640300, 0.93755400), vec3(0.94658500, 0.95027500, 0.94195900), vec3(0.95070300, 0.95414500, 0.94637600), vec3(0.95482000, 0.95800900, 0.95080400), vec3(0.95893400, 0.96186300, 0.95524000), vec3(0.96304200, 0.96570500, 0.95968200), vec3(0.96714700, 0.96954000, 0.96412900), vec3(0.97125200, 0.97336800, 0.96858400), vec3(0.97535800, 0.97719100, 0.97304800), vec3(0.97946400, 0.98100700, 0.97752000), vec3(0.98357000, 0.98481800, 0.98200000), vec3(0.98767700, 0.98862200, 0.98648800), vec3(0.99178400, 0.99242100, 0.99098400), vec3(0.99589200, 0.99621300, 0.99548800), vec3(1.00000000, 1.00000000, 1.00000000) ); /* * Chromaticities for RGB primaries */ // CIE 1931 RGB const mat3 primariesCie = Primaries( 0.72329, 0.27671, 0.28557, 0.71045, 0.15235, 0.02 ); // Identity RGB const mat3 primariesIdentity = mat3(1.0); // Original 1953 NTSC primaries const mat3 primariesNtsc = Primaries( 0.67, 0.33, 0.21, 0.71, 0.14, 0.08 ); // Never-popular and antiquated 'HDTV' primaries based mostly on 1953 NTSC const mat3 primaries240m = Primaries( 0.67, 0.33, 0.21, 0.71, 0.15, 0.06 ); // European Broadcasting Union primaries for SDTV and Rec. 601 (625 lines) const mat3 primariesEbu = Primaries( 0.64, 0.33, 0.29, 0.6, 0.15, 0.06 ); // P22 Phosphor primaries (allegedly; only found one source) // Used by older versions of SMPTE-C, before specific chromaticities were given const mat3 primariesP22 = Primaries( 0.61, 0.342, 0.298, 0.588, 0.151, 0.064 ); // Modern day SMPTE-C primaries, used in modern NTSC and Rec. 601 (525 lines) const mat3 primariesSmpteC = Primaries( 0.63, 0.34, 0.31, 0.595, 0.155, 0.07 ); // Alleged primaries for old Sony TVs with a very blue whitepoint const mat3 primariesSony = Primaries( 0.625, 0.34, 0.28, 0.595, 0.155, 0.07 ); // Rec. 709 (HDTV) and sRGB primaries const mat3 primaries709 = Primaries( 0.64, 0.33, 0.3, 0.6, 0.15, 0.06 ); // Adobe RGB primaries const mat3 primariesAdobe = Primaries( 0.64, 0.33, 0.21, 0.71, 0.15, 0.06 ); // DCI-P3 primaries const mat3 primariesP3 = Primaries( 0.68, 0.32, 0.265, 0.69, 0.15, 0.06 ); // Rec. 2020 UHDTV primaries const mat3 primaries2020 = Primaries( 0.708, 0.292, 0.17, 0.797, 0.131, 0.046 ); // Approximate Google Pixel primaries /*const mat3 primariesPixel = Primaries( 0.66, 0.34, 0.228, 0.719, 0.144, 0.04 );*/ // Actual colorimeter reasons for Google Pixel /*const mat3 primariesPixel = Primaries( 0.6582, 0.3418, 0.2337, 0.7129, 0.1425, 0.0428 );*/ /*const mat3 primariesPixel = Primaries( 0.6565, 0.3435, 0.2374, 0.7146, 0.1461, 0.0511 );*/ /*const mat3 primariesPixel = Primaries( 0.6647, 0.3341, 0.2381, 0.7098, 0.1434, 0.0432 );*/ /*const mat3 primariesPixel = Primaries( 0.6586, 0.3414, 0.2341, 0.7131, 0.1423, 0.0430 );*/ /*const mat3 primariesPixel = Primaries( 0.6586, 0.3414, 0.2348, 0.7127, 0.1423, 0.0431 );*/ const mat3 primariesPixel = Primaries( 0.6583, 0.3417, 0.2358, 0.7120, 0.1421, 0.0433 ); // If the HUNT XYZ->LMS matrix were expressed instead as // chromaticity coordinates, these would be them const mat3 primariesHunt = Primaries( 0.8374, 0.1626, 2.3, -1.3, 0.168, 0.0 ); // If the CIECAM02 XYZ->LMS matrix were expressed instead as // chromaticity coordinates, these would be them const mat3 primariesCiecam02 = Primaries( 0.711, 0.295, -1.476, 2.506, 0.144, 0.057 ); // LMS primaries as chromaticity coordinates, computed from // http://www.cvrl.org/ciepr8dp.htm, and // http://www.cvrl.org/database/text/cienewxyz/cie2012xyz2.htm /*const mat3 primariesLms = Primaries( 0.73840145, 0.26159855, 1.32671635, -0.32671635, 0.15861916, 0.0 );*/ // Same as above, but in fractional form (much more precise) const mat3 primariesLms = Primaries( 194735469.0/263725741.0, 68990272.0/263725741.0, 141445123.0/106612934.0, -34832189.0/106612934.0, 36476327.0/229961670.0, 0.0 ); /* * Chromaticities for white points */ // Standard Illuminant A const vec3 whiteA = White(0.44757, 0.40745); // Standard Illuminant C. White point for the original 1953 NTSC color system const vec3 whiteC = White(0.310063, 0.316158); // Standard illuminant E (also known as the 'equal energy' white point) const vec3 whiteE = White(1.0/3.0, 1.0/3.0); // Alleged whitepoint to use with the P22 phosphors (D65 might be more proper) const vec3 whiteP22 = White(0.313, 0.329); // Standard Illuminant D70 const vec3 whiteD75 = White(0.29902, 0.31485); // Standard Illuminant D70 const vec3 whiteD70 = White(0.3053, 0.3215); // Standard illuminant D65. Note that there are more digits here than specified // in either sRGB or Rec 709, so in some cases results may differ from other // software. Color temperature is roughly 6504 K (originally 6500K, but complex // science stuff made them realize that was innaccurate) const vec3 whiteD65 = White(0.312713, 0.329016); // Standard Illuminant D58 const vec3 whiteD58 = White(0.3258, 0.3415); // Standard illuminant D50. Just included for the sake of including it. Content // for Rec. 709 and sRGB is recommended to be produced using a D50 whitepoint. // For the same reason as D65, the color temperature is 5003 K instead of 5000 K const vec3 whiteD50 = White(0.34567, 0.35850); // Standard Illuminant D45. Daylight simulator for 4500K temperature white const vec3 whiteD45 = White(0.3621, 0.3709); // Standard Illuminant D40. Daylight simulator for 4000K temperature white const vec3 whiteD40 = White(0.3823, 0.3838); // Very blue white point for old Sony televisions. Color temperature of 9300 K. // Use with the 'primariesSony' RGB primaries defined above const vec3 whiteSony = White(0.283, 0.298); // White point for DCI-P3's theater variant const vec3 whiteP3 = White(0.314, 0.351); // Approximate Google Pixel white point //const vec3 whitePixel = White(0.299, 0.324); //const vec3 whitePixel = White(0.312, 0.334); //const vec3 whitePixel = White(0.3070, 0.3390); // Actual colorimeter readings for Google Pixel //const vec3 whitePixel = White(0.3009, 0.3236); //const vec3 whitePixel = White(0.3100, 0.3390); //const vec3 whitePixel = White(0.3027, 0.3179); const vec3 whitePixel = White(0.3008, 0.3247); //const vec3 whitePixel = White(0.3033, 0.3262); // Bedroom LED ceiling light const vec3 whiteRoom = White(0.3946, 0.3774); //const vec3 whiteRoom = White(0.4103, 0.38774); //const vec3 whiteRoom = White(0.418743, 0.391503); //const vec3 whiteRoom = White(0.418986, 0.391673); // Bathroom lighting (CFL) const vec3 whiteCfl = White(0.3867, 0.3889); // Bedside lamp (LED) const vec3 whiteLamp = White(0.346729, 0.363566); // Approximate theater light const vec3 whiteTheater = White(0.42, 0.31); /* * Gamma curve parameters */ // Linear gamma const transfer gam10 = transfer(vec3(1), vec3(0), vec3(1), vec3(0), vec3(0)); // Square gamma const transfer gam20 = transfer(vec3(2), vec3(0), vec3(1), vec3(0), vec3(0)); // Gamma of 2.2; not linear near 0. Was defined abstractly to be used by early // NTSC systems, before SMPTE 170M was modified to specify a more exact curve const transfer gam22 = transfer(vec3(2.2), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); // Gamma of 1.8; not linear near 0. Used by older Macintosh computers const transfer gam18 = transfer(vec3(1.8), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); // Gamma of 2.4; not linear near 0. Seems a popular choice among some people // online, so I included it. I don't think any standard uses this const transfer gam24 = transfer(vec3(2.4), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); // Gamma of 2.5; not linear near 0. Approximately what old Sony TVs used const transfer gam25 = transfer(vec3(2.5), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); // Gamma of 2.8; not linear near 0. Loosely defined gamma for European SDTV const transfer gam28 = transfer(vec3(2.8), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); // Modern SMPTE 170M, as well as Rec. 601, Rec. 709, and a rough approximation // for Rec. 2020 content as well. Do not use with Rec. 2020 if you work with // high bit depths! const transfer gam170m = transfer(vec3(1.0/0.45), vec3(0.099), vec3(4.5), vec3(0.0812), vec3(0.018)); // More precise version of the above for high but depth Rec. 2020 const transfer gam2020 = Transfer(vec3(1.0/0.45), vec3(0.099)); // SMPTE 240M const transfer gam240m = transfer(vec3(1.0/0.45), vec3(0.1115), vec3(4.0), vec3(0.0913), vec3(0.0228)); // Gamma for sRGB. Besides being full-range (0-255 values), this is the only // difference between sRGB and Rec. 709. const transfer gamSrgb = transfer(vec3(2.4), vec3(0.055), vec3(12.92), vec3(0.04045), vec3(0.0031308)); // Same as above, but calculated for high not depth const transfer gamSrgbHigh = Transfer(vec3(2.4), vec3(0.055)); // Gamma for the CIE L*a*b* Lightness scale const transfer gamLab = transfer(vec3(3.0), vec3(0.16), vec3(243.89/27.0), vec3(0.08), vec3(216.0/24389.0)); // Approximate Google Pixel display gamma //const transfer gamPixel = transfer(vec3(2.27, 2.32, 2.30), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); //const transfer gamPixel = transfer(vec3(2.22, 2.27, 2.25), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); const transfer gamPixel = transfer(vec3(2.247), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); // Some self-made approximations //const transfer gamTest = transfer(vec3(2.47), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); //const transfer gamTest = transfer(vec3(2.44, 2.495, 2.473), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); //const transfer gamTest = Transfer(vec3(2.45), vec3(0.01)); const transfer gamTest = Transfer(vec3(2.44, 2.495, 2.473)/**1.05*/, vec3(0.0/*1*/)); // Gamma that the LUT is calibrated for const transfer gamCal = transfer(vec3(2.23, 2.22, 2.22), vec3(0.0), vec3(1.0), vec3(0.0), vec3(0.0)); /* * RGB Colorspaces */ // CIE 1931 RGB const rgb_space Cie1931 = rgb_space(primariesCie, whiteE, gam10); // Identity RGB const rgb_space Identity = rgb_space(primariesIdentity, whiteE, gam10); // Original 1953 NTSC const rgb_space Ntsc = rgb_space(primariesNtsc, whiteC, gam22); // Mostly unused and early HDTV standard (SMPTE 240M) const rgb_space Smpte240m = rgb_space(primaries240m, whiteD65, gam22); // European Broadcasting Union SDTV const rgb_space Ebu = rgb_space(primariesEbu, whiteD65, gam28); // Original, imprecise colorspace for NTSC after 1987 (probably incorrect) const rgb_space SmpteC = rgb_space(primariesP22, whiteD65, gam22); // Modern SMPTE "C" colorimetry const rgb_space Smpte170m = rgb_space(primariesSmpteC, whiteD65, gam170m); // Old Sony displays using high temperature white point const rgb_space Sony = rgb_space(primariesSony, whiteSony, gam25); // Rec. 709 (HDTV) const rgb_space Rec709 = rgb_space(primaries709, whiteD65, gam170m); // sRGB (mostly the same as Rec. 709, but different gamma and full range values) const rgb_space Srgb = rgb_space(primaries709, whiteD65, gamSrgb); // Adobe RGB const rgb_space Adobe = rgb_space(primariesAdobe, whiteD65, gam22); // Rec. 2020 const rgb_space Rec2020 = rgb_space(primaries2020, whiteD65, gam170m); // My Google Pixel const rgb_space Pixel = rgb_space(primariesPixel, whitePixel, gamCal); // Hunt primaries, balanced against equal energy white point const rgb_space HuntRgb = rgb_space(primariesHunt, whiteE, gam10); // CIE CAM 2002 primaries, balanced against equal energy white point const rgb_space Ciecam02Rgb = rgb_space(primariesCiecam02, whiteE, gam10); // Lms primaries, balanced against equal energy white point const rgb_space LmsRgb = rgb_space(primariesLms, whiteE, gam10); /* * Settings */ // Choose RGB colorspace for the display const rgb_space inSpace = rgb_space(primaries709, whiteD50, gam170m); const rgb_space outSpace = Pixel; /* WARNING: I DELETED HALF OR MORE OF THE CODE AT THIS POINT BY ACCIDENT. DO NOT TAKE SERIOUSLY. Edit: I think I managed to get all of it back to how it should be. Still, regard this section with some caution. */ const vec3 whiteCameraFr = whiteRoom; const vec3 whiteCameraTo = whiteCameraFr; const float facFr = clamp((Cct(whiteCameraFr) - Cct(whiteA))/(Cct(whiteD65) - Cct(whiteA)), 0.0, 1.0); const float facTo = clamp((Cct(whiteCameraTo) - Cct(whiteA))/(Cct(whiteD65) - Cct(whiteA)), 0.0, 1.0); const mat3 cameraFrMat = facFr*cameraMat1 + (1.0 - facFr)*cameraMat2; const mat3 cameraFrCal = facFr*cameraCal1 + (1.0 - facFr)*cameraCal2; const mat3 cameraFrFor = facFr*cameraFor1 + (1.0 - facFr)*cameraFor2; const mat3 cameraFrCon = diag(inverse(cameraFrCal)*cameraFrMat*Bright(whiteCameraFr)); const mat3 cameraFrRaw = cameraFrCal*/*cameraFrMat;*/cameraFrCon*inverse(cameraFrFor); const mat3 cameraToMat = facTo*cameraMat1 + (1.0 - facTo)*cameraMat2; const mat3 cameraToCal = facTo*cameraCal1 + (1.0 - facTo)*cameraCal2; const mat3 cameraToFor = facTo*cameraFor1 + (1.0 - facTo)*cameraFor2; const mat3 cameraToCon = diag(inverse(cameraToCal)*cameraToMat*Bright(whiteCameraTo)); const mat3 cameraToRaw = cameraToCal*/*cameraToMat;*/cameraToCon*inverse(cameraToFor); /* END OF ACCIDENTALLY DELETED PART OF THE CODE */ // Choose main XYZ->RAW conversion matrix from which others derive const mat3 rawMat = cameraToRaw; const mat3 toRaw = cameraFrRaw; const mat3 fromRaw = inverse(rawMat); // Color Appearance Model (CAM) white point const vec3 whiteCam = whiteD50; // Input CAM matrix const mat3 camMat1 = CIECAM97_1; const mat3 toCam1 = /*inverse(diag(camMat1*Bright(whiteCam)))**/camMat1; const mat3 fromCam1 = inverse(camMat1);//*diag(camMat1*Bright(whiteCam)); // Output CAM matrix const mat3 camMat2 = xyzToRgb(LmsRgb); const mat3 toCam2 = /*inverse(diag(camMat2*Bright(whiteCam)))**/camMat2; const mat3 fromCam2 = inverse(camMat2);//*diag(camMat2*Bright(whiteCam)); const mat3 aFrom = fromCam1*diag((toCam1*Bright(whiteCam))/(toCam1*Bright(inSpace.white)))*toCam1; const mat3 aTo = fromCam2*diag((toCam2*Bright(outSpace.white))/(toCam2*Bright(whiteCam)))*toCam2; const mat3 toXyz = aFrom*rgbToXyz(inSpace); const mat3 toRgb = xyzToRgb(outSpace);//*aTo; const mat3 whiteBalance = //diag((rawMat*Bright(inSpace.white))/(toRaw*Bright(outSpace.white)));/** //diag((rawMat*Bright(whiteCameraFr))/(rawMat*Bright(whiteCameraTo)))* //rawMat*inverse(toRaw)* diag((rawMat*Bright(whiteCameraFr))/(toRaw*Bright(whiteCam)));/**/ const mat3 transMat = fromRaw*whiteBalance*toRaw*toXyz; /* * Conversion Functions */ vec3 toLinear(vec3 color, transfer trc) { bvec3 cutoff = lessThan(color, trc.cutoffToLinear); bvec3 negCutoff = lessThanEqual(color, -1.0*trc.cutoffToLinear); vec3 higher = pow((color + trc.off)/(1.0 + trc.off), trc.power); vec3 lower = color/trc.slope; vec3 neg = -1.0*pow((color - trc.off)/(-1.0 - trc.off), trc.power); color = mix(higher, lower, cutoff); color = mix(color, neg, negCutoff); return color; } vec3 toGamma(vec3 color, transfer trc) { bvec3 cutoff = lessThan(color, trc.cutoffToGamma); bvec3 negCutoff = lessThanEqual(color, -1.0*trc.cutoffToGamma); vec3 higher = (1.0 + trc.off)*pow(color, 1.0/trc.power) - trc.off; vec3 lower = color*trc.slope; vec3 neg = (-1.0 - trc.off)*pow(-1.0*color, 1.0/trc.power) + trc.off; color = mix(higher, lower, cutoff); color = mix(color, neg, negCutoff); return color; } // Scales a color to the closest in-gamut representation of that color vec3 gamutScale(inout vec3 color, float luma) { float low = min(color.r, min(color.g, min(color.b, 0.0))); float high = max(color.r, max(color.g, max(color.b, 1.0))); float lowScale = low/(low - luma); float highScale = (high - 1.0)/(high - luma); float scale = max(lowScale, highScale); color += scale*(luma - color); return color; } vec3 convert(inout vec3 color) { // Y_b /*float backRelLuma = light;//18.0; // L_W const float whiteAbsLuma = 250.0;//445.0; // Y_w const float whiteRelLuma = 16.0; // L_A float adaptAbsLuma = backRelLuma*whiteAbsLuma/whiteRelLuma; // S_R const float surroundRatio = 0.18; // F const float factor = 0.9; // c const float impact = 0.59; // N_c const float induction = 0.95; float kFac = pow(1.0/(5.0*adaptAbsLuma + 1.0), 4.0); float lumAdaptFac = kFac*adaptAbsLuma + pow(1.0 - kFac, 2.0)/10.0*pow(adaptAbsLuma*5.0, 1.0/3.0); float degree = factor*(1.0 - (1.0/3.6)*pow(EULER, -(adaptAbsLuma + 42.0)/92.0));*/ // Convert to XYZ //color = toXyz*color; /*const mat3 conv = conversionMatrix(inSpace, outSpace, whiteD40, whiteD65, toRaw); color = conv*color;*/ /*color = toCam*rgbToXyz(inSpace)*color; color = ((toCam*whiteD50)/(toCam*whiteD50)*degree + 1.0 - degree)*color; color = inverse(toCam)*color;*/ // Convert to LMS //color = toCam*color; // Perform white balance //color = whiteBalance*color; // Convert back to XYZ //color = fromCam*color; // Simpler transformation color = transMat*color; // Resacale to New white point to keep colors in gamut mat3 newPrims = toRgb*transMat*mat3(1); vec3 newWhite = toRgb*transMat*vec3(1); color.rgb /= max(newPrims[0].r, max(newPrims[0].g, max(newPrims[0].b, max(newPrims[1].r, max(newPrims[1].g, max(newPrims[1].b, max(newPrims[2].r, max(newPrims[2].g, max(newPrims[2].b, max(newWhite.r, max(newWhite.g, newWhite.b)))))))))));/**/ // Brightness adjustment //color *= 0.6; // Convert to RGB float luma = color.y; color = toRgb*color; color = gamutScale(color, luma); return color; } /* * Functions for Noise and Dithering */ // Based on https://www.shadertoy.com/view/4tXyWN vec3 hash(vec3 seed) { uvec3 x = uvec3(seed); uvec3 q = 1103515245U * ( (x>>1U) ^ (x.zyx ) ); uint n = 1103515245U * ( (q.x ) ^ (q.y>>3U) ^ (q.z<<3U) ); return vec3(float(n) * (1.0/float(0xffffffffU))); } // Dither between two colors by 'amount' vec3 dither(vec3 color1, vec3 color2, vec3 amount) { vec3 seed = vec3(gl_FragCoord.xy, fract(time)*1024.0); bvec3 cmix = bvec3(round(amount + hash(seed) - 0.5)); return mix(color1, color2, cmix); } void main() { vec2 texRes = vec2(textureSize(cam, 0)); //vec2 uv = gl_FragCoord.xy/resolution; vec2 texCoord = gl_FragCoord.xy/texRes.yx; texCoord -= 0.5; texCoord *= cameraOrientation; texCoord += 0.5; //vec3 color = floor(vec3(uv.x*256.0))/255.0; vec3 color = texture(cam, texCoord).rgb; // Fix incorrect scaling of YUV values by Android color = BT709*color; color *= vec3(219.0/255.0, vec2(224.0/255.0)); color.r += 16.0/255.0; color = BT709_INV*color; // Old color correction (doesn't use YUV) //color *= 219.0/255.0; //color += 16.0/255.0; color = toLinear(color, inSpace.trc); color = convert(color); //vec3 colorLin = color; color = toGamma(color, outSpace.trc); // Prevent out of bounds LUT access color = clamp(color, vec3(0), vec3(1)); //colorLin = clamp(colorLin, vec3(0), vec3(1)); // Perform display calibration using 1D LUT color *= 255.0; vec3 low = floor(color); //vec3 med = round(color); vec3 high = ceil(color); vec3 colorFract = fract(color); //vec3 lowLin = toLinear(low/255.0, outSpace.trc); //vec3 medLin = toLinear(med/255.0, outSpace.trc); //vec3 highLin = toLinear(high/255.0, outSpace.trc); //vec3 fractLin = (colorLin - lowLin)/(highLin - lowLin); ivec3 lutLow = ivec3(low); //ivec3 lutMed = ivec3(med); ivec3 lutHigh = ivec3(high); vec3 colorLow = vec3(lut[lutLow.r].r, lut[lutLow.g].g, lut[lutLow.b].b); //vec3 colorMed = vec3(lut[lutMed.r].r, // lut[lutMed.g].g, // lut[lutMed.b].b); vec3 colorHigh = vec3(lut[lutHigh.r].r, lut[lutHigh.g].g, lut[lutHigh.b].b); color = colorLow; color += colorFract*(colorHigh - colorLow); colorLow = floor(color*256.0)/255.0; colorHigh = ceil(color*256.0)/255.0; //colorFract = fract(color*255.0); colorFract = (color - colorLow)/(colorHigh - colorLow); color = dither(colorLow, colorHigh, colorFract); /*color.r = lut[colorLow.r].r + ( lut[colorHigh.r].r - lut[colorLow.r].r )*colorFract.r; color.g = lut[colorLow.g].g + ( lut[colorHigh.g].g - lut[colorLow.g].g )*colorFract.g; color.b = lut[colorLow.b].b + ( lut[colorHigh.b].b - lut[colorLow.b].b )*colorFract.b;/**/ gl_FragColor = vec4(color, 1); }