1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
/*
* Stellarium
* Copyright (C) 2002-2022 Fabien Chereau and Stellarium contributors
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/
const highp float pi = 3.1415926535897931;
const highp float ln10 = 2.3025850929940459;
uniform highp float alphaWaOverAlphaDa;
uniform highp float oneOverGamma;
uniform highp float term2TimesOneOverMaxdLpOneOverGamma;
uniform highp float term2TimesOneOverMaxdL;
uniform highp float brightnessScale; // Only the atmosphere fader value [0...1], i.e. drawn or not, or in transition.
uniform bool doSRGB;
uniform bool flagUseTmGamma;
float applyTMAndGamma(highp float Y)
{
if (flagUseTmGamma)
{
// Y = std::pow(adaptLuminanceScaled(Y), oneOverGamma);
return pow(abs(Y*pi*1e-4), alphaWaOverAlphaDa*oneOverGamma) * term2TimesOneOverMaxdLpOneOverGamma;
}
else
{
// Y = adaptLuminanceScaled(Y);
return pow(abs(Y*pi*1e-4), alphaWaOverAlphaDa) * term2TimesOneOverMaxdL;
}
}
vec3 xyYToRGB(highp float x, highp float y, highp float Y)
{
///////////////////////////////////////////////////////////////////////////
// Now we have the xyY components, need to convert to RGB
vec3 color = vec3(1,0,1);
// 1. Hue conversion
// if log10Y>0.6, photopic vision only (with the cones, colors are seen)
// else scotopic vision if log10Y<-2 (with the rods, no colors, everything blue),
// else mesopic vision (with rods and cones, transition state)
if (Y <= 0.01)
{
// special case for s = 0 (x=0.25, y=0.25)
Y *= 0.5121445;
Y = applyTMAndGamma(Y);
color = vec3(0.787077, 0.9898434, 1.9256125) * Y * brightnessScale;
}
else
{
if (Y<3.9810717055349722)
{
// Compute s, ratio between scotopic and photopic vision
float op = (log(Y)/ln10 + 2.)/2.6;
float s = op * op *(3. - 2. * op);
// Do the blue shift for scotopic vision simulation (night vision) [3]
// The "night blue" is x,y(0.25, 0.25)
x = (1. - s) * 0.25 + s * x; // Add scotopic + photopic components
y = (1. - s) * 0.25 + s * y; // Add scotopic + photopic components
// Take into account the scotopic luminance approximated by V [3] [4]
float V = Y * (1.33 * (1. + y / x + x * (1. - x - y)) - 1.68);
Y = 0.4468 * (1. - s) * V + s * Y;
}
// 2. Adapt the luminance value and scale it to fit in the RGB range [2]
Y = applyTMAndGamma(Y);
// Convert from xyY to XYZ
highp vec3 XYZ = vec3(x * Y / y, Y, (1. - x - y) * Y / y);
highp mat3 XYZ2RGB;
if(doSRGB)
{
// Use the XYZ to sRGB matrix which uses a D65 reference white
// Ref: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
XYZ2RGB = mat3(vec3( 3.2404542, -0.9692660, 0.0556434),
vec3(-1.5371385, 1.8760108, -0.2040259),
vec3(-0.4985314, 0.0415560, 1.0572252));
}
else
{
// Use a XYZ to Adobe RGB (1998) matrix which uses a D65 reference white. Use values from same source:
XYZ2RGB = mat3(vec3( 2.0413690, -0.9692660, 0.0134474),
vec3(-0.5649464, +1.8760108, -0.1183897),
vec3(-0.3446944, +0.0415560, +1.0154096));
}
color = XYZ2RGB * XYZ * brightnessScale;
}
return flagUseTmGamma ? color : pow(abs(color), vec3(oneOverGamma));
}
|