File: xyYToRGB.glsl

package info (click to toggle)
stellarium 24.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 911,396 kB
  • sloc: ansic: 317,377; cpp: 204,602; xml: 48,590; javascript: 26,348; python: 1,254; perl: 1,108; sh: 207; makefile: 190; pascal: 169
file content (106 lines) | stat: -rw-r--r-- 3,847 bytes parent folder | download
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));
}