diff --git a/README.md b/README.md
index 4b19f6ed..28b2e0ad 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# [Aladin Lite](https://aladin.u-strasbg.fr/AladinLite)
+# [Aladin Lite](https://aladin.cds.unistra.fr/AladinLite)
**An astronomical HiPS visualizer in the browser**
@@ -8,14 +8,14 @@ See [A&A 578, A114 (2015)](https://arxiv.org/abs/1505.02291) and [IVOA HiPS Reco
Aladin Lite is built to be easily embeddable in any web page. It powers astronomical portals like [ESASky](https://sky.esa.int/), [ESO Science Archive portal](http://archive.eso.org/scienceportal/) and [ALMA Portal](https://almascience.eso.org/asax/).
-More details on [Aladin Lite documentation page](http://aladin.u-strasbg.fr/AladinLite/doc/).
+More details on [Aladin Lite documentation page](http://aladin.cds.unistra.fr/AladinLite/doc/).
A new [API technical documentation](https://cds-astro.github.io/aladin-lite/) is now available.
[](https://github.com/cds-astro/aladin-lite/actions/workflows/test.yml)
[](https://cds-astro.github.io/aladin-lite)
[](https://aladin.cds.unistra.fr/AladinLite/doc/release/)
-Try Aladin Lite [here](https://aladin.u-strasbg.fr/AladinLite).
+Try Aladin Lite [here](https://aladin.cds.unistra.fr/AladinLite).
Aladin Lite is made possible thanks to pure Rust core libraries:
* [cdshealpix](https://github.com/cds-astro/cds-healpix-rust) - for HEALPix projection and unprojection to/from sky coordinates
diff --git a/package.json b/package.json
index 187c47da..780dfa46 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "homepage": "https://aladin.u-strasbg.fr/",
+ "homepage": "https://aladin.cds.unistra.fr/",
"name": "aladin-lite",
"type": "module",
"version": "3.7.2-beta",
diff --git a/src/core/src/app.rs b/src/core/src/app.rs
index 224c69ac..0aa5e10a 100644
--- a/src/core/src/app.rs
+++ b/src/core/src/app.rs
@@ -87,6 +87,7 @@ pub struct App {
time_start_dragging: Time,
time_mouse_high_vel: Time,
dragging: bool,
+ vel_history: Vec,
prev_cam_position: Vector3,
//prev_center: Vector3,
@@ -208,6 +209,7 @@ impl App {
let browser_features_support = BrowserFeaturesSupport::new();
+ let vel_history = vec![];
Ok(App {
gl,
//ui,
@@ -244,6 +246,7 @@ impl App {
time_start_dragging,
time_mouse_high_vel,
dragging,
+ vel_history,
prev_cam_position,
out_of_fov,
@@ -1538,7 +1541,16 @@ impl App {
let dx = crate::math::vector::dist2(&from_mouse_pos, &to_mouse_pos).sqrt();
self.dist_dragging += dx;
+ //let now = Time::now();
+ //let dragging_duration = (now - self.time_start_dragging).as_secs();
+ //let dragging_vel = self.dist_dragging / dragging_duration;
+
+ // 1. Use smoothed velocity instead of instantaneous velocity
let dv = dx / (Time::now() - self.camera.get_time_of_last_move()).as_secs();
+ self.vel_history.push(dv);
+ if self.vel_history.len() > 5 {
+ self.vel_history.remove(0);
+ }
if dv > 10000.0 {
self.time_mouse_high_vel = Time::now();
@@ -1587,15 +1599,18 @@ impl App {
}
let now = Time::now();
- let dragging_duration = (now - self.time_start_dragging).as_secs();
- let dragging_vel = self.dist_dragging / dragging_duration;
+ let avg_vel = self.vel_history.iter().copied().sum::() / self.vel_history.len() as f32;
- // Detect if there has been a recent acceleration
- // It is also possible that the dragging time is too short and if it is the case, trigger the inertia
- let recent_acceleration = (Time::now() - self.time_mouse_high_vel).as_secs() < 0.1
- || (Time::now() - self.time_start_dragging).as_secs() < 0.1;
+ // 2. Clamp minimum + maximum velocities
+ let min_vel = 1000.0; // tweak
- if dragging_vel < 2000.0 && !recent_acceleration {
+ // 3. Better condition for “recent acceleration”
+ let t_since_drag = (now - self.time_start_dragging).as_secs();
+ let t_since_accel = (now - self.time_mouse_high_vel).as_secs();
+
+ let inertia_trigger =
+ avg_vel > min_vel || ((t_since_drag < 0.15) || (t_since_accel < 0.15));
+ if !inertia_trigger {
return;
}
@@ -1605,10 +1620,8 @@ impl App {
let center = self.camera.get_center();
let axis = self.prev_cam_position.cross(*center).normalize();
- //let delta_time = ((now - time_of_last_move).0 as f64).max(1.0);
let delta_angle = math::vector::angle3(&self.prev_cam_position, center).to_radians();
- let ampl = delta_angle * (dragging_vel as f64) * 5e-3;
- //let ampl = (dragging_vel * 0.01) as f64;
+ let ampl = (delta_angle * avg_vel as f64) * 5e-3;
self.inertia = Some(Inertia::new(ampl.to_radians(), axis, self.north_up))
}
diff --git a/src/core/src/inertia.rs b/src/core/src/inertia.rs
index 8cc98d1a..44f13a19 100644
--- a/src/core/src/inertia.rs
+++ b/src/core/src/inertia.rs
@@ -27,6 +27,7 @@ impl Inertia {
}
}
+ /*
pub fn apply(&mut self, camera: &mut CameraViewPort, proj: &ProjectionType, _dt: DeltaTime) {
let t = ((Time::now() - self.time_start).as_millis() / 1000.0) as f64;
// Undamped angular frequency of the oscillator
@@ -46,6 +47,24 @@ impl Inertia {
let fov = start_fov * (1_f32 - alpha) + goal_fov * alpha;*/
camera.apply_axis_rotation(&self.axis, self.speed.to_angle(), proj);
+ if self.north_up {
+ camera.set_position_angle(0.0.to_angle(), proj);
+ }
+ }*/
+
+ pub fn apply(&mut self, camera: &mut CameraViewPort, proj: &ProjectionType, _dt: DeltaTime) {
+ let t = ((Time::now() - self.time_start).as_millis() / 1000.0) as f64;
+ // Initial angular velocity
+ let v0 = self.ampl * 0.5;
+
+ // Friction coefficient (tweak this)
+ let damping = 2.5;
+
+ // Exponential decay of angular velocity
+ self.speed = (v0 * (-damping * t).exp()).min(3.0);
+
+ camera.apply_axis_rotation(&self.axis, self.speed.to_angle(), proj);
+
if self.north_up {
camera.set_position_angle(0.0.to_angle(), proj);
}
diff --git a/src/core/src/shaders.rs b/src/core/src/shaders.rs
index 024c45af..05133497 100644
--- a/src/core/src/shaders.rs
+++ b/src/core/src/shaders.rs
@@ -3,135 +3,264 @@ use std::collections::HashMap;
pub fn get_all() -> HashMap<&'static str, &'static str> {
let mut out = HashMap::new();
out.insert(
- r"hips_rasterizer_raster.vert",
+ r"line_inst_ndc.vert",
r#"#version 300 es
precision highp float;
+layout (location = 0) in vec2 p_a;
+layout (location = 1) in vec2 p_b;
+layout (location = 2) in vec2 vertex;
-layout (location = 0) in vec3 xyz;
-layout (location = 1) in vec3 uv_start;
-layout (location = 2) in vec3 uv_end;
-layout (location = 3) in float time_tile_received;
+out vec2 l;
-out vec3 frag_uv_start;
-out vec3 frag_uv_end;
-out float frag_blending_factor;
+uniform float u_width;
+uniform float u_height;
+uniform float u_thickness;
-uniform mat3 inv_model;
-uniform vec2 ndc_to_clip;
-uniform float czf;
-uniform float current_time;
+void main() {
+ vec2 x_b = p_b - p_a;
+ vec2 y_b = normalize(vec2(-x_b.y, x_b.x));
-const float PI = 3.141592653589793;
-const float SQRT_2 = 1.41421356237309504880168872420969808;
+ float ndc2pix = 2.0 / u_width;
-vec2 w2c_sin(vec3 p) {
- vec2 q = vec2(-p.x, p.y);
- return p.z >= 0.f ? q : normalize(q);
+ vec2 p = p_a + x_b * vertex.x + (u_thickness + 2.0) * y_b * vertex.y * vec2(1.0, u_width/u_height) * ndc2pix;
+ gl_Position = vec4(p, 0.f, 1.f);
+ l = vec2(0.0, vertex.y);
+}"#,
+ );
+ out.insert(
+ r"fits_i16.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2D;
+precision mediump int;
+
+out vec4 out_frag_color;
+in vec2 frag_uv;
+
+uniform sampler2D tex;
+uniform float opacity;
+
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
}
-vec2 w2c_sin_no_backface(vec3 p) {
- return vec2(-p.x, p.y);
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
}
-vec2 w2c_ait(vec3 p) {
- float r = length(p.zx);
- float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
- w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
- float y2d = p.y / w;
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
- float x2d = 0.0;
- if (abs(p.x) < 5e-3) {
- float x_over_r = p.x/r;
- x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
} else {
- w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
- x2d = sign(-p.x) * w;
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
}
- return vec2(x2d * 0.5, y2d) / SQRT_2;
-}
-const float eps = 1.25e-8;
-const int n_iter = 100;
-
-float newton_solve(float z) {
- float cte = PI * z;
- float x = 2.0 * asin(z);
- float f = x + sin(x) - cte;
- int i = 0;
- while (abs(f) > eps && i < n_iter) {
- x -= f / (1.0 + cos(x));
- f = x + sin(x) - cte;
- i += 1;
- }
-
- return 0.5 * x;
+ return value;
}
-vec2 w2c_mol(vec3 p) {
- float g = newton_solve(p.y);
-
- float sg = sin(g);
- float cg = cos(g);
- return vec2((atan(-p.x, p.z) * cg) / PI, sg);
-}
-vec2 w2c_tan(vec3 p) {
- p.z = max(p.z, 1e-2);
- return vec2(-p.x, p.y) / (p.z*PI);
-}
-vec2 w2c_stg(vec3 p) {
- float w = (1.0 + p.z) * 0.5;
- return vec2(-p.x, p.y) / (PI * w);
-}
-vec2 w2c_zea(vec3 p) {
- float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
- return vec2(-p.x, p.y) * 0.5 / w;
-}
-vec2 w2c_mer(vec3 p) {
- return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
}
-vec3 lonlat2xyz(vec2 lonlat) {
- float t = lonlat.x;
- float tc = cos(t);
- float ts = sin(t);
- float d = lonlat.y;
- float dc = cos(d);
- float ds = sin(d);
- return vec3(dc * ts, ds, dc * tc);
+
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
}
-uniform int u_proj;
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
-vec2 proj(vec3 p) {
- if (u_proj == 0) {
- return w2c_tan(p);
- } else if (u_proj == 1) {
- return w2c_stg(p);
- } else if (u_proj == 2) {
- return w2c_sin(p);
- } else if (u_proj == 3) {
- return w2c_zea(p);
- } else if (u_proj == 4) {
- return w2c_ait(p);
- } else if (u_proj == 5) {
- return w2c_mol(p);
- } else {
- return w2c_mer(p);
- }
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uv2c_f32(vec2 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uv2c_i32(vec2 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uv2c_i16(vec2 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uv2c_u8(vec2 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
}
void main() {
- vec3 p_w = inv_model * xyz;
- vec2 p_clip = proj(p_w);
+ vec2 uv = frag_uv;
+ uv.y = 1.0 - uv.y;
- vec2 p_ndc = p_clip / (ndc_to_clip * czf);
- gl_Position = vec4(p_ndc, 0.0, 1.0);
+ out_frag_color = uv2c_i16(frag_uv);
+ out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"hips_raytracer_backcolor.vert",
+ r#"#version 300 es
+precision lowp float;
+precision mediump int;
- frag_uv_start = uv_start;
- frag_uv_end = uv_end;
- frag_blending_factor = min((current_time - time_tile_received) / 200.0, 1.0);
+layout (location = 0) in vec2 pos_clip_space;
+
+uniform vec2 ndc_to_clip;
+uniform float czf;
+
+void main() {
+ gl_Position = vec4(pos_clip_space / (ndc_to_clip * czf), 0.0, 1.0);
+}"#,
+ );
+ out.insert(
+ r"colormaps_colormap.vert",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2D;
+
+layout (location = 0) in vec2 position;
+layout (location = 1) in vec2 uv;
+
+out vec2 out_uv;
+
+void main() {
+ gl_Position = vec4(position, 0.f, 1.f);
+ out_uv = uv;
}"#,
);
out.insert(
@@ -400,16 +529,144 @@ void main() {
}"#,
);
out.insert(
- r"hips3d_raster.vert",
+ r"catalogs_mollweide.vert",
r#"#version 300 es
precision lowp float;
+layout (location = 0) in vec2 offset;
+layout (location = 1) in vec2 uv;
+layout (location = 2) in vec3 center;
-layout (location = 0) in vec2 lonlat;
-layout (location = 1) in vec3 uv;
-
-out vec3 frag_uv;
-
+uniform float current_time;
uniform mat3 inv_model;
+
+uniform vec2 ndc_to_clip;
+uniform float czf;
+uniform vec2 kernel_size;
+
+out vec2 out_uv;
+out vec3 out_p;
+
+const float PI = 3.141592653589793;
+const float SQRT_2 = 1.41421356237309504880168872420969808;
+
+vec2 w2c_sin(vec3 p) {
+ vec2 q = vec2(-p.x, p.y);
+ return p.z >= 0.f ? q : normalize(q);
+}
+
+vec2 w2c_sin_no_backface(vec3 p) {
+ return vec2(-p.x, p.y);
+}
+
+vec2 w2c_ait(vec3 p) {
+ float r = length(p.zx);
+ float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
+ w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
+ float y2d = p.y / w;
+
+ float x2d = 0.0;
+ if (abs(p.x) < 5e-3) {
+ float x_over_r = p.x/r;
+ x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
+ } else {
+ w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
+ x2d = sign(-p.x) * w;
+ }
+
+ return vec2(x2d * 0.5, y2d) / SQRT_2;
+}
+const float eps = 1.25e-8;
+const int n_iter = 100;
+
+float newton_solve(float z) {
+ float cte = PI * z;
+ float x = 2.0 * asin(z);
+ float f = x + sin(x) - cte;
+ int i = 0;
+ while (abs(f) > eps && i < n_iter) {
+ x -= f / (1.0 + cos(x));
+ f = x + sin(x) - cte;
+ i += 1;
+ }
+
+ return 0.5 * x;
+}
+
+vec2 w2c_mol(vec3 p) {
+ float g = newton_solve(p.y);
+
+ float sg = sin(g);
+ float cg = cos(g);
+ return vec2((atan(-p.x, p.z) * cg) / PI, sg);
+}
+vec2 w2c_tan(vec3 p) {
+ p.z = max(p.z, 1e-2);
+ return vec2(-p.x, p.y) / (p.z*PI);
+}
+vec2 w2c_stg(vec3 p) {
+ float w = (1.0 + p.z) * 0.5;
+ return vec2(-p.x, p.y) / (PI * w);
+}
+vec2 w2c_zea(vec3 p) {
+ float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
+ return vec2(-p.x, p.y) * 0.5 / w;
+}
+vec2 w2c_mer(vec3 p) {
+ return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
+}
+
+vec3 lonlat2xyz(vec2 lonlat) {
+ float t = lonlat.x;
+ float tc = cos(t);
+ float ts = sin(t);
+
+ float d = lonlat.y;
+ float dc = cos(d);
+ float ds = sin(d);
+
+ return vec3(dc * ts, ds, dc * tc);
+}
+
+uniform int u_proj;
+
+vec2 proj(vec3 p) {
+ if (u_proj == 0) {
+ return w2c_tan(p);
+ } else if (u_proj == 1) {
+ return w2c_stg(p);
+ } else if (u_proj == 2) {
+ return w2c_sin(p);
+ } else if (u_proj == 3) {
+ return w2c_zea(p);
+ } else if (u_proj == 4) {
+ return w2c_ait(p);
+ } else if (u_proj == 5) {
+ return w2c_mol(p);
+ } else {
+ return w2c_mer(p);
+ }
+}
+
+
+void main() {
+ vec3 p = inv_model * center;
+
+ vec2 center_pos_clip_space = world2clip_mollweide(p);
+
+ vec2 pos_clip_space = center_pos_clip_space;
+ gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
+
+ out_uv = uv;
+ out_p = p;
+}"#,
+ );
+ out.insert(
+ r"moc_base.vert",
+ r#"#version 300 es
+precision highp float;
+layout (location = 0) in vec2 lonlat;
+
+uniform mat3 u_2world;
uniform vec2 ndc_to_clip;
uniform float czf;
@@ -516,43 +773,25 @@ vec2 proj(vec3 p) {
void main() {
vec3 p_xyz = lonlat2xyz(lonlat);
- vec3 p_w = inv_model * p_xyz;
- vec2 p_clip = proj(p_w.xyz);
+ vec3 p_w = u_2world * p_xyz;
+ vec2 p_clip = proj(p_w);
vec2 p_ndc = p_clip / (ndc_to_clip * czf);
- gl_Position = vec4(p_ndc, 0.0, 1.0);
-
- frag_uv = uv;
+ gl_Position = vec4(p_ndc, 0.f, 1.f);
}"#,
);
out.insert(
- r"hips_raytracer_backcolor.vert",
+ r"fits_f32.frag",
r#"#version 300 es
-precision lowp float;
-precision mediump int;
-
-layout (location = 0) in vec2 pos_clip_space;
-
-uniform vec2 ndc_to_clip;
-uniform float czf;
-
-void main() {
- gl_Position = vec4(pos_clip_space / (ndc_to_clip * czf), 0.0, 1.0);
-}"#,
- );
- out.insert(
- r"hips_rasterizer_u8.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2DArray;
-
-uniform sampler2DArray tex;
-
-in vec3 frag_uv_start;
-in vec3 frag_uv_end;
-in float frag_blending_factor;
+precision highp float;
+precision highp sampler2D;
+precision highp int;
out vec4 out_frag_color;
+in vec2 frag_uv;
+
+uniform sampler2D tex;
+uniform float opacity;
uniform float scale;
uniform float offset;
@@ -654,21 +893,6 @@ vec4 apply_tonal(vec4 color) {
k_gamma
);
}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
highp float decode_f32(highp vec4 rgba) {
highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
@@ -712,49 +936,6 @@ uint decode_u8(float r) {
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
vec4 val2c_f32(float x) {
float alpha = x * scale + offset;
@@ -776,343 +957,32 @@ vec4 val2c(float x) {
return apply_tonal(new_color);
}
-vec4 uvw2c_f32(vec3 uv) {
+vec4 uv2c_f32(vec2 uv) {
float val = decode_f32(texture(tex, uv).rgba*255.0);
return val2c_f32(val);
}
-vec4 uvw2c_i32(vec3 uv) {
+vec4 uv2c_i32(vec2 uv) {
float val = float(decode_i32(texture(tex, uv).rgba));
return val2c(val);
}
-vec4 uvw2c_i16(vec3 uv) {
+vec4 uv2c_i16(vec2 uv) {
float val = float(decode_i16(texture(tex, uv).rg));
return val2c(val);
}
-vec4 uvw2c_u8(vec3 uv) {
+vec4 uv2c_u8(vec2 uv) {
float val = float(decode_u8(texture(tex, uv).r));
return val2c(val);
}
-uniform float opacity;
-
void main() {
- vec3 uv0 = frag_uv_start;
- vec3 uv1 = frag_uv_end;
- uv0.y = 1.0 - uv0.y;
- uv1.y = 1.0 - uv1.y;
+ vec2 uv = frag_uv;
+ uv.y = 1.0 - uv.y;
- vec4 color_start = uvw2c_u8(uv0);
- vec4 color_end = uvw2c_u8(uv1);
-
- out_frag_color = mix(color_start, color_end, frag_blending_factor);
+ out_frag_color = uv2c_f32(frag_uv);
out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"hips_raytracer_backcolor.frag",
- r#"#version 300 es
-precision lowp float;
-precision mediump int;
-
-out vec4 out_frag_color;
-
-uniform vec3 color;
-
-void main() {
- out_frag_color = vec4(color, 1.0);
-}"#,
- );
- out.insert(
- r"catalogs_tan.vert",
- r#"#version 300 es
-precision lowp float;
-
-layout (location = 0) in vec2 offset;
-layout (location = 1) in vec2 uv;
-layout (location = 2) in vec3 center;
-
-uniform float current_time;
-uniform mat3 inv_model;
-
-uniform vec2 ndc_to_clip;
-uniform float czf;
-uniform vec2 kernel_size;
-
-out vec2 out_uv;
-out vec3 out_p;
-
-const float PI = 3.141592653589793;
-const float SQRT_2 = 1.41421356237309504880168872420969808;
-
-vec2 w2c_sin(vec3 p) {
- vec2 q = vec2(-p.x, p.y);
- return p.z >= 0.f ? q : normalize(q);
-}
-
-vec2 w2c_sin_no_backface(vec3 p) {
- return vec2(-p.x, p.y);
-}
-
-vec2 w2c_ait(vec3 p) {
- float r = length(p.zx);
- float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
- w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
- float y2d = p.y / w;
-
- float x2d = 0.0;
- if (abs(p.x) < 5e-3) {
- float x_over_r = p.x/r;
- x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
- } else {
- w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
- x2d = sign(-p.x) * w;
- }
-
- return vec2(x2d * 0.5, y2d) / SQRT_2;
-}
-const float eps = 1.25e-8;
-const int n_iter = 100;
-
-float newton_solve(float z) {
- float cte = PI * z;
- float x = 2.0 * asin(z);
- float f = x + sin(x) - cte;
- int i = 0;
- while (abs(f) > eps && i < n_iter) {
- x -= f / (1.0 + cos(x));
- f = x + sin(x) - cte;
- i += 1;
- }
-
- return 0.5 * x;
-}
-
-vec2 w2c_mol(vec3 p) {
- float g = newton_solve(p.y);
-
- float sg = sin(g);
- float cg = cos(g);
- return vec2((atan(-p.x, p.z) * cg) / PI, sg);
-}
-vec2 w2c_tan(vec3 p) {
- p.z = max(p.z, 1e-2);
- return vec2(-p.x, p.y) / (p.z*PI);
-}
-vec2 w2c_stg(vec3 p) {
- float w = (1.0 + p.z) * 0.5;
- return vec2(-p.x, p.y) / (PI * w);
-}
-vec2 w2c_zea(vec3 p) {
- float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
- return vec2(-p.x, p.y) * 0.5 / w;
-}
-vec2 w2c_mer(vec3 p) {
- return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
-}
-
-vec3 lonlat2xyz(vec2 lonlat) {
- float t = lonlat.x;
- float tc = cos(t);
- float ts = sin(t);
-
- float d = lonlat.y;
- float dc = cos(d);
- float ds = sin(d);
-
- return vec3(dc * ts, ds, dc * tc);
-}
-
-uniform int u_proj;
-
-vec2 proj(vec3 p) {
- if (u_proj == 0) {
- return w2c_tan(p);
- } else if (u_proj == 1) {
- return w2c_stg(p);
- } else if (u_proj == 2) {
- return w2c_sin(p);
- } else if (u_proj == 3) {
- return w2c_zea(p);
- } else if (u_proj == 4) {
- return w2c_ait(p);
- } else if (u_proj == 5) {
- return w2c_mol(p);
- } else {
- return w2c_mer(p);
- }
-}
-
-
-void main() {
- vec3 p = inv_model * center;
-
- vec2 center_pos_clip_space = world2clip_gnomonic(p);
-
- vec2 pos_clip_space = center_pos_clip_space;
- gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
-
- out_uv = uv;
- out_p = p;
-}"#,
- );
- out.insert(
- r"passes_post_fragment_100es.frag",
- r#"#version 300 es
-precision mediump float;
-
-in vec2 v_tc;
-out vec4 color;
-
-uniform sampler2D fbo_tex;
-
-vec3 srgb_from_linear(vec3 rgb) {
- bvec3 cutoff = lessThan(rgb, vec3(0.0031308));
- vec3 lower = rgb * vec3(3294.6);
- vec3 higher = vec3(269.025) * pow(rgb, vec3(1.0 / 2.4)) - vec3(14.025);
- return mix(higher, lower, vec3(cutoff));
-}
-
-vec4 srgba_from_linear(vec4 rgba) {
- return vec4(srgb_from_linear(rgba.rgb), 255.0 * rgba.a);
-}
-
-void main() {
- color = texture(fbo_tex, v_tc);
-
-}"#,
- );
- out.insert(
- r"catalogs_arc.vert",
- r#"#version 300 es
-precision lowp float;
-layout (location = 0) in vec2 offset;
-layout (location = 1) in vec2 uv;
-layout (location = 2) in vec3 center;
-
-uniform float current_time;
-uniform mat3 inv_model;
-
-uniform vec2 ndc_to_clip;
-uniform float czf;
-uniform vec2 kernel_size;
-
-out vec2 out_uv;
-out vec3 out_p;
-
-const float PI = 3.141592653589793;
-const float SQRT_2 = 1.41421356237309504880168872420969808;
-
-vec2 w2c_sin(vec3 p) {
- vec2 q = vec2(-p.x, p.y);
- return p.z >= 0.f ? q : normalize(q);
-}
-
-vec2 w2c_sin_no_backface(vec3 p) {
- return vec2(-p.x, p.y);
-}
-
-vec2 w2c_ait(vec3 p) {
- float r = length(p.zx);
- float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
- w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
- float y2d = p.y / w;
-
- float x2d = 0.0;
- if (abs(p.x) < 5e-3) {
- float x_over_r = p.x/r;
- x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
- } else {
- w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
- x2d = sign(-p.x) * w;
- }
-
- return vec2(x2d * 0.5, y2d) / SQRT_2;
-}
-const float eps = 1.25e-8;
-const int n_iter = 100;
-
-float newton_solve(float z) {
- float cte = PI * z;
- float x = 2.0 * asin(z);
- float f = x + sin(x) - cte;
- int i = 0;
- while (abs(f) > eps && i < n_iter) {
- x -= f / (1.0 + cos(x));
- f = x + sin(x) - cte;
- i += 1;
- }
-
- return 0.5 * x;
-}
-
-vec2 w2c_mol(vec3 p) {
- float g = newton_solve(p.y);
-
- float sg = sin(g);
- float cg = cos(g);
- return vec2((atan(-p.x, p.z) * cg) / PI, sg);
-}
-vec2 w2c_tan(vec3 p) {
- p.z = max(p.z, 1e-2);
- return vec2(-p.x, p.y) / (p.z*PI);
-}
-vec2 w2c_stg(vec3 p) {
- float w = (1.0 + p.z) * 0.5;
- return vec2(-p.x, p.y) / (PI * w);
-}
-vec2 w2c_zea(vec3 p) {
- float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
- return vec2(-p.x, p.y) * 0.5 / w;
-}
-vec2 w2c_mer(vec3 p) {
- return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
-}
-
-vec3 lonlat2xyz(vec2 lonlat) {
- float t = lonlat.x;
- float tc = cos(t);
- float ts = sin(t);
-
- float d = lonlat.y;
- float dc = cos(d);
- float ds = sin(d);
-
- return vec3(dc * ts, ds, dc * tc);
-}
-
-uniform int u_proj;
-
-vec2 proj(vec3 p) {
- if (u_proj == 0) {
- return w2c_tan(p);
- } else if (u_proj == 1) {
- return w2c_stg(p);
- } else if (u_proj == 2) {
- return w2c_sin(p);
- } else if (u_proj == 3) {
- return w2c_zea(p);
- } else if (u_proj == 4) {
- return w2c_ait(p);
- } else if (u_proj == 5) {
- return w2c_mol(p);
- } else {
- return w2c_mer(p);
- }
-}
-
-void main() {
- vec3 p = inv_model * center;
-
- vec2 center_pos_clip_space = world2clip_arc(p);
-
- vec2 pos_clip_space = center_pos_clip_space;
- gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
-
- out_uv = uv;
- out_p = p;
}"#,
);
out.insert(
@@ -1126,1022 +996,6 @@ uniform vec4 u_color;
void main() {
color = u_color;
-}"#,
- );
- out.insert(
- r"colormaps_colormap.vert",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2D;
-
-layout (location = 0) in vec2 position;
-layout (location = 1) in vec2 uv;
-
-out vec2 out_uv;
-
-void main() {
- gl_Position = vec4(position, 0.f, 1.f);
- out_uv = uv;
-}"#,
- );
- out.insert(
- r"fits_base.vert",
- r#"#version 300 es
-precision highp float;
-precision highp int;
-
-layout (location = 0) in vec2 ndc_pos;
-layout (location = 1) in vec2 uv;
-
-out vec2 frag_uv;
-
-void main() {
- gl_Position = vec4(ndc_pos, 0.0, 1.0);
- frag_uv = uv;
-}"#,
- );
- out.insert(
- r"hips3d_red.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler3D;
-precision lowp isampler3D;
-precision lowp usampler3D;
-
-uniform sampler3D tex;
-
-in vec3 frag_uv;
-
-out vec4 out_frag_color;
-uniform float opacity;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uvw2c_f32(vec3 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uvw2c_i32(vec3 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uvw2c_i16(vec3 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uvw2c_u8(vec3 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-
-void main() {
- vec3 uv = vec3(frag_uv.xyz);
- vec4 color = uvw2c_ra(uv);
-
- out_frag_color = color;
- out_frag_color.a = opacity * out_frag_color.a;
-}"#,
- );
- out.insert(
- r"catalogs_ortho.frag",
- r#"#version 300 es
-precision lowp float;
-
-in vec2 out_uv;
-in vec3 out_p;
-
-out vec4 color;
-
-uniform sampler2D kernel_texture;
-uniform float max_density; // max number of sources in a kernel sized HEALPix cell at the current depth
-uniform float fov;
-uniform float strength;
-void main() {
- if (out_p.z < 0.f) {
- discard;
- }
-
- color = texture(kernel_texture, out_uv) / max(log2(fov*100.0), 1.0);
- color.r *= strength;
-}"#,
- );
- out.insert(
- r"hips_rasterizer_i16.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2DArray;
-
-uniform sampler2DArray tex;
-
-in vec3 frag_uv_start;
-in vec3 frag_uv_end;
-in float frag_blending_factor;
-
-out vec4 out_frag_color;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uvw2c_f32(vec3 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uvw2c_i32(vec3 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uvw2c_i16(vec3 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uvw2c_u8(vec3 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-
-uniform float opacity;
-
-void main() {
- vec3 uv0 = frag_uv_start;
- vec3 uv1 = frag_uv_end;
- uv0.y = 1.0 - uv0.y;
- uv1.y = 1.0 - uv1.y;
-
- vec4 color_start = uvw2c_i16(uv0);
- vec4 color_end = uvw2c_i16(uv1);
-
- out_frag_color = mix(color_start, color_end, frag_blending_factor);
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"line_inst_lonlat.vert",
- r#"#version 300 es
-precision highp float;
-layout (location = 0) in vec2 p_a_lonlat;
-layout (location = 1) in vec2 p_b_lonlat;
-layout (location = 2) in vec2 vertex;
-
-uniform mat3 u_2world;
-uniform vec2 ndc_to_clip;
-uniform float czf;
-uniform float u_width;
-uniform float u_height;
-uniform float u_thickness;
-
-out vec2 l;
-
-const float PI = 3.141592653589793;
-const float SQRT_2 = 1.41421356237309504880168872420969808;
-
-vec2 w2c_sin(vec3 p) {
- vec2 q = vec2(-p.x, p.y);
- return p.z >= 0.f ? q : normalize(q);
-}
-
-vec2 w2c_sin_no_backface(vec3 p) {
- return vec2(-p.x, p.y);
-}
-
-vec2 w2c_ait(vec3 p) {
- float r = length(p.zx);
- float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
- w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
- float y2d = p.y / w;
-
- float x2d = 0.0;
- if (abs(p.x) < 5e-3) {
- float x_over_r = p.x/r;
- x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
- } else {
- w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
- x2d = sign(-p.x) * w;
- }
-
- return vec2(x2d * 0.5, y2d) / SQRT_2;
-}
-const float eps = 1.25e-8;
-const int n_iter = 100;
-
-float newton_solve(float z) {
- float cte = PI * z;
- float x = 2.0 * asin(z);
- float f = x + sin(x) - cte;
- int i = 0;
- while (abs(f) > eps && i < n_iter) {
- x -= f / (1.0 + cos(x));
- f = x + sin(x) - cte;
- i += 1;
- }
-
- return 0.5 * x;
-}
-
-vec2 w2c_mol(vec3 p) {
- float g = newton_solve(p.y);
-
- float sg = sin(g);
- float cg = cos(g);
- return vec2((atan(-p.x, p.z) * cg) / PI, sg);
-}
-vec2 w2c_tan(vec3 p) {
- p.z = max(p.z, 1e-2);
- return vec2(-p.x, p.y) / (p.z*PI);
-}
-vec2 w2c_stg(vec3 p) {
- float w = (1.0 + p.z) * 0.5;
- return vec2(-p.x, p.y) / (PI * w);
-}
-vec2 w2c_zea(vec3 p) {
- float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
- return vec2(-p.x, p.y) * 0.5 / w;
-}
-vec2 w2c_mer(vec3 p) {
- return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
-}
-
-vec3 lonlat2xyz(vec2 lonlat) {
- float t = lonlat.x;
- float tc = cos(t);
- float ts = sin(t);
-
- float d = lonlat.y;
- float dc = cos(d);
- float ds = sin(d);
-
- return vec3(dc * ts, ds, dc * tc);
-}
-
-uniform int u_proj;
-
-vec2 proj(vec3 p) {
- if (u_proj == 0) {
- return w2c_tan(p);
- } else if (u_proj == 1) {
- return w2c_stg(p);
- } else if (u_proj == 2) {
- return w2c_sin(p);
- } else if (u_proj == 3) {
- return w2c_zea(p);
- } else if (u_proj == 4) {
- return w2c_ait(p);
- } else if (u_proj == 5) {
- return w2c_mol(p);
- } else {
- return w2c_mer(p);
- }
-}
-
-void main() {
- vec3 p_a_xyz = lonlat2xyz(p_a_lonlat);
- vec3 p_b_xyz = lonlat2xyz(p_b_lonlat);
- vec3 p_a_w = u_2world * p_a_xyz;
- vec3 p_b_w = u_2world * p_b_xyz;
- vec2 p_a_clip = proj(p_a_w);
- vec2 p_b_clip = proj(p_b_w);
-
- vec2 da = p_a_clip - p_b_clip;
-
- vec2 p_a_ndc = p_a_clip / (ndc_to_clip * czf);
- vec2 p_b_ndc = p_b_clip / (ndc_to_clip * czf);
-
- vec2 x_b = p_b_ndc - p_a_ndc;
- vec2 y_b = normalize(vec2(-x_b.y, x_b.x));
-
- float ndc2pix = 2.0 / u_width;
-
- vec2 p_ndc_x = x_b * vertex.x;
- vec2 p_ndc_y = (u_thickness + 2.0) * y_b * vertex.y * vec2(1.0, u_width/u_height) * ndc2pix;
-
- vec2 p_ndc = p_a_ndc + p_ndc_x + p_ndc_y;
- gl_Position = vec4(p_ndc, 0.f, 1.f);
-
- l = vec2(dot(da, da), vertex.y);
-}"#,
- );
- out.insert(
- r"hips_rasterizer_rgba.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2DArray;
-
-uniform sampler2DArray tex;
-
-in vec3 frag_uv_start;
-in vec3 frag_uv_end;
-in float frag_blending_factor;
-
-out vec4 out_frag_color;
-uniform float opacity;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uvw2c_f32(vec3 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uvw2c_i32(vec3 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uvw2c_i16(vec3 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uvw2c_u8(vec3 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-
-void main() {
- vec4 color_start = uvw2c_rgba(frag_uv_start);
- vec4 color_end = uvw2c_rgba(frag_uv_end);
-
- out_frag_color = mix(color_start, color_end, frag_blending_factor);
- out_frag_color.a = opacity * out_frag_color.a;
-}"#,
- );
- out.insert(
- r"image_base.vert",
- r#"#version 300 es
-precision highp float;
-
-layout (location = 0) in vec2 ndc_pos;
-layout (location = 1) in vec2 uv;
-
-out vec2 frag_uv;
-
-void main() {
- gl_Position = vec4(ndc_pos, 0.0, 1.0);
- frag_uv = uv;
}"#,
);
out.insert(
@@ -2411,1266 +1265,18 @@ void main() {
}"#,
);
out.insert(
- r"line_base.vert",
- r#"#version 300 es
-precision highp float;
-layout (location = 0) in vec2 ndc_pos;
-
-out float l;
-
-void main() {
- gl_Position = vec4(
- ndc_pos,
- 0.0,
- 1.0
- );
-}"#,
- );
- out.insert(
- r"hips_raytracer_u8.frag",
+ r"hips3d_raster.vert",
r#"#version 300 es
precision lowp float;
-precision lowp sampler2DArray;
-precision lowp usampler2DArray;
-precision lowp isampler2DArray;
-precision mediump int;
-uniform sampler2DArray tex;
+layout (location = 0) in vec2 lonlat;
+layout (location = 1) in vec3 uv;
-in vec3 frag_pos;
-in vec2 out_clip_pos;
-out vec4 out_frag_color;
+out vec3 frag_uv;
-struct Tile {
- int uniq; // Healpix cell
- int texture_idx; // Index in the texture buffer
- float start_time; // Absolute time that the load has been done in ms
- float empty;
-};
-
-uniform Tile textures_tiles[12];
-
-uniform float opacity;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uvw2c_f32(vec3 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uvw2c_i32(vec3 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uvw2c_i16(vec3 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uvw2c_u8(vec3 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-const float TWICE_PI = 6.28318530718;
-const float PI = 3.141592653589793;
-const float FOUR_OVER_PI = 1.27323954474;
-const float TRANSITION_Z = 0.66666666666;
-const float TRANSITION_Z_INV = 1.5;
-
-int quarter(vec2 p) {
- int x_neg = int(p.x < 0.0);
- int y_neg = int(p.y < 0.0);
- int q = (x_neg + y_neg) | (y_neg << 1);
- return q;
-}
-
-float xpm1(vec2 p) {
- bool x_neg = (p.x < 0.0);
- bool y_neg = (p.y < 0.0);
- float lon = atan(abs(p.y), abs(p.x));
- float x02 = lon * FOUR_OVER_PI;
- if (x_neg != y_neg) { // Could be replaced by a sign copy from (x_neg ^ y_neg) << 32
- return 1.0 - x02;
- } else {
- return x02 - 1.0;
- }
-}
-
-float one_minus_z_pos(vec3 p) {
- float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
-
- if (d2 < 1e-1) { // <=> dec > 84.27 deg
- return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
- }
- return 1.0f - p.z;
-}
-
-float one_minus_z_neg(vec3 p) {
- float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
- if (d2 < 1e-1f) { // <=> dec < -84.27 deg
- return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
- }
- return p.z + 1.0;
-}
-
-int ij2z(int i, int j) {
- int i4 = i | (j << 2);
-
- int j4 = (i4 ^ (i4 >> 1)) & 0x22222222;
- int i5 = i4 ^ j4 ^ (j4 << 1);
-
- return i5;
-}
-
-struct HashDxDy {
- int idx;
- float dx;
- float dy;
-};
-
-uniform sampler2D ang2pixd;
-HashDxDy hash_with_dxdy2(vec2 radec) {
- vec2 aa = vec2(radec.x/TWICE_PI + 1.0, (radec.y/PI) + 0.5);
- vec3 v = texture(ang2pixd, aa).rgb;
- return HashDxDy(
- int(v.x * 255.0),
- v.y,
- v.z
- );
-}
-HashDxDy hash_with_dxdy(int depth, vec3 p) {
-
- int nside = 1 << depth;
- float half_nside = float(nside) * 0.5;
-
- float x_pm1 = xpm1(p.xy);
- int q = quarter(p.xy);
-
- int d0h = 0;
- vec2 p_proj = vec2(0.0);
- if (p.z > TRANSITION_Z) {
- float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_pos(p));
- p_proj = vec2(x_pm1 * sqrt_3_one_min_z, 2.0 - sqrt_3_one_min_z);
- d0h = q;
- } else if (p.z < -TRANSITION_Z) {
- float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_neg(p));
- p_proj = vec2(x_pm1 * sqrt_3_one_min_z, sqrt_3_one_min_z);
- d0h = q + 8;
- } else {
- float y_pm1 = p.z * TRANSITION_Z_INV;
- int q01 = int(x_pm1 > y_pm1); // 0/1
- int q12 = int(x_pm1 >= -y_pm1); // 0\1
- int q03 = 1 - q12; // 1\0
- int q1 = q01 & q12; // = 1 if q1, 0 else
- p_proj = vec2(
- x_pm1 - float(q01 + q12 - 1),
- y_pm1 + float(q01 + q03)
- );
- d0h = ((q01 + q03) << 2) + ((q + q1) & 3);
- }
-
- float x = (half_nside * (p_proj.x + p_proj.y));
- float y = (half_nside * (p_proj.y - p_proj.x));
- int i = int(x);
- int j = int(y);
-
- return HashDxDy(
- (d0h << (depth << 1)) + ij2z(i, j),
- x - float(i),
- y - float(j)
- );
-}
-vec3 xyz2uv(vec3 xyz) {
- HashDxDy result = hash_with_dxdy(0, xyz.zxy);
-
- int idx = result.idx;
- vec2 offset = vec2(result.dy, result.dx);
- Tile tile = textures_tiles[idx];
-
- return vec3(offset, float(tile.texture_idx));
-}
-
-void main() {
- vec3 uv = xyz2uv(normalize(frag_pos));
-
- uv.y = 1.0 - uv.y;
- vec4 c = uvw2c_u8(uv);
-
-
- out_frag_color = c;
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"hips_raytracer_i32.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2DArray;
-precision lowp usampler2DArray;
-precision lowp isampler2DArray;
-precision mediump int;
-
-uniform sampler2DArray tex;
-
-in vec3 frag_pos;
-in vec2 out_clip_pos;
-out vec4 out_frag_color;
-
-struct Tile {
- int uniq; // Healpix cell
- int texture_idx; // Index in the texture buffer
- float start_time; // Absolute time that the load has been done in ms
- float empty;
-};
-
-uniform Tile textures_tiles[12];
-
-uniform float opacity;
-
-const float TWICE_PI = 6.28318530718;
-const float PI = 3.141592653589793;
-const float FOUR_OVER_PI = 1.27323954474;
-const float TRANSITION_Z = 0.66666666666;
-const float TRANSITION_Z_INV = 1.5;
-
-int quarter(vec2 p) {
- int x_neg = int(p.x < 0.0);
- int y_neg = int(p.y < 0.0);
- int q = (x_neg + y_neg) | (y_neg << 1);
- return q;
-}
-
-float xpm1(vec2 p) {
- bool x_neg = (p.x < 0.0);
- bool y_neg = (p.y < 0.0);
- float lon = atan(abs(p.y), abs(p.x));
- float x02 = lon * FOUR_OVER_PI;
- if (x_neg != y_neg) { // Could be replaced by a sign copy from (x_neg ^ y_neg) << 32
- return 1.0 - x02;
- } else {
- return x02 - 1.0;
- }
-}
-
-float one_minus_z_pos(vec3 p) {
- float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
-
- if (d2 < 1e-1) { // <=> dec > 84.27 deg
- return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
- }
- return 1.0f - p.z;
-}
-
-float one_minus_z_neg(vec3 p) {
- float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
- if (d2 < 1e-1f) { // <=> dec < -84.27 deg
- return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
- }
- return p.z + 1.0;
-}
-
-int ij2z(int i, int j) {
- int i4 = i | (j << 2);
-
- int j4 = (i4 ^ (i4 >> 1)) & 0x22222222;
- int i5 = i4 ^ j4 ^ (j4 << 1);
-
- return i5;
-}
-
-struct HashDxDy {
- int idx;
- float dx;
- float dy;
-};
-
-uniform sampler2D ang2pixd;
-HashDxDy hash_with_dxdy2(vec2 radec) {
- vec2 aa = vec2(radec.x/TWICE_PI + 1.0, (radec.y/PI) + 0.5);
- vec3 v = texture(ang2pixd, aa).rgb;
- return HashDxDy(
- int(v.x * 255.0),
- v.y,
- v.z
- );
-}
-HashDxDy hash_with_dxdy(int depth, vec3 p) {
-
- int nside = 1 << depth;
- float half_nside = float(nside) * 0.5;
-
- float x_pm1 = xpm1(p.xy);
- int q = quarter(p.xy);
-
- int d0h = 0;
- vec2 p_proj = vec2(0.0);
- if (p.z > TRANSITION_Z) {
- float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_pos(p));
- p_proj = vec2(x_pm1 * sqrt_3_one_min_z, 2.0 - sqrt_3_one_min_z);
- d0h = q;
- } else if (p.z < -TRANSITION_Z) {
- float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_neg(p));
- p_proj = vec2(x_pm1 * sqrt_3_one_min_z, sqrt_3_one_min_z);
- d0h = q + 8;
- } else {
- float y_pm1 = p.z * TRANSITION_Z_INV;
- int q01 = int(x_pm1 > y_pm1); // 0/1
- int q12 = int(x_pm1 >= -y_pm1); // 0\1
- int q03 = 1 - q12; // 1\0
- int q1 = q01 & q12; // = 1 if q1, 0 else
- p_proj = vec2(
- x_pm1 - float(q01 + q12 - 1),
- y_pm1 + float(q01 + q03)
- );
- d0h = ((q01 + q03) << 2) + ((q + q1) & 3);
- }
-
- float x = (half_nside * (p_proj.x + p_proj.y));
- float y = (half_nside * (p_proj.y - p_proj.x));
- int i = int(x);
- int j = int(y);
-
- return HashDxDy(
- (d0h << (depth << 1)) + ij2z(i, j),
- x - float(i),
- y - float(j)
- );
-}
-vec3 xyz2uv(vec3 xyz) {
- HashDxDy result = hash_with_dxdy(0, xyz.zxy);
-
- int idx = result.idx;
- vec2 offset = vec2(result.dy, result.dx);
- Tile tile = textures_tiles[idx];
-
- return vec3(offset, float(tile.texture_idx));
-}
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uvw2c_f32(vec3 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uvw2c_i32(vec3 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uvw2c_i16(vec3 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uvw2c_u8(vec3 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-
-void main() {
- vec3 uv = xyz2uv(normalize(frag_pos));
-
- uv.y = 1.0 - uv.y;
- vec4 c = uvw2c_i32(uv);
-
- out_frag_color = c;
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"line_inst_ndc.vert",
- r#"#version 300 es
-precision highp float;
-layout (location = 0) in vec2 p_a;
-layout (location = 1) in vec2 p_b;
-layout (location = 2) in vec2 vertex;
-
-out vec2 l;
-
-uniform float u_width;
-uniform float u_height;
-uniform float u_thickness;
-
-void main() {
- vec2 x_b = p_b - p_a;
- vec2 y_b = normalize(vec2(-x_b.y, x_b.x));
-
- float ndc2pix = 2.0 / u_width;
-
- vec2 p = p_a + x_b * vertex.x + (u_thickness + 2.0) * y_b * vertex.y * vec2(1.0, u_width/u_height) * ndc2pix;
- gl_Position = vec4(p, 0.f, 1.f);
- l = vec2(0.0, vertex.y);
-}"#,
- );
- out.insert(
- r"fits_i32.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2D;
-precision mediump int;
-
-out vec4 out_frag_color;
-in vec2 frag_uv;
-
-uniform sampler2D tex;
-uniform float opacity;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uv2c_f32(vec2 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uv2c_i32(vec2 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uv2c_i16(vec2 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uv2c_u8(vec2 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-
-void main() {
- vec2 uv = frag_uv;
- uv.y = 1.0 - uv.y;
-
- out_frag_color = uv2c_i32(frag_uv);
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"fits_u8.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2D;
-precision mediump int;
-
-out vec4 out_frag_color;
-in vec2 frag_uv;
-
-uniform sampler2D tex;
-uniform float opacity;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uv2c_f32(vec2 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uv2c_i32(vec2 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uv2c_i16(vec2 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uv2c_u8(vec2 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-
-void main() {
- vec2 uv = frag_uv;
- uv.y = 1.0 - uv.y;
-
- out_frag_color = uv2c_u8(frag_uv);
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"catalogs_ortho.vert",
- r#"#version 300 es
-precision lowp float;
-layout (location = 0) in vec2 offset;
-layout (location = 1) in vec2 uv;
-layout (location = 2) in vec3 center;
-
-uniform float current_time;
uniform mat3 inv_model;
-
uniform vec2 ndc_to_clip;
uniform float czf;
-uniform vec2 kernel_size;
-
-out vec2 out_uv;
-out vec3 out_p;
const float PI = 3.141592653589793;
const float SQRT_2 = 1.41421356237309504880168872420969808;
@@ -3773,343 +1379,41 @@ vec2 proj(vec3 p) {
}
}
-
void main() {
- vec3 p = inv_model * center;
+ vec3 p_xyz = lonlat2xyz(lonlat);
+ vec3 p_w = inv_model * p_xyz;
+ vec2 p_clip = proj(p_w.xyz);
- vec2 center_pos_clip_space = world2clip_orthographic(p);
+ vec2 p_ndc = p_clip / (ndc_to_clip * czf);
+ gl_Position = vec4(p_ndc, 0.0, 1.0);
- vec2 pos_clip_space = center_pos_clip_space;
- gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
-
- out_uv = uv;
- out_p = p;
+ frag_uv = uv;
}"#,
);
out.insert(
- r"hips_raytracer_raytracer.vert",
- r#"#version 300 es
-precision lowp float;
-precision mediump int;
-
-layout (location = 0) in vec2 pos_clip_space;
-layout (location = 1) in vec3 pos_world_space;
-
-out vec2 out_clip_pos;
-out vec3 frag_pos;
-
-uniform vec2 ndc_to_clip;
-uniform float czf;
-uniform mat3 model;
-
-void main() {
- vec2 uv = pos_clip_space * 0.5 + 0.5;
-
- frag_pos = model * pos_world_space;
-
- gl_Position = vec4(pos_clip_space / (ndc_to_clip * czf), 0.0, 1.0);
- out_clip_pos = pos_clip_space;
-}"#,
- );
- out.insert(
- r"image_sampler.frag",
- r#"#version 300 es
-precision highp float;
-precision highp sampler2D;
-
-out vec4 out_frag_color;
-in vec2 frag_uv;
-
-uniform sampler2D tex;
-uniform float opacity;
-
-void main() {
- out_frag_color = texture(tex, frag_uv);
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"hips3d_i16.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler3D;
-precision lowp isampler3D;
-precision lowp usampler3D;
-
-uniform sampler3D tex;
-
-in vec3 frag_uv;
-
-out vec4 out_frag_color;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uvw2c_f32(vec3 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uvw2c_i32(vec3 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uvw2c_i16(vec3 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uvw2c_u8(vec3 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-
-uniform float opacity;
-
-void main() {
- vec3 uv = vec3(frag_uv.xyz);
- uv.y = 1.0 - uv.y;
-
- vec4 color = uvw2c_i16(uv);
-
- out_frag_color = color;
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"hips_rasterizer_i32.frag",
+ r"hips_raytracer_i16.frag",
r#"#version 300 es
precision lowp float;
precision lowp sampler2DArray;
+precision mediump int;
uniform sampler2DArray tex;
-in vec3 frag_uv_start;
-in vec3 frag_uv_end;
-in float frag_blending_factor;
-
+in vec3 frag_pos;
+in vec2 out_clip_pos;
out vec4 out_frag_color;
+struct Tile {
+ int uniq; // Healpix cell
+ int texture_idx; // Index in the texture buffer
+ float start_time; // Absolute time that the load has been done in ms
+ float empty;
+};
+
+uniform Tile textures_tiles[12];
+
+uniform float opacity;
+
uniform float scale;
uniform float offset;
uniform float blank;
@@ -4351,19 +1655,133 @@ vec4 uvw2c_u8(vec3 uv) {
float val = float(decode_u8(texture(tex, uv).r));
return val2c(val);
}
+const float TWICE_PI = 6.28318530718;
+const float PI = 3.141592653589793;
+const float FOUR_OVER_PI = 1.27323954474;
+const float TRANSITION_Z = 0.66666666666;
+const float TRANSITION_Z_INV = 1.5;
-uniform float opacity;
+int quarter(vec2 p) {
+ int x_neg = int(p.x < 0.0);
+ int y_neg = int(p.y < 0.0);
+ int q = (x_neg + y_neg) | (y_neg << 1);
+ return q;
+}
+
+float xpm1(vec2 p) {
+ bool x_neg = (p.x < 0.0);
+ bool y_neg = (p.y < 0.0);
+ float lon = atan(abs(p.y), abs(p.x));
+ float x02 = lon * FOUR_OVER_PI;
+ if (x_neg != y_neg) { // Could be replaced by a sign copy from (x_neg ^ y_neg) << 32
+ return 1.0 - x02;
+ } else {
+ return x02 - 1.0;
+ }
+}
+
+float one_minus_z_pos(vec3 p) {
+ float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
+
+ if (d2 < 1e-1) { // <=> dec > 84.27 deg
+ return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
+ }
+ return 1.0f - p.z;
+}
+
+float one_minus_z_neg(vec3 p) {
+ float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
+ if (d2 < 1e-1f) { // <=> dec < -84.27 deg
+ return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
+ }
+ return p.z + 1.0;
+}
+
+int ij2z(int i, int j) {
+ int i4 = i | (j << 2);
+
+ int j4 = (i4 ^ (i4 >> 1)) & 0x22222222;
+ int i5 = i4 ^ j4 ^ (j4 << 1);
+
+ return i5;
+}
+
+struct HashDxDy {
+ int idx;
+ float dx;
+ float dy;
+};
+
+uniform sampler2D ang2pixd;
+HashDxDy hash_with_dxdy2(vec2 radec) {
+ vec2 aa = vec2(radec.x/TWICE_PI + 1.0, (radec.y/PI) + 0.5);
+ vec3 v = texture(ang2pixd, aa).rgb;
+ return HashDxDy(
+ int(v.x * 255.0),
+ v.y,
+ v.z
+ );
+}
+HashDxDy hash_with_dxdy(int depth, vec3 p) {
+
+ int nside = 1 << depth;
+ float half_nside = float(nside) * 0.5;
+
+ float x_pm1 = xpm1(p.xy);
+ int q = quarter(p.xy);
+
+ int d0h = 0;
+ vec2 p_proj = vec2(0.0);
+ if (p.z > TRANSITION_Z) {
+ float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_pos(p));
+ p_proj = vec2(x_pm1 * sqrt_3_one_min_z, 2.0 - sqrt_3_one_min_z);
+ d0h = q;
+ } else if (p.z < -TRANSITION_Z) {
+ float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_neg(p));
+ p_proj = vec2(x_pm1 * sqrt_3_one_min_z, sqrt_3_one_min_z);
+ d0h = q + 8;
+ } else {
+ float y_pm1 = p.z * TRANSITION_Z_INV;
+ int q01 = int(x_pm1 > y_pm1); // 0/1
+ int q12 = int(x_pm1 >= -y_pm1); // 0\1
+ int q03 = 1 - q12; // 1\0
+ int q1 = q01 & q12; // = 1 if q1, 0 else
+ p_proj = vec2(
+ x_pm1 - float(q01 + q12 - 1),
+ y_pm1 + float(q01 + q03)
+ );
+ d0h = ((q01 + q03) << 2) + ((q + q1) & 3);
+ }
+
+ float x = (half_nside * (p_proj.x + p_proj.y));
+ float y = (half_nside * (p_proj.y - p_proj.x));
+ int i = int(x);
+ int j = int(y);
+
+ return HashDxDy(
+ (d0h << (depth << 1)) + ij2z(i, j),
+ x - float(i),
+ y - float(j)
+ );
+}
+vec3 xyz2uv(vec3 xyz) {
+ HashDxDy result = hash_with_dxdy(0, xyz.zxy);
+
+ int idx = result.idx;
+ vec2 offset = vec2(result.dy, result.dx);
+ Tile tile = textures_tiles[idx];
+
+ return vec3(offset, float(tile.texture_idx));
+}
void main() {
- vec3 uv0 = frag_uv_start;
- vec3 uv1 = frag_uv_end;
- uv0.y = 1.0 - uv0.y;
- uv1.y = 1.0 - uv1.y;
+ vec3 uv = xyz2uv(normalize(frag_pos));
- vec4 color_start = uvw2c_i32(uv0);
- vec4 color_end = uvw2c_i32(uv1);
+ uv.y = 1.0 - uv.y;
+ vec4 c = uvw2c_i16(uv);
- out_frag_color = mix(color_start, color_end, frag_blending_factor);
+
+ out_frag_color = c;
out_frag_color.a = out_frag_color.a * opacity;
}"#,
);
@@ -4761,7 +2179,7 @@ void main() {
}"#,
);
out.insert(
- r"catalogs_mercator.vert",
+ r"catalogs_ortho.vert",
r#"#version 300 es
precision lowp float;
layout (location = 0) in vec2 offset;
@@ -4883,7 +2301,7 @@ vec2 proj(vec3 p) {
void main() {
vec3 p = inv_model * center;
- vec2 center_pos_clip_space = world2clip_mercator(p);
+ vec2 center_pos_clip_space = world2clip_orthographic(p);
vec2 pos_clip_space = center_pos_clip_space;
gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
@@ -4893,16 +2311,27 @@ void main() {
}"#,
);
out.insert(
- r"colormaps_colormap.frag",
+ r"hips3d_red.frag",
r#"#version 300 es
precision lowp float;
-precision lowp sampler2D;
+precision lowp sampler3D;
+precision lowp isampler3D;
+precision lowp usampler3D;
-in vec2 out_uv;
-out vec4 color;
+uniform sampler3D tex;
-uniform sampler2D texture_fbo;
-uniform float alpha;
+in vec3 frag_uv;
+
+out vec4 out_frag_color;
+uniform float opacity;
+
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
uniform sampler2D colormaps;
uniform float num_colormaps;
@@ -4912,150 +2341,259 @@ vec4 colormap_f(float x) {
float id = (colormap_id + 0.5) / num_colormaps;
return texture(colormaps, vec2(x, id));
}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
+
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
+
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
+ } else {
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uvw2c_f32(vec3 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uvw2c_i32(vec3 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uvw2c_i16(vec3 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uvw2c_u8(vec3 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
void main() {
- float opacity = texture(texture_fbo, out_uv).r;
+ vec3 uv = vec3(frag_uv.xyz);
+ vec4 color = uvw2c_ra(uv);
- float o = smoothstep(0.0, 0.1, opacity);
-
- color = colormap_f(opacity);
- color.a = o * alpha;
+ out_frag_color = color;
+ out_frag_color.a = opacity * out_frag_color.a;
}"#,
);
out.insert(
- r"catalogs_healpix.vert",
+ r"image_sampler.frag",
r#"#version 300 es
-precision lowp float;
-layout (location = 0) in vec2 offset;
-layout (location = 1) in vec2 uv;
-layout (location = 2) in vec3 center;
+precision highp float;
+precision highp sampler2D;
-uniform float current_time;
-uniform mat3 inv_model;
-
-uniform vec2 ndc_to_clip;
-uniform float czf;
-uniform vec2 kernel_size;
-
-out vec2 out_uv;
-out vec3 out_p;
-
-const float PI = 3.141592653589793;
-const float SQRT_2 = 1.41421356237309504880168872420969808;
-
-vec2 w2c_sin(vec3 p) {
- vec2 q = vec2(-p.x, p.y);
- return p.z >= 0.f ? q : normalize(q);
-}
-
-vec2 w2c_sin_no_backface(vec3 p) {
- return vec2(-p.x, p.y);
-}
-
-vec2 w2c_ait(vec3 p) {
- float r = length(p.zx);
- float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
- w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
- float y2d = p.y / w;
-
- float x2d = 0.0;
- if (abs(p.x) < 5e-3) {
- float x_over_r = p.x/r;
- x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
- } else {
- w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
- x2d = sign(-p.x) * w;
- }
-
- return vec2(x2d * 0.5, y2d) / SQRT_2;
-}
-const float eps = 1.25e-8;
-const int n_iter = 100;
-
-float newton_solve(float z) {
- float cte = PI * z;
- float x = 2.0 * asin(z);
- float f = x + sin(x) - cte;
- int i = 0;
- while (abs(f) > eps && i < n_iter) {
- x -= f / (1.0 + cos(x));
- f = x + sin(x) - cte;
- i += 1;
- }
-
- return 0.5 * x;
-}
-
-vec2 w2c_mol(vec3 p) {
- float g = newton_solve(p.y);
-
- float sg = sin(g);
- float cg = cos(g);
- return vec2((atan(-p.x, p.z) * cg) / PI, sg);
-}
-vec2 w2c_tan(vec3 p) {
- p.z = max(p.z, 1e-2);
- return vec2(-p.x, p.y) / (p.z*PI);
-}
-vec2 w2c_stg(vec3 p) {
- float w = (1.0 + p.z) * 0.5;
- return vec2(-p.x, p.y) / (PI * w);
-}
-vec2 w2c_zea(vec3 p) {
- float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
- return vec2(-p.x, p.y) * 0.5 / w;
-}
-vec2 w2c_mer(vec3 p) {
- return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
-}
-
-vec3 lonlat2xyz(vec2 lonlat) {
- float t = lonlat.x;
- float tc = cos(t);
- float ts = sin(t);
-
- float d = lonlat.y;
- float dc = cos(d);
- float ds = sin(d);
-
- return vec3(dc * ts, ds, dc * tc);
-}
-
-uniform int u_proj;
-
-vec2 proj(vec3 p) {
- if (u_proj == 0) {
- return w2c_tan(p);
- } else if (u_proj == 1) {
- return w2c_stg(p);
- } else if (u_proj == 2) {
- return w2c_sin(p);
- } else if (u_proj == 3) {
- return w2c_zea(p);
- } else if (u_proj == 4) {
- return w2c_ait(p);
- } else if (u_proj == 5) {
- return w2c_mol(p);
- } else {
- return w2c_mer(p);
- }
-}
+out vec4 out_frag_color;
+in vec2 frag_uv;
+uniform sampler2D tex;
+uniform float opacity;
void main() {
- vec3 p = inv_model * center;
-
- vec2 center_pos_clip_space = world2clip_healpix(p);
-
- vec2 pos_clip_space = center_pos_clip_space;
- gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
-
- out_uv = uv;
- out_p = p;
+ out_frag_color = texture(tex, frag_uv);
+ out_frag_color.a = out_frag_color.a * opacity;
}"#,
);
out.insert(
- r"hips3d_i32.frag",
+ r"hips3d_i16.frag",
r#"#version 300 es
precision lowp float;
precision lowp sampler3D;
@@ -5316,24 +2854,48 @@ void main() {
vec3 uv = vec3(frag_uv.xyz);
uv.y = 1.0 - uv.y;
- vec4 color = uvw2c_i32(uv);
+ vec4 color = uvw2c_i16(uv);
out_frag_color = color;
out_frag_color.a = out_frag_color.a * opacity;
}"#,
);
out.insert(
- r"fits_f32.frag",
+ r"catalogs_ortho.frag",
r#"#version 300 es
-precision highp float;
-precision highp sampler2D;
-precision highp int;
+precision lowp float;
+
+in vec2 out_uv;
+in vec3 out_p;
+
+out vec4 color;
+
+uniform sampler2D kernel_texture;
+uniform float max_density; // max number of sources in a kernel sized HEALPix cell at the current depth
+uniform float fov;
+uniform float strength;
+void main() {
+ if (out_p.z < 0.f) {
+ discard;
+ }
+
+ color = texture(kernel_texture, out_uv) / max(log2(fov*100.0), 1.0);
+ color.r *= strength;
+}"#,
+ );
+ out.insert(
+ r"hips_rasterizer_i16.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2DArray;
+
+uniform sampler2DArray tex;
+
+in vec3 frag_uv_start;
+in vec3 frag_uv_end;
+in float frag_blending_factor;
out vec4 out_frag_color;
-in vec2 frag_uv;
-
-uniform sampler2D tex;
-uniform float opacity;
uniform float scale;
uniform float offset;
@@ -5435,6 +2997,21 @@ vec4 apply_tonal(vec4 color) {
k_gamma
);
}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
highp float decode_f32(highp vec4 rgba) {
highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
@@ -5478,6 +3055,49 @@ uint decode_u8(float r) {
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
vec4 val2c_f32(float x) {
float alpha = x * scale + offset;
@@ -5499,36 +3119,43 @@ vec4 val2c(float x) {
return apply_tonal(new_color);
}
-vec4 uv2c_f32(vec2 uv) {
+vec4 uvw2c_f32(vec3 uv) {
float val = decode_f32(texture(tex, uv).rgba*255.0);
return val2c_f32(val);
}
-vec4 uv2c_i32(vec2 uv) {
+vec4 uvw2c_i32(vec3 uv) {
float val = float(decode_i32(texture(tex, uv).rgba));
return val2c(val);
}
-vec4 uv2c_i16(vec2 uv) {
+vec4 uvw2c_i16(vec3 uv) {
float val = float(decode_i16(texture(tex, uv).rg));
return val2c(val);
}
-vec4 uv2c_u8(vec2 uv) {
+vec4 uvw2c_u8(vec3 uv) {
float val = float(decode_u8(texture(tex, uv).r));
return val2c(val);
}
-void main() {
- vec2 uv = frag_uv;
- uv.y = 1.0 - uv.y;
+uniform float opacity;
- out_frag_color = uv2c_f32(frag_uv);
+void main() {
+ vec3 uv0 = frag_uv_start;
+ vec3 uv1 = frag_uv_end;
+ uv0.y = 1.0 - uv0.y;
+ uv1.y = 1.0 - uv1.y;
+
+ vec4 color_start = uvw2c_i16(uv0);
+ vec4 color_end = uvw2c_i16(uv1);
+
+ out_frag_color = mix(color_start, color_end, frag_blending_factor);
out_frag_color.a = out_frag_color.a * opacity;
}"#,
);
out.insert(
- r"fits_i16.frag",
+ r"fits_u8.frag",
r#"#version 300 es
precision lowp float;
precision lowp sampler2D;
@@ -5728,7 +3355,7 @@ void main() {
vec2 uv = frag_uv;
uv.y = 1.0 - uv.y;
- out_frag_color = uv2c_i16(frag_uv);
+ out_frag_color = uv2c_u8(frag_uv);
out_frag_color.a = out_frag_color.a * opacity;
}"#,
);
@@ -6004,146 +3631,21 @@ void main() {
}"#,
);
out.insert(
- r"catalogs_mollweide.vert",
- r#"#version 300 es
-precision lowp float;
-layout (location = 0) in vec2 offset;
-layout (location = 1) in vec2 uv;
-layout (location = 2) in vec3 center;
-
-uniform float current_time;
-uniform mat3 inv_model;
-
-uniform vec2 ndc_to_clip;
-uniform float czf;
-uniform vec2 kernel_size;
-
-out vec2 out_uv;
-out vec3 out_p;
-
-const float PI = 3.141592653589793;
-const float SQRT_2 = 1.41421356237309504880168872420969808;
-
-vec2 w2c_sin(vec3 p) {
- vec2 q = vec2(-p.x, p.y);
- return p.z >= 0.f ? q : normalize(q);
-}
-
-vec2 w2c_sin_no_backface(vec3 p) {
- return vec2(-p.x, p.y);
-}
-
-vec2 w2c_ait(vec3 p) {
- float r = length(p.zx);
- float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
- w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
- float y2d = p.y / w;
-
- float x2d = 0.0;
- if (abs(p.x) < 5e-3) {
- float x_over_r = p.x/r;
- x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
- } else {
- w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
- x2d = sign(-p.x) * w;
- }
-
- return vec2(x2d * 0.5, y2d) / SQRT_2;
-}
-const float eps = 1.25e-8;
-const int n_iter = 100;
-
-float newton_solve(float z) {
- float cte = PI * z;
- float x = 2.0 * asin(z);
- float f = x + sin(x) - cte;
- int i = 0;
- while (abs(f) > eps && i < n_iter) {
- x -= f / (1.0 + cos(x));
- f = x + sin(x) - cte;
- i += 1;
- }
-
- return 0.5 * x;
-}
-
-vec2 w2c_mol(vec3 p) {
- float g = newton_solve(p.y);
-
- float sg = sin(g);
- float cg = cos(g);
- return vec2((atan(-p.x, p.z) * cg) / PI, sg);
-}
-vec2 w2c_tan(vec3 p) {
- p.z = max(p.z, 1e-2);
- return vec2(-p.x, p.y) / (p.z*PI);
-}
-vec2 w2c_stg(vec3 p) {
- float w = (1.0 + p.z) * 0.5;
- return vec2(-p.x, p.y) / (PI * w);
-}
-vec2 w2c_zea(vec3 p) {
- float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
- return vec2(-p.x, p.y) * 0.5 / w;
-}
-vec2 w2c_mer(vec3 p) {
- return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
-}
-
-vec3 lonlat2xyz(vec2 lonlat) {
- float t = lonlat.x;
- float tc = cos(t);
- float ts = sin(t);
-
- float d = lonlat.y;
- float dc = cos(d);
- float ds = sin(d);
-
- return vec3(dc * ts, ds, dc * tc);
-}
-
-uniform int u_proj;
-
-vec2 proj(vec3 p) {
- if (u_proj == 0) {
- return w2c_tan(p);
- } else if (u_proj == 1) {
- return w2c_stg(p);
- } else if (u_proj == 2) {
- return w2c_sin(p);
- } else if (u_proj == 3) {
- return w2c_zea(p);
- } else if (u_proj == 4) {
- return w2c_ait(p);
- } else if (u_proj == 5) {
- return w2c_mol(p);
- } else {
- return w2c_mer(p);
- }
-}
-
-
-void main() {
- vec3 p = inv_model * center;
-
- vec2 center_pos_clip_space = world2clip_mollweide(p);
-
- vec2 pos_clip_space = center_pos_clip_space;
- gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
-
- out_uv = uv;
- out_p = p;
-}"#,
- );
- out.insert(
- r"moc_base.vert",
+ r"line_inst_lonlat.vert",
r#"#version 300 es
precision highp float;
-layout (location = 0) in vec2 lonlat;
+layout (location = 0) in vec2 p_a_lonlat;
+layout (location = 1) in vec2 p_b_lonlat;
+layout (location = 2) in vec2 vertex;
uniform mat3 u_2world;
uniform vec2 ndc_to_clip;
uniform float czf;
+uniform float u_width;
+uniform float u_height;
+uniform float u_thickness;
+
+out vec2 l;
const float PI = 3.141592653589793;
const float SQRT_2 = 1.41421356237309504880168872420969808;
@@ -6247,78 +3749,244 @@ vec2 proj(vec3 p) {
}
void main() {
- vec3 p_xyz = lonlat2xyz(lonlat);
- vec3 p_w = u_2world * p_xyz;
- vec2 p_clip = proj(p_w);
+ vec3 p_a_xyz = lonlat2xyz(p_a_lonlat);
+ vec3 p_b_xyz = lonlat2xyz(p_b_lonlat);
+ vec3 p_a_w = u_2world * p_a_xyz;
+ vec3 p_b_w = u_2world * p_b_xyz;
+ vec2 p_a_clip = proj(p_a_w);
+ vec2 p_b_clip = proj(p_b_w);
- vec2 p_ndc = p_clip / (ndc_to_clip * czf);
+ vec2 da = p_a_clip - p_b_clip;
+
+ vec2 p_a_ndc = p_a_clip / (ndc_to_clip * czf);
+ vec2 p_b_ndc = p_b_clip / (ndc_to_clip * czf);
+
+ vec2 x_b = p_b_ndc - p_a_ndc;
+ vec2 y_b = normalize(vec2(-x_b.y, x_b.x));
+
+ float ndc2pix = 2.0 / u_width;
+
+ vec2 p_ndc_x = x_b * vertex.x;
+ vec2 p_ndc_y = (u_thickness + 2.0) * y_b * vertex.y * vec2(1.0, u_width/u_height) * ndc2pix;
+
+ vec2 p_ndc = p_a_ndc + p_ndc_x + p_ndc_y;
gl_Position = vec4(p_ndc, 0.f, 1.f);
+
+ l = vec2(dot(da, da), vertex.y);
}"#,
);
out.insert(
- r"catalogs_catalog.frag",
+ r"fits_i32.frag",
r#"#version 300 es
precision lowp float;
+precision lowp sampler2D;
+precision mediump int;
-in vec2 out_uv;
-in vec3 out_p;
+out vec4 out_frag_color;
+in vec2 frag_uv;
-out vec4 color;
+uniform sampler2D tex;
+uniform float opacity;
-uniform sampler2D kernel_texture;
-uniform float max_density; // max number of sources in a kernel sized HEALPix cell at the current depth
-uniform float fov;
-uniform float strength;
-void main() {
- color = texture(kernel_texture, out_uv) / max(log2(fov*100.0), 1.0);
- color.r *= strength;
-}"#,
- );
- out.insert(
- r"line_base.frag",
- r#"#version 300 es
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
-precision highp float;
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
-out vec4 color;
-in vec2 l;
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
-uniform vec4 u_color;
-uniform float u_thickness;
-uniform float u_width;
-uniform float u_height;
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
-void main() {
- if (l.x > 0.05) {
- discard;
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
} else {
- color = u_color;
-
- float dist = abs((u_thickness + 2.0) * l.y);
-
- float half_thickness = (u_thickness + 2.0) * 0.5;
- color.a = color.a * (1.0 - smoothstep(half_thickness - 1.0, half_thickness, dist));
+ return pow2_f(x, min_value, max_value);
}
-}"#,
- );
- out.insert(
- r"passes_post_vertex_100es.vert",
- r#"#version 300 es
-precision mediump float;
+}
-layout (location = 0) in vec2 a_pos;
-out vec2 v_tc;
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uv2c_f32(vec2 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uv2c_i32(vec2 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uv2c_i16(vec2 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uv2c_u8(vec2 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
void main() {
- gl_Position = vec4(a_pos * 2. - 1., 0.0, 1.0);
- v_tc = a_pos;
+ vec2 uv = frag_uv;
+ uv.y = 1.0 - uv.y;
+
+ out_frag_color = uv2c_i32(frag_uv);
+ out_frag_color.a = out_frag_color.a * opacity;
}"#,
);
out.insert(
- r"hips3d_u8.frag",
+ r"hips3d_i32.frag",
r#"#version 300 es
precision lowp float;
precision lowp sampler3D;
+precision lowp isampler3D;
+precision lowp usampler3D;
uniform sampler3D tex;
@@ -6574,10 +4242,37 @@ void main() {
vec3 uv = vec3(frag_uv.xyz);
uv.y = 1.0 - uv.y;
- vec4 color = uvw2c_u8(uv);
+ vec4 color = uvw2c_i32(uv);
out_frag_color = color;
out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"line_base.frag",
+ r#"#version 300 es
+
+precision highp float;
+
+out vec4 color;
+in vec2 l;
+
+uniform vec4 u_color;
+uniform float u_thickness;
+uniform float u_width;
+uniform float u_height;
+
+void main() {
+ if (l.x > 0.05) {
+ discard;
+ } else {
+ color = u_color;
+
+ float dist = abs((u_thickness + 2.0) * l.y);
+
+ float half_thickness = (u_thickness + 2.0) * 0.5;
+ color.a = color.a * (1.0 - smoothstep(half_thickness - 1.0, half_thickness, dist));
+ }
}"#,
);
out.insert(
@@ -6969,401 +4664,6 @@ void main() {
vec3 uv = xyz2uv(normalize(frag_pos));
vec4 c = uvw2cmap_rgba(uv);
- out_frag_color = c;
- out_frag_color.a = out_frag_color.a * opacity;
-}"#,
- );
- out.insert(
- r"hips_raytracer_i16.frag",
- r#"#version 300 es
-precision lowp float;
-precision lowp sampler2DArray;
-precision mediump int;
-
-uniform sampler2DArray tex;
-
-in vec3 frag_pos;
-in vec2 out_clip_pos;
-out vec4 out_frag_color;
-
-struct Tile {
- int uniq; // Healpix cell
- int texture_idx; // Index in the texture buffer
- float start_time; // Absolute time that the load has been done in ms
- float empty;
-};
-
-uniform Tile textures_tiles[12];
-
-uniform float opacity;
-
-uniform float scale;
-uniform float offset;
-uniform float blank;
-uniform float min_value;
-uniform float max_value;
-uniform int H;
-uniform float reversed;
-
-uniform sampler2D colormaps;
-uniform float num_colormaps;
-uniform float colormap_id;
-
-vec4 colormap_f(float x) {
- float id = (colormap_id + 0.5) / num_colormaps;
- return texture(colormaps, vec2(x, id));
-}
-float linear_f(float x, float min_value, float max_value) {
- return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
-}
-
-float sqrt_f(float x, float min_value, float max_value) {
- float a = linear_f(x, min_value, max_value);
- return sqrt(a);
-}
-
-float log_f(float x, float min_value, float max_value) {
- float y = linear_f(x, min_value, max_value);
- float a = 1000.0;
- return log(a*y + 1.0)/log(a);
-}
-
-float asinh_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return asinh(10.0*d)/3.0;
-}
-
-float pow2_f(float x, float min_value, float max_value) {
- float d = linear_f(x, min_value, max_value);
- return d*d;
-}
-
-float transfer_func(int H, float x, float min_value, float max_value) {
- if (H == 0) {
- return linear_f(x, min_value, max_value);
- } else if (H == 1) {
- return sqrt_f(x, min_value, max_value);
- } else if (H == 2) {
- return log_f(x, min_value, max_value);
- } else if (H == 3) {
- return asinh_f(x, min_value, max_value);
- } else {
- return pow2_f(x, min_value, max_value);
- }
-}
-
-uniform float k_gamma;
-uniform float k_saturation;
-uniform float k_contrast;
-uniform float k_brightness;
-uniform float k_exposure;
-
-vec4 apply_gamma(vec4 ic, float g) {
- float new_r = pow(ic.r, g);
- float new_g = pow(ic.g, g);
- float new_b = pow(ic.b, g);
-
- return vec4(new_r, new_g, new_b, ic.a);
-}
-
-vec4 apply_saturation(vec4 color, float value) {
- const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
- vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
-
- return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
-}
-
-vec4 apply_contrast(vec4 color, float value) {
- return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
-}
-
-vec4 apply_brightness(vec4 color, float value) {
- return vec4(color.rgb + value, color.a);
-}
-
-vec4 apply_exposure(vec4 color, float value) {
- return vec4((1.0 + value) * color.rgb, color.a);
-}
-
-vec4 apply_tonal(vec4 color) {
- return apply_gamma(
- apply_saturation(
- apply_contrast(
- apply_brightness(color, k_brightness),
- k_contrast
- ),
- k_saturation
- ),
- k_gamma
- );
-}
-vec3 rgb2hsv(vec3 c) {
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
-
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
-}
-
-vec3 hsv2rgb(vec3 c) {
- vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
- vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
- return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
-}
-highp float decode_f32(highp vec4 rgba) {
- highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
- highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
- if (abs(Exponent + 127.0) < 1e-3) {
- return 0.0;
- }
- highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
- highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
- return Result;
-}
-
-int decode_i32(vec4 rgba) {
- int r = int(rgba.r * 255.0 + 0.5);
- int g = int(rgba.g * 255.0 + 0.5);
- int b = int(rgba.b * 255.0 + 0.5);
- int a = int(rgba.a * 255.0 + 0.5);
-
- int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
-
- return value;
-}
-
-int decode_i16(vec2 rg) {
- int r = int(rg.r * 255.0 + 0.5);
- int g = int(rg.g * 255.0 + 0.5);
-
- int value = (r << 8) | g; // Combine into a 16-bit integer
-
- if (value >= 32768) {
- value -= 65536;
- }
-
- return value;
-}
-
-uint decode_u8(float r) {
- uint value = uint(r * 255.0 + 0.5);
- return value;
-}
-
-
-
-
-vec4 uvw2c_r(vec3 uv) {
- vec2 va = texture(tex, uv).ra;
-
- va.x = transfer_func(H, va.x, min_value, max_value);
-
- va.x = mix(va.x, 1.0 - va.x, reversed);
-
- vec4 c = colormap_f(va.x);
- return apply_tonal(c);
-}
-
-vec4 uvw2c_rgba(vec3 uv) {
- vec4 c = texture(tex, uv).rgba;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
- c.g = transfer_func(H, c.g, min_value, max_value);
- c.b = transfer_func(H, c.b, min_value, max_value);
-
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 uvw2c_ra(vec3 uv) {
- vec2 c = texture(tex, uv).rg;
-
- c.r = transfer_func(H, c.r, min_value, max_value);
-
- c.r = mix(c.r, 1.0 - c.r, reversed);
-
- vec3 color = colormap_f(c.r).rgb;
-
- return apply_tonal(vec4(color, c.g));
-}
-
-vec4 uvw2cmap_rgba(vec3 uv) {
- float v = texture(tex, uv).r;
- v = transfer_func(H, v, min_value, max_value);
- vec4 c = colormap_f(v);
- c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
-
- return apply_tonal(c);
-}
-
-vec4 val2c_f32(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
- return apply_tonal(new_color);
-}
-
-vec4 val2c(float x) {
- float alpha = x * scale + offset;
- alpha = transfer_func(H, alpha, min_value, max_value);
-
- alpha = mix(alpha, 1.0 - alpha, reversed);
-
- vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
- return apply_tonal(new_color);
-}
-
-vec4 uvw2c_f32(vec3 uv) {
- float val = decode_f32(texture(tex, uv).rgba*255.0);
- return val2c_f32(val);
-}
-
-vec4 uvw2c_i32(vec3 uv) {
- float val = float(decode_i32(texture(tex, uv).rgba));
- return val2c(val);
-}
-
-vec4 uvw2c_i16(vec3 uv) {
- float val = float(decode_i16(texture(tex, uv).rg));
- return val2c(val);
-}
-
-vec4 uvw2c_u8(vec3 uv) {
- float val = float(decode_u8(texture(tex, uv).r));
- return val2c(val);
-}
-const float TWICE_PI = 6.28318530718;
-const float PI = 3.141592653589793;
-const float FOUR_OVER_PI = 1.27323954474;
-const float TRANSITION_Z = 0.66666666666;
-const float TRANSITION_Z_INV = 1.5;
-
-int quarter(vec2 p) {
- int x_neg = int(p.x < 0.0);
- int y_neg = int(p.y < 0.0);
- int q = (x_neg + y_neg) | (y_neg << 1);
- return q;
-}
-
-float xpm1(vec2 p) {
- bool x_neg = (p.x < 0.0);
- bool y_neg = (p.y < 0.0);
- float lon = atan(abs(p.y), abs(p.x));
- float x02 = lon * FOUR_OVER_PI;
- if (x_neg != y_neg) { // Could be replaced by a sign copy from (x_neg ^ y_neg) << 32
- return 1.0 - x02;
- } else {
- return x02 - 1.0;
- }
-}
-
-float one_minus_z_pos(vec3 p) {
- float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
-
- if (d2 < 1e-1) { // <=> dec > 84.27 deg
- return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
- }
- return 1.0f - p.z;
-}
-
-float one_minus_z_neg(vec3 p) {
- float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
- if (d2 < 1e-1f) { // <=> dec < -84.27 deg
- return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
- }
- return p.z + 1.0;
-}
-
-int ij2z(int i, int j) {
- int i4 = i | (j << 2);
-
- int j4 = (i4 ^ (i4 >> 1)) & 0x22222222;
- int i5 = i4 ^ j4 ^ (j4 << 1);
-
- return i5;
-}
-
-struct HashDxDy {
- int idx;
- float dx;
- float dy;
-};
-
-uniform sampler2D ang2pixd;
-HashDxDy hash_with_dxdy2(vec2 radec) {
- vec2 aa = vec2(radec.x/TWICE_PI + 1.0, (radec.y/PI) + 0.5);
- vec3 v = texture(ang2pixd, aa).rgb;
- return HashDxDy(
- int(v.x * 255.0),
- v.y,
- v.z
- );
-}
-HashDxDy hash_with_dxdy(int depth, vec3 p) {
-
- int nside = 1 << depth;
- float half_nside = float(nside) * 0.5;
-
- float x_pm1 = xpm1(p.xy);
- int q = quarter(p.xy);
-
- int d0h = 0;
- vec2 p_proj = vec2(0.0);
- if (p.z > TRANSITION_Z) {
- float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_pos(p));
- p_proj = vec2(x_pm1 * sqrt_3_one_min_z, 2.0 - sqrt_3_one_min_z);
- d0h = q;
- } else if (p.z < -TRANSITION_Z) {
- float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_neg(p));
- p_proj = vec2(x_pm1 * sqrt_3_one_min_z, sqrt_3_one_min_z);
- d0h = q + 8;
- } else {
- float y_pm1 = p.z * TRANSITION_Z_INV;
- int q01 = int(x_pm1 > y_pm1); // 0/1
- int q12 = int(x_pm1 >= -y_pm1); // 0\1
- int q03 = 1 - q12; // 1\0
- int q1 = q01 & q12; // = 1 if q1, 0 else
- p_proj = vec2(
- x_pm1 - float(q01 + q12 - 1),
- y_pm1 + float(q01 + q03)
- );
- d0h = ((q01 + q03) << 2) + ((q + q1) & 3);
- }
-
- float x = (half_nside * (p_proj.x + p_proj.y));
- float y = (half_nside * (p_proj.y - p_proj.x));
- int i = int(x);
- int j = int(y);
-
- return HashDxDy(
- (d0h << (depth << 1)) + ij2z(i, j),
- x - float(i),
- y - float(j)
- );
-}
-vec3 xyz2uv(vec3 xyz) {
- HashDxDy result = hash_with_dxdy(0, xyz.zxy);
-
- int idx = result.idx;
- vec2 offset = vec2(result.dy, result.dx);
- Tile tile = textures_tiles[idx];
-
- return vec3(offset, float(tile.texture_idx));
-}
-
-void main() {
- vec3 uv = xyz2uv(normalize(frag_pos));
-
- uv.y = 1.0 - uv.y;
- vec4 c = uvw2c_i16(uv);
-
-
out_frag_color = c;
out_frag_color.a = out_frag_color.a * opacity;
}"#,
@@ -7766,6 +5066,2076 @@ void main() {
out_frag_color = c;
out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"hips_raytracer_backcolor.frag",
+ r#"#version 300 es
+precision lowp float;
+precision mediump int;
+
+out vec4 out_frag_color;
+
+uniform vec3 color;
+
+void main() {
+ out_frag_color = vec4(color, 1.0);
+}"#,
+ );
+ out.insert(
+ r"catalogs_mercator.vert",
+ r#"#version 300 es
+precision lowp float;
+layout (location = 0) in vec2 offset;
+layout (location = 1) in vec2 uv;
+layout (location = 2) in vec3 center;
+
+uniform float current_time;
+uniform mat3 inv_model;
+
+uniform vec2 ndc_to_clip;
+uniform float czf;
+uniform vec2 kernel_size;
+
+out vec2 out_uv;
+out vec3 out_p;
+
+const float PI = 3.141592653589793;
+const float SQRT_2 = 1.41421356237309504880168872420969808;
+
+vec2 w2c_sin(vec3 p) {
+ vec2 q = vec2(-p.x, p.y);
+ return p.z >= 0.f ? q : normalize(q);
+}
+
+vec2 w2c_sin_no_backface(vec3 p) {
+ return vec2(-p.x, p.y);
+}
+
+vec2 w2c_ait(vec3 p) {
+ float r = length(p.zx);
+ float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
+ w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
+ float y2d = p.y / w;
+
+ float x2d = 0.0;
+ if (abs(p.x) < 5e-3) {
+ float x_over_r = p.x/r;
+ x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
+ } else {
+ w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
+ x2d = sign(-p.x) * w;
+ }
+
+ return vec2(x2d * 0.5, y2d) / SQRT_2;
+}
+const float eps = 1.25e-8;
+const int n_iter = 100;
+
+float newton_solve(float z) {
+ float cte = PI * z;
+ float x = 2.0 * asin(z);
+ float f = x + sin(x) - cte;
+ int i = 0;
+ while (abs(f) > eps && i < n_iter) {
+ x -= f / (1.0 + cos(x));
+ f = x + sin(x) - cte;
+ i += 1;
+ }
+
+ return 0.5 * x;
+}
+
+vec2 w2c_mol(vec3 p) {
+ float g = newton_solve(p.y);
+
+ float sg = sin(g);
+ float cg = cos(g);
+ return vec2((atan(-p.x, p.z) * cg) / PI, sg);
+}
+vec2 w2c_tan(vec3 p) {
+ p.z = max(p.z, 1e-2);
+ return vec2(-p.x, p.y) / (p.z*PI);
+}
+vec2 w2c_stg(vec3 p) {
+ float w = (1.0 + p.z) * 0.5;
+ return vec2(-p.x, p.y) / (PI * w);
+}
+vec2 w2c_zea(vec3 p) {
+ float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
+ return vec2(-p.x, p.y) * 0.5 / w;
+}
+vec2 w2c_mer(vec3 p) {
+ return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
+}
+
+vec3 lonlat2xyz(vec2 lonlat) {
+ float t = lonlat.x;
+ float tc = cos(t);
+ float ts = sin(t);
+
+ float d = lonlat.y;
+ float dc = cos(d);
+ float ds = sin(d);
+
+ return vec3(dc * ts, ds, dc * tc);
+}
+
+uniform int u_proj;
+
+vec2 proj(vec3 p) {
+ if (u_proj == 0) {
+ return w2c_tan(p);
+ } else if (u_proj == 1) {
+ return w2c_stg(p);
+ } else if (u_proj == 2) {
+ return w2c_sin(p);
+ } else if (u_proj == 3) {
+ return w2c_zea(p);
+ } else if (u_proj == 4) {
+ return w2c_ait(p);
+ } else if (u_proj == 5) {
+ return w2c_mol(p);
+ } else {
+ return w2c_mer(p);
+ }
+}
+
+
+void main() {
+ vec3 p = inv_model * center;
+
+ vec2 center_pos_clip_space = world2clip_mercator(p);
+
+ vec2 pos_clip_space = center_pos_clip_space;
+ gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
+
+ out_uv = uv;
+ out_p = p;
+}"#,
+ );
+ out.insert(
+ r"fits_base.vert",
+ r#"#version 300 es
+precision highp float;
+precision highp int;
+
+layout (location = 0) in vec2 ndc_pos;
+layout (location = 1) in vec2 uv;
+
+out vec2 frag_uv;
+
+void main() {
+ gl_Position = vec4(ndc_pos, 0.0, 1.0);
+ frag_uv = uv;
+}"#,
+ );
+ out.insert(
+ r"hips_raytracer_raytracer.vert",
+ r#"#version 300 es
+precision lowp float;
+precision mediump int;
+
+layout (location = 0) in vec2 pos_clip_space;
+layout (location = 1) in vec3 pos_world_space;
+
+out vec2 out_clip_pos;
+out vec3 frag_pos;
+
+uniform vec2 ndc_to_clip;
+uniform float czf;
+uniform mat3 model;
+
+void main() {
+ vec2 uv = pos_clip_space * 0.5 + 0.5;
+
+ frag_pos = model * pos_world_space;
+
+ gl_Position = vec4(pos_clip_space / (ndc_to_clip * czf), 0.0, 1.0);
+ out_clip_pos = pos_clip_space;
+}"#,
+ );
+ out.insert(
+ r"catalogs_tan.vert",
+ r#"#version 300 es
+precision lowp float;
+
+layout (location = 0) in vec2 offset;
+layout (location = 1) in vec2 uv;
+layout (location = 2) in vec3 center;
+
+uniform float current_time;
+uniform mat3 inv_model;
+
+uniform vec2 ndc_to_clip;
+uniform float czf;
+uniform vec2 kernel_size;
+
+out vec2 out_uv;
+out vec3 out_p;
+
+const float PI = 3.141592653589793;
+const float SQRT_2 = 1.41421356237309504880168872420969808;
+
+vec2 w2c_sin(vec3 p) {
+ vec2 q = vec2(-p.x, p.y);
+ return p.z >= 0.f ? q : normalize(q);
+}
+
+vec2 w2c_sin_no_backface(vec3 p) {
+ return vec2(-p.x, p.y);
+}
+
+vec2 w2c_ait(vec3 p) {
+ float r = length(p.zx);
+ float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
+ w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
+ float y2d = p.y / w;
+
+ float x2d = 0.0;
+ if (abs(p.x) < 5e-3) {
+ float x_over_r = p.x/r;
+ x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
+ } else {
+ w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
+ x2d = sign(-p.x) * w;
+ }
+
+ return vec2(x2d * 0.5, y2d) / SQRT_2;
+}
+const float eps = 1.25e-8;
+const int n_iter = 100;
+
+float newton_solve(float z) {
+ float cte = PI * z;
+ float x = 2.0 * asin(z);
+ float f = x + sin(x) - cte;
+ int i = 0;
+ while (abs(f) > eps && i < n_iter) {
+ x -= f / (1.0 + cos(x));
+ f = x + sin(x) - cte;
+ i += 1;
+ }
+
+ return 0.5 * x;
+}
+
+vec2 w2c_mol(vec3 p) {
+ float g = newton_solve(p.y);
+
+ float sg = sin(g);
+ float cg = cos(g);
+ return vec2((atan(-p.x, p.z) * cg) / PI, sg);
+}
+vec2 w2c_tan(vec3 p) {
+ p.z = max(p.z, 1e-2);
+ return vec2(-p.x, p.y) / (p.z*PI);
+}
+vec2 w2c_stg(vec3 p) {
+ float w = (1.0 + p.z) * 0.5;
+ return vec2(-p.x, p.y) / (PI * w);
+}
+vec2 w2c_zea(vec3 p) {
+ float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
+ return vec2(-p.x, p.y) * 0.5 / w;
+}
+vec2 w2c_mer(vec3 p) {
+ return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
+}
+
+vec3 lonlat2xyz(vec2 lonlat) {
+ float t = lonlat.x;
+ float tc = cos(t);
+ float ts = sin(t);
+
+ float d = lonlat.y;
+ float dc = cos(d);
+ float ds = sin(d);
+
+ return vec3(dc * ts, ds, dc * tc);
+}
+
+uniform int u_proj;
+
+vec2 proj(vec3 p) {
+ if (u_proj == 0) {
+ return w2c_tan(p);
+ } else if (u_proj == 1) {
+ return w2c_stg(p);
+ } else if (u_proj == 2) {
+ return w2c_sin(p);
+ } else if (u_proj == 3) {
+ return w2c_zea(p);
+ } else if (u_proj == 4) {
+ return w2c_ait(p);
+ } else if (u_proj == 5) {
+ return w2c_mol(p);
+ } else {
+ return w2c_mer(p);
+ }
+}
+
+
+void main() {
+ vec3 p = inv_model * center;
+
+ vec2 center_pos_clip_space = world2clip_gnomonic(p);
+
+ vec2 pos_clip_space = center_pos_clip_space;
+ gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
+
+ out_uv = uv;
+ out_p = p;
+}"#,
+ );
+ out.insert(
+ r"catalogs_healpix.vert",
+ r#"#version 300 es
+precision lowp float;
+layout (location = 0) in vec2 offset;
+layout (location = 1) in vec2 uv;
+layout (location = 2) in vec3 center;
+
+uniform float current_time;
+uniform mat3 inv_model;
+
+uniform vec2 ndc_to_clip;
+uniform float czf;
+uniform vec2 kernel_size;
+
+out vec2 out_uv;
+out vec3 out_p;
+
+const float PI = 3.141592653589793;
+const float SQRT_2 = 1.41421356237309504880168872420969808;
+
+vec2 w2c_sin(vec3 p) {
+ vec2 q = vec2(-p.x, p.y);
+ return p.z >= 0.f ? q : normalize(q);
+}
+
+vec2 w2c_sin_no_backface(vec3 p) {
+ return vec2(-p.x, p.y);
+}
+
+vec2 w2c_ait(vec3 p) {
+ float r = length(p.zx);
+ float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
+ w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
+ float y2d = p.y / w;
+
+ float x2d = 0.0;
+ if (abs(p.x) < 5e-3) {
+ float x_over_r = p.x/r;
+ x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
+ } else {
+ w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
+ x2d = sign(-p.x) * w;
+ }
+
+ return vec2(x2d * 0.5, y2d) / SQRT_2;
+}
+const float eps = 1.25e-8;
+const int n_iter = 100;
+
+float newton_solve(float z) {
+ float cte = PI * z;
+ float x = 2.0 * asin(z);
+ float f = x + sin(x) - cte;
+ int i = 0;
+ while (abs(f) > eps && i < n_iter) {
+ x -= f / (1.0 + cos(x));
+ f = x + sin(x) - cte;
+ i += 1;
+ }
+
+ return 0.5 * x;
+}
+
+vec2 w2c_mol(vec3 p) {
+ float g = newton_solve(p.y);
+
+ float sg = sin(g);
+ float cg = cos(g);
+ return vec2((atan(-p.x, p.z) * cg) / PI, sg);
+}
+vec2 w2c_tan(vec3 p) {
+ p.z = max(p.z, 1e-2);
+ return vec2(-p.x, p.y) / (p.z*PI);
+}
+vec2 w2c_stg(vec3 p) {
+ float w = (1.0 + p.z) * 0.5;
+ return vec2(-p.x, p.y) / (PI * w);
+}
+vec2 w2c_zea(vec3 p) {
+ float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
+ return vec2(-p.x, p.y) * 0.5 / w;
+}
+vec2 w2c_mer(vec3 p) {
+ return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
+}
+
+vec3 lonlat2xyz(vec2 lonlat) {
+ float t = lonlat.x;
+ float tc = cos(t);
+ float ts = sin(t);
+
+ float d = lonlat.y;
+ float dc = cos(d);
+ float ds = sin(d);
+
+ return vec3(dc * ts, ds, dc * tc);
+}
+
+uniform int u_proj;
+
+vec2 proj(vec3 p) {
+ if (u_proj == 0) {
+ return w2c_tan(p);
+ } else if (u_proj == 1) {
+ return w2c_stg(p);
+ } else if (u_proj == 2) {
+ return w2c_sin(p);
+ } else if (u_proj == 3) {
+ return w2c_zea(p);
+ } else if (u_proj == 4) {
+ return w2c_ait(p);
+ } else if (u_proj == 5) {
+ return w2c_mol(p);
+ } else {
+ return w2c_mer(p);
+ }
+}
+
+
+void main() {
+ vec3 p = inv_model * center;
+
+ vec2 center_pos_clip_space = world2clip_healpix(p);
+
+ vec2 pos_clip_space = center_pos_clip_space;
+ gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
+
+ out_uv = uv;
+ out_p = p;
+}"#,
+ );
+ out.insert(
+ r"hips3d_u8.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler3D;
+
+uniform sampler3D tex;
+
+in vec3 frag_uv;
+
+out vec4 out_frag_color;
+
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
+
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
+
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
+ } else {
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uvw2c_f32(vec3 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uvw2c_i32(vec3 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uvw2c_i16(vec3 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uvw2c_u8(vec3 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
+
+uniform float opacity;
+
+void main() {
+ vec3 uv = vec3(frag_uv.xyz);
+ uv.y = 1.0 - uv.y;
+
+ vec4 color = uvw2c_u8(uv);
+
+ out_frag_color = color;
+ out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"hips_rasterizer_rgba.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2DArray;
+
+uniform sampler2DArray tex;
+
+in vec3 frag_uv_start;
+in vec3 frag_uv_end;
+in float frag_blending_factor;
+
+out vec4 out_frag_color;
+uniform float opacity;
+
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
+
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
+
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
+ } else {
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uvw2c_f32(vec3 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uvw2c_i32(vec3 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uvw2c_i16(vec3 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uvw2c_u8(vec3 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
+
+void main() {
+ vec4 color_start = uvw2c_rgba(frag_uv_start);
+ vec4 color_end = uvw2c_rgba(frag_uv_end);
+
+ out_frag_color = mix(color_start, color_end, frag_blending_factor);
+ out_frag_color.a = opacity * out_frag_color.a;
+}"#,
+ );
+ out.insert(
+ r"hips_rasterizer_raster.vert",
+ r#"#version 300 es
+precision highp float;
+
+layout (location = 0) in vec3 xyz;
+layout (location = 1) in vec3 uv_start;
+layout (location = 2) in vec3 uv_end;
+layout (location = 3) in float time_tile_received;
+
+out vec3 frag_uv_start;
+out vec3 frag_uv_end;
+out float frag_blending_factor;
+
+uniform mat3 inv_model;
+uniform vec2 ndc_to_clip;
+uniform float czf;
+uniform float current_time;
+
+const float PI = 3.141592653589793;
+const float SQRT_2 = 1.41421356237309504880168872420969808;
+
+vec2 w2c_sin(vec3 p) {
+ vec2 q = vec2(-p.x, p.y);
+ return p.z >= 0.f ? q : normalize(q);
+}
+
+vec2 w2c_sin_no_backface(vec3 p) {
+ return vec2(-p.x, p.y);
+}
+
+vec2 w2c_ait(vec3 p) {
+ float r = length(p.zx);
+ float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
+ w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
+ float y2d = p.y / w;
+
+ float x2d = 0.0;
+ if (abs(p.x) < 5e-3) {
+ float x_over_r = p.x/r;
+ x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
+ } else {
+ w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
+ x2d = sign(-p.x) * w;
+ }
+
+ return vec2(x2d * 0.5, y2d) / SQRT_2;
+}
+const float eps = 1.25e-8;
+const int n_iter = 100;
+
+float newton_solve(float z) {
+ float cte = PI * z;
+ float x = 2.0 * asin(z);
+ float f = x + sin(x) - cte;
+ int i = 0;
+ while (abs(f) > eps && i < n_iter) {
+ x -= f / (1.0 + cos(x));
+ f = x + sin(x) - cte;
+ i += 1;
+ }
+
+ return 0.5 * x;
+}
+
+vec2 w2c_mol(vec3 p) {
+ float g = newton_solve(p.y);
+
+ float sg = sin(g);
+ float cg = cos(g);
+ return vec2((atan(-p.x, p.z) * cg) / PI, sg);
+}
+vec2 w2c_tan(vec3 p) {
+ p.z = max(p.z, 1e-2);
+ return vec2(-p.x, p.y) / (p.z*PI);
+}
+vec2 w2c_stg(vec3 p) {
+ float w = (1.0 + p.z) * 0.5;
+ return vec2(-p.x, p.y) / (PI * w);
+}
+vec2 w2c_zea(vec3 p) {
+ float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
+ return vec2(-p.x, p.y) * 0.5 / w;
+}
+vec2 w2c_mer(vec3 p) {
+ return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
+}
+
+vec3 lonlat2xyz(vec2 lonlat) {
+ float t = lonlat.x;
+ float tc = cos(t);
+ float ts = sin(t);
+
+ float d = lonlat.y;
+ float dc = cos(d);
+ float ds = sin(d);
+
+ return vec3(dc * ts, ds, dc * tc);
+}
+
+uniform int u_proj;
+
+vec2 proj(vec3 p) {
+ if (u_proj == 0) {
+ return w2c_tan(p);
+ } else if (u_proj == 1) {
+ return w2c_stg(p);
+ } else if (u_proj == 2) {
+ return w2c_sin(p);
+ } else if (u_proj == 3) {
+ return w2c_zea(p);
+ } else if (u_proj == 4) {
+ return w2c_ait(p);
+ } else if (u_proj == 5) {
+ return w2c_mol(p);
+ } else {
+ return w2c_mer(p);
+ }
+}
+
+void main() {
+ vec3 p_w = inv_model * xyz;
+ vec2 p_clip = proj(p_w);
+
+ vec2 p_ndc = p_clip / (ndc_to_clip * czf);
+ gl_Position = vec4(p_ndc, 0.0, 1.0);
+
+ frag_uv_start = uv_start;
+ frag_uv_end = uv_end;
+ frag_blending_factor = min((current_time - time_tile_received) / 200.0, 1.0);
+}"#,
+ );
+ out.insert(
+ r"hips_raytracer_u8.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2DArray;
+precision lowp usampler2DArray;
+precision lowp isampler2DArray;
+precision mediump int;
+
+uniform sampler2DArray tex;
+
+in vec3 frag_pos;
+in vec2 out_clip_pos;
+out vec4 out_frag_color;
+
+struct Tile {
+ int uniq; // Healpix cell
+ int texture_idx; // Index in the texture buffer
+ float start_time; // Absolute time that the load has been done in ms
+ float empty;
+};
+
+uniform Tile textures_tiles[12];
+
+uniform float opacity;
+
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
+
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
+
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
+ } else {
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uvw2c_f32(vec3 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uvw2c_i32(vec3 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uvw2c_i16(vec3 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uvw2c_u8(vec3 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
+const float TWICE_PI = 6.28318530718;
+const float PI = 3.141592653589793;
+const float FOUR_OVER_PI = 1.27323954474;
+const float TRANSITION_Z = 0.66666666666;
+const float TRANSITION_Z_INV = 1.5;
+
+int quarter(vec2 p) {
+ int x_neg = int(p.x < 0.0);
+ int y_neg = int(p.y < 0.0);
+ int q = (x_neg + y_neg) | (y_neg << 1);
+ return q;
+}
+
+float xpm1(vec2 p) {
+ bool x_neg = (p.x < 0.0);
+ bool y_neg = (p.y < 0.0);
+ float lon = atan(abs(p.y), abs(p.x));
+ float x02 = lon * FOUR_OVER_PI;
+ if (x_neg != y_neg) { // Could be replaced by a sign copy from (x_neg ^ y_neg) << 32
+ return 1.0 - x02;
+ } else {
+ return x02 - 1.0;
+ }
+}
+
+float one_minus_z_pos(vec3 p) {
+ float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
+
+ if (d2 < 1e-1) { // <=> dec > 84.27 deg
+ return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
+ }
+ return 1.0f - p.z;
+}
+
+float one_minus_z_neg(vec3 p) {
+ float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
+ if (d2 < 1e-1f) { // <=> dec < -84.27 deg
+ return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
+ }
+ return p.z + 1.0;
+}
+
+int ij2z(int i, int j) {
+ int i4 = i | (j << 2);
+
+ int j4 = (i4 ^ (i4 >> 1)) & 0x22222222;
+ int i5 = i4 ^ j4 ^ (j4 << 1);
+
+ return i5;
+}
+
+struct HashDxDy {
+ int idx;
+ float dx;
+ float dy;
+};
+
+uniform sampler2D ang2pixd;
+HashDxDy hash_with_dxdy2(vec2 radec) {
+ vec2 aa = vec2(radec.x/TWICE_PI + 1.0, (radec.y/PI) + 0.5);
+ vec3 v = texture(ang2pixd, aa).rgb;
+ return HashDxDy(
+ int(v.x * 255.0),
+ v.y,
+ v.z
+ );
+}
+HashDxDy hash_with_dxdy(int depth, vec3 p) {
+
+ int nside = 1 << depth;
+ float half_nside = float(nside) * 0.5;
+
+ float x_pm1 = xpm1(p.xy);
+ int q = quarter(p.xy);
+
+ int d0h = 0;
+ vec2 p_proj = vec2(0.0);
+ if (p.z > TRANSITION_Z) {
+ float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_pos(p));
+ p_proj = vec2(x_pm1 * sqrt_3_one_min_z, 2.0 - sqrt_3_one_min_z);
+ d0h = q;
+ } else if (p.z < -TRANSITION_Z) {
+ float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_neg(p));
+ p_proj = vec2(x_pm1 * sqrt_3_one_min_z, sqrt_3_one_min_z);
+ d0h = q + 8;
+ } else {
+ float y_pm1 = p.z * TRANSITION_Z_INV;
+ int q01 = int(x_pm1 > y_pm1); // 0/1
+ int q12 = int(x_pm1 >= -y_pm1); // 0\1
+ int q03 = 1 - q12; // 1\0
+ int q1 = q01 & q12; // = 1 if q1, 0 else
+ p_proj = vec2(
+ x_pm1 - float(q01 + q12 - 1),
+ y_pm1 + float(q01 + q03)
+ );
+ d0h = ((q01 + q03) << 2) + ((q + q1) & 3);
+ }
+
+ float x = (half_nside * (p_proj.x + p_proj.y));
+ float y = (half_nside * (p_proj.y - p_proj.x));
+ int i = int(x);
+ int j = int(y);
+
+ return HashDxDy(
+ (d0h << (depth << 1)) + ij2z(i, j),
+ x - float(i),
+ y - float(j)
+ );
+}
+vec3 xyz2uv(vec3 xyz) {
+ HashDxDy result = hash_with_dxdy(0, xyz.zxy);
+
+ int idx = result.idx;
+ vec2 offset = vec2(result.dy, result.dx);
+ Tile tile = textures_tiles[idx];
+
+ return vec3(offset, float(tile.texture_idx));
+}
+
+void main() {
+ vec3 uv = xyz2uv(normalize(frag_pos));
+
+ uv.y = 1.0 - uv.y;
+ vec4 c = uvw2c_u8(uv);
+
+
+ out_frag_color = c;
+ out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"hips_rasterizer_u8.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2DArray;
+
+uniform sampler2DArray tex;
+
+in vec3 frag_uv_start;
+in vec3 frag_uv_end;
+in float frag_blending_factor;
+
+out vec4 out_frag_color;
+
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
+
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
+
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
+ } else {
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uvw2c_f32(vec3 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uvw2c_i32(vec3 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uvw2c_i16(vec3 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uvw2c_u8(vec3 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
+
+uniform float opacity;
+
+void main() {
+ vec3 uv0 = frag_uv_start;
+ vec3 uv1 = frag_uv_end;
+ uv0.y = 1.0 - uv0.y;
+ uv1.y = 1.0 - uv1.y;
+
+ vec4 color_start = uvw2c_u8(uv0);
+ vec4 color_end = uvw2c_u8(uv1);
+
+ out_frag_color = mix(color_start, color_end, frag_blending_factor);
+ out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"hips_rasterizer_i32.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2DArray;
+
+uniform sampler2DArray tex;
+
+in vec3 frag_uv_start;
+in vec3 frag_uv_end;
+in float frag_blending_factor;
+
+out vec4 out_frag_color;
+
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
+
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
+
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
+ } else {
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uvw2c_f32(vec3 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uvw2c_i32(vec3 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uvw2c_i16(vec3 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uvw2c_u8(vec3 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
+
+uniform float opacity;
+
+void main() {
+ vec3 uv0 = frag_uv_start;
+ vec3 uv1 = frag_uv_end;
+ uv0.y = 1.0 - uv0.y;
+ uv1.y = 1.0 - uv1.y;
+
+ vec4 color_start = uvw2c_i32(uv0);
+ vec4 color_end = uvw2c_i32(uv1);
+
+ out_frag_color = mix(color_start, color_end, frag_blending_factor);
+ out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"line_base.vert",
+ r#"#version 300 es
+precision highp float;
+layout (location = 0) in vec2 ndc_pos;
+
+out float l;
+
+void main() {
+ gl_Position = vec4(
+ ndc_pos,
+ 0.0,
+ 1.0
+ );
}"#,
);
out.insert(
@@ -7897,6 +7267,636 @@ void main() {
out_uv = uv;
out_p = p;
+}"#,
+ );
+ out.insert(
+ r"catalogs_arc.vert",
+ r#"#version 300 es
+precision lowp float;
+layout (location = 0) in vec2 offset;
+layout (location = 1) in vec2 uv;
+layout (location = 2) in vec3 center;
+
+uniform float current_time;
+uniform mat3 inv_model;
+
+uniform vec2 ndc_to_clip;
+uniform float czf;
+uniform vec2 kernel_size;
+
+out vec2 out_uv;
+out vec3 out_p;
+
+const float PI = 3.141592653589793;
+const float SQRT_2 = 1.41421356237309504880168872420969808;
+
+vec2 w2c_sin(vec3 p) {
+ vec2 q = vec2(-p.x, p.y);
+ return p.z >= 0.f ? q : normalize(q);
+}
+
+vec2 w2c_sin_no_backface(vec3 p) {
+ return vec2(-p.x, p.y);
+}
+
+vec2 w2c_ait(vec3 p) {
+ float r = length(p.zx);
+ float w = sqrt((r * (r + p.z)) * 0.5f); // = cos(b) cos(l/2)
+ w = sqrt((1.0 + w) * 0.5f); // = 1 / gamma
+ float y2d = p.y / w;
+
+ float x2d = 0.0;
+ if (abs(p.x) < 5e-3) {
+ float x_over_r = p.x/r;
+ x2d = -p.x * (1.0 - x_over_r*x_over_r/21.0) / w;
+ } else {
+ w = sqrt((r*r - r*p.z) * 2.0) / w; // = 2 * gamma * cos(b) sin(l/2)
+ x2d = sign(-p.x) * w;
+ }
+
+ return vec2(x2d * 0.5, y2d) / SQRT_2;
+}
+const float eps = 1.25e-8;
+const int n_iter = 100;
+
+float newton_solve(float z) {
+ float cte = PI * z;
+ float x = 2.0 * asin(z);
+ float f = x + sin(x) - cte;
+ int i = 0;
+ while (abs(f) > eps && i < n_iter) {
+ x -= f / (1.0 + cos(x));
+ f = x + sin(x) - cte;
+ i += 1;
+ }
+
+ return 0.5 * x;
+}
+
+vec2 w2c_mol(vec3 p) {
+ float g = newton_solve(p.y);
+
+ float sg = sin(g);
+ float cg = cos(g);
+ return vec2((atan(-p.x, p.z) * cg) / PI, sg);
+}
+vec2 w2c_tan(vec3 p) {
+ p.z = max(p.z, 1e-2);
+ return vec2(-p.x, p.y) / (p.z*PI);
+}
+vec2 w2c_stg(vec3 p) {
+ float w = (1.0 + p.z) * 0.5;
+ return vec2(-p.x, p.y) / (PI * w);
+}
+vec2 w2c_zea(vec3 p) {
+ float w = sqrt(0.5 + 0.5 * p.z); // <=> sqrt[(1 + x) / 2]
+ return vec2(-p.x, p.y) * 0.5 / w;
+}
+vec2 w2c_mer(vec3 p) {
+ return vec2(atan(-p.x, p.z), atanh(p.y)) / PI;
+}
+
+vec3 lonlat2xyz(vec2 lonlat) {
+ float t = lonlat.x;
+ float tc = cos(t);
+ float ts = sin(t);
+
+ float d = lonlat.y;
+ float dc = cos(d);
+ float ds = sin(d);
+
+ return vec3(dc * ts, ds, dc * tc);
+}
+
+uniform int u_proj;
+
+vec2 proj(vec3 p) {
+ if (u_proj == 0) {
+ return w2c_tan(p);
+ } else if (u_proj == 1) {
+ return w2c_stg(p);
+ } else if (u_proj == 2) {
+ return w2c_sin(p);
+ } else if (u_proj == 3) {
+ return w2c_zea(p);
+ } else if (u_proj == 4) {
+ return w2c_ait(p);
+ } else if (u_proj == 5) {
+ return w2c_mol(p);
+ } else {
+ return w2c_mer(p);
+ }
+}
+
+void main() {
+ vec3 p = inv_model * center;
+
+ vec2 center_pos_clip_space = world2clip_arc(p);
+
+ vec2 pos_clip_space = center_pos_clip_space;
+ gl_Position = vec4((pos_clip_space / (ndc_to_clip * czf)) + offset * kernel_size , 0.f, 1.f);
+
+ out_uv = uv;
+ out_p = p;
+}"#,
+ );
+ out.insert(
+ r"passes_post_fragment_100es.frag",
+ r#"#version 300 es
+precision mediump float;
+
+in vec2 v_tc;
+out vec4 color;
+
+uniform sampler2D fbo_tex;
+
+vec3 srgb_from_linear(vec3 rgb) {
+ bvec3 cutoff = lessThan(rgb, vec3(0.0031308));
+ vec3 lower = rgb * vec3(3294.6);
+ vec3 higher = vec3(269.025) * pow(rgb, vec3(1.0 / 2.4)) - vec3(14.025);
+ return mix(higher, lower, vec3(cutoff));
+}
+
+vec4 srgba_from_linear(vec4 rgba) {
+ return vec4(srgb_from_linear(rgba.rgb), 255.0 * rgba.a);
+}
+
+void main() {
+ color = texture(fbo_tex, v_tc);
+
+}"#,
+ );
+ out.insert(
+ r"passes_post_vertex_100es.vert",
+ r#"#version 300 es
+precision mediump float;
+
+layout (location = 0) in vec2 a_pos;
+out vec2 v_tc;
+
+void main() {
+ gl_Position = vec4(a_pos * 2. - 1., 0.0, 1.0);
+ v_tc = a_pos;
+}"#,
+ );
+ out.insert(
+ r"catalogs_catalog.frag",
+ r#"#version 300 es
+precision lowp float;
+
+in vec2 out_uv;
+in vec3 out_p;
+
+out vec4 color;
+
+uniform sampler2D kernel_texture;
+uniform float max_density; // max number of sources in a kernel sized HEALPix cell at the current depth
+uniform float fov;
+uniform float strength;
+void main() {
+ color = texture(kernel_texture, out_uv) / max(log2(fov*100.0), 1.0);
+ color.r *= strength;
+}"#,
+ );
+ out.insert(
+ r"colormaps_colormap.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2D;
+
+in vec2 out_uv;
+out vec4 color;
+
+uniform sampler2D texture_fbo;
+uniform float alpha;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+
+void main() {
+ float opacity = texture(texture_fbo, out_uv).r;
+
+ float o = smoothstep(0.0, 0.1, opacity);
+
+ color = colormap_f(opacity);
+ color.a = o * alpha;
+}"#,
+ );
+ out.insert(
+ r"hips_raytracer_i32.frag",
+ r#"#version 300 es
+precision lowp float;
+precision lowp sampler2DArray;
+precision lowp usampler2DArray;
+precision lowp isampler2DArray;
+precision mediump int;
+
+uniform sampler2DArray tex;
+
+in vec3 frag_pos;
+in vec2 out_clip_pos;
+out vec4 out_frag_color;
+
+struct Tile {
+ int uniq; // Healpix cell
+ int texture_idx; // Index in the texture buffer
+ float start_time; // Absolute time that the load has been done in ms
+ float empty;
+};
+
+uniform Tile textures_tiles[12];
+
+uniform float opacity;
+
+const float TWICE_PI = 6.28318530718;
+const float PI = 3.141592653589793;
+const float FOUR_OVER_PI = 1.27323954474;
+const float TRANSITION_Z = 0.66666666666;
+const float TRANSITION_Z_INV = 1.5;
+
+int quarter(vec2 p) {
+ int x_neg = int(p.x < 0.0);
+ int y_neg = int(p.y < 0.0);
+ int q = (x_neg + y_neg) | (y_neg << 1);
+ return q;
+}
+
+float xpm1(vec2 p) {
+ bool x_neg = (p.x < 0.0);
+ bool y_neg = (p.y < 0.0);
+ float lon = atan(abs(p.y), abs(p.x));
+ float x02 = lon * FOUR_OVER_PI;
+ if (x_neg != y_neg) { // Could be replaced by a sign copy from (x_neg ^ y_neg) << 32
+ return 1.0 - x02;
+ } else {
+ return x02 - 1.0;
+ }
+}
+
+float one_minus_z_pos(vec3 p) {
+ float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
+
+ if (d2 < 1e-1) { // <=> dec > 84.27 deg
+ return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
+ }
+ return 1.0f - p.z;
+}
+
+float one_minus_z_neg(vec3 p) {
+ float d2 = dot(p.xy, p.xy); // z = sqrt(1 - d2) AND sqrt(1 - x) = 1 - x / 2 - x^2 / 8 - x^3 / 16 - 5 x^4/128 - 7 * x^5/256
+ if (d2 < 1e-1f) { // <=> dec < -84.27 deg
+ return d2 * (0.5 + d2 * (0.125 + d2 * (0.0625 + d2 * (0.0390625 + d2 * 0.02734375))));
+ }
+ return p.z + 1.0;
+}
+
+int ij2z(int i, int j) {
+ int i4 = i | (j << 2);
+
+ int j4 = (i4 ^ (i4 >> 1)) & 0x22222222;
+ int i5 = i4 ^ j4 ^ (j4 << 1);
+
+ return i5;
+}
+
+struct HashDxDy {
+ int idx;
+ float dx;
+ float dy;
+};
+
+uniform sampler2D ang2pixd;
+HashDxDy hash_with_dxdy2(vec2 radec) {
+ vec2 aa = vec2(radec.x/TWICE_PI + 1.0, (radec.y/PI) + 0.5);
+ vec3 v = texture(ang2pixd, aa).rgb;
+ return HashDxDy(
+ int(v.x * 255.0),
+ v.y,
+ v.z
+ );
+}
+HashDxDy hash_with_dxdy(int depth, vec3 p) {
+
+ int nside = 1 << depth;
+ float half_nside = float(nside) * 0.5;
+
+ float x_pm1 = xpm1(p.xy);
+ int q = quarter(p.xy);
+
+ int d0h = 0;
+ vec2 p_proj = vec2(0.0);
+ if (p.z > TRANSITION_Z) {
+ float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_pos(p));
+ p_proj = vec2(x_pm1 * sqrt_3_one_min_z, 2.0 - sqrt_3_one_min_z);
+ d0h = q;
+ } else if (p.z < -TRANSITION_Z) {
+ float sqrt_3_one_min_z = sqrt(3.0 * one_minus_z_neg(p));
+ p_proj = vec2(x_pm1 * sqrt_3_one_min_z, sqrt_3_one_min_z);
+ d0h = q + 8;
+ } else {
+ float y_pm1 = p.z * TRANSITION_Z_INV;
+ int q01 = int(x_pm1 > y_pm1); // 0/1
+ int q12 = int(x_pm1 >= -y_pm1); // 0\1
+ int q03 = 1 - q12; // 1\0
+ int q1 = q01 & q12; // = 1 if q1, 0 else
+ p_proj = vec2(
+ x_pm1 - float(q01 + q12 - 1),
+ y_pm1 + float(q01 + q03)
+ );
+ d0h = ((q01 + q03) << 2) + ((q + q1) & 3);
+ }
+
+ float x = (half_nside * (p_proj.x + p_proj.y));
+ float y = (half_nside * (p_proj.y - p_proj.x));
+ int i = int(x);
+ int j = int(y);
+
+ return HashDxDy(
+ (d0h << (depth << 1)) + ij2z(i, j),
+ x - float(i),
+ y - float(j)
+ );
+}
+vec3 xyz2uv(vec3 xyz) {
+ HashDxDy result = hash_with_dxdy(0, xyz.zxy);
+
+ int idx = result.idx;
+ vec2 offset = vec2(result.dy, result.dx);
+ Tile tile = textures_tiles[idx];
+
+ return vec3(offset, float(tile.texture_idx));
+}
+uniform float scale;
+uniform float offset;
+uniform float blank;
+uniform float min_value;
+uniform float max_value;
+uniform int H;
+uniform float reversed;
+
+uniform sampler2D colormaps;
+uniform float num_colormaps;
+uniform float colormap_id;
+
+vec4 colormap_f(float x) {
+ float id = (colormap_id + 0.5) / num_colormaps;
+ return texture(colormaps, vec2(x, id));
+}
+float linear_f(float x, float min_value, float max_value) {
+ return clamp((x - min_value)/(max_value - min_value), 0.0, 1.0);
+}
+
+float sqrt_f(float x, float min_value, float max_value) {
+ float a = linear_f(x, min_value, max_value);
+ return sqrt(a);
+}
+
+float log_f(float x, float min_value, float max_value) {
+ float y = linear_f(x, min_value, max_value);
+ float a = 1000.0;
+ return log(a*y + 1.0)/log(a);
+}
+
+float asinh_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return asinh(10.0*d)/3.0;
+}
+
+float pow2_f(float x, float min_value, float max_value) {
+ float d = linear_f(x, min_value, max_value);
+ return d*d;
+}
+
+float transfer_func(int H, float x, float min_value, float max_value) {
+ if (H == 0) {
+ return linear_f(x, min_value, max_value);
+ } else if (H == 1) {
+ return sqrt_f(x, min_value, max_value);
+ } else if (H == 2) {
+ return log_f(x, min_value, max_value);
+ } else if (H == 3) {
+ return asinh_f(x, min_value, max_value);
+ } else {
+ return pow2_f(x, min_value, max_value);
+ }
+}
+
+uniform float k_gamma;
+uniform float k_saturation;
+uniform float k_contrast;
+uniform float k_brightness;
+uniform float k_exposure;
+
+vec4 apply_gamma(vec4 ic, float g) {
+ float new_r = pow(ic.r, g);
+ float new_g = pow(ic.g, g);
+ float new_b = pow(ic.b, g);
+
+ return vec4(new_r, new_g, new_b, ic.a);
+}
+
+vec4 apply_saturation(vec4 color, float value) {
+ const vec3 luminosity_factor = vec3(0.2126, 0.7152, 0.0722);
+ vec3 grayscale = vec3(dot(color.rgb, luminosity_factor));
+
+ return vec4(mix(grayscale, color.rgb, 1.0 + value), color.a);
+}
+
+vec4 apply_contrast(vec4 color, float value) {
+ return vec4(0.5 + (1.0 + value) * (color.rgb - 0.5), color.a);
+}
+
+vec4 apply_brightness(vec4 color, float value) {
+ return vec4(color.rgb + value, color.a);
+}
+
+vec4 apply_exposure(vec4 color, float value) {
+ return vec4((1.0 + value) * color.rgb, color.a);
+}
+
+vec4 apply_tonal(vec4 color) {
+ return apply_gamma(
+ apply_saturation(
+ apply_contrast(
+ apply_brightness(color, k_brightness),
+ k_contrast
+ ),
+ k_saturation
+ ),
+ k_gamma
+ );
+}
+vec3 rgb2hsv(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+highp float decode_f32(highp vec4 rgba) {
+ highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
+ highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
+ if (abs(Exponent + 127.0) < 1e-3) {
+ return 0.0;
+ }
+ highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
+ highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
+ return Result;
+}
+
+int decode_i32(vec4 rgba) {
+ int r = int(rgba.r * 255.0 + 0.5);
+ int g = int(rgba.g * 255.0 + 0.5);
+ int b = int(rgba.b * 255.0 + 0.5);
+ int a = int(rgba.a * 255.0 + 0.5);
+
+ int value = (r << 24) | (g << 16) | (b << 8) | a; // Combine into a 16-bit integer
+
+ return value;
+}
+
+int decode_i16(vec2 rg) {
+ int r = int(rg.r * 255.0 + 0.5);
+ int g = int(rg.g * 255.0 + 0.5);
+
+ int value = (r << 8) | g; // Combine into a 16-bit integer
+
+ if (value >= 32768) {
+ value -= 65536;
+ }
+
+ return value;
+}
+
+uint decode_u8(float r) {
+ uint value = uint(r * 255.0 + 0.5);
+ return value;
+}
+
+
+
+
+vec4 uvw2c_r(vec3 uv) {
+ vec2 va = texture(tex, uv).ra;
+
+ va.x = transfer_func(H, va.x, min_value, max_value);
+
+ va.x = mix(va.x, 1.0 - va.x, reversed);
+
+ vec4 c = colormap_f(va.x);
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_rgba(vec3 uv) {
+ vec4 c = texture(tex, uv).rgba;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+ c.g = transfer_func(H, c.g, min_value, max_value);
+ c.b = transfer_func(H, c.b, min_value, max_value);
+
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 uvw2c_ra(vec3 uv) {
+ vec2 c = texture(tex, uv).rg;
+
+ c.r = transfer_func(H, c.r, min_value, max_value);
+
+ c.r = mix(c.r, 1.0 - c.r, reversed);
+
+ vec3 color = colormap_f(c.r).rgb;
+
+ return apply_tonal(vec4(color, c.g));
+}
+
+vec4 uvw2cmap_rgba(vec3 uv) {
+ float v = texture(tex, uv).r;
+ v = transfer_func(H, v, min_value, max_value);
+ vec4 c = colormap_f(v);
+ c.rgb = mix(c.rgb, 1.0 - c.rgb, reversed);
+
+ return apply_tonal(c);
+}
+
+vec4 val2c_f32(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(isinf(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 val2c(float x) {
+ float alpha = x * scale + offset;
+ alpha = transfer_func(H, alpha, min_value, max_value);
+
+ alpha = mix(alpha, 1.0 - alpha, reversed);
+
+ vec4 new_color = mix(colormap_f(alpha), vec4(0.0), float(x == blank || isnan(x)));
+ return apply_tonal(new_color);
+}
+
+vec4 uvw2c_f32(vec3 uv) {
+ float val = decode_f32(texture(tex, uv).rgba*255.0);
+ return val2c_f32(val);
+}
+
+vec4 uvw2c_i32(vec3 uv) {
+ float val = float(decode_i32(texture(tex, uv).rgba));
+ return val2c(val);
+}
+
+vec4 uvw2c_i16(vec3 uv) {
+ float val = float(decode_i16(texture(tex, uv).rg));
+ return val2c(val);
+}
+
+vec4 uvw2c_u8(vec3 uv) {
+ float val = float(decode_u8(texture(tex, uv).r));
+ return val2c(val);
+}
+
+void main() {
+ vec3 uv = xyz2uv(normalize(frag_pos));
+
+ uv.y = 1.0 - uv.y;
+ vec4 c = uvw2c_i32(uv);
+
+ out_frag_color = c;
+ out_frag_color.a = out_frag_color.a * opacity;
+}"#,
+ );
+ out.insert(
+ r"image_base.vert",
+ r#"#version 300 es
+precision highp float;
+
+layout (location = 0) in vec2 ndc_pos;
+layout (location = 1) in vec2 uv;
+
+out vec2 frag_uv;
+
+void main() {
+ gl_Position = vec4(ndc_pos, 0.0, 1.0);
+ frag_uv = uv;
}"#,
);
out
diff --git a/src/js/A.js b/src/js/A.js
index 8a4402c3..7e997688 100644
--- a/src/js/A.js
+++ b/src/js/A.js
@@ -362,7 +362,7 @@ A.graphicOverlay = function (options) {
* @returns {ProgressiveCat} Returns a new Overlay object representing the graphic overlay.
*
* @example
- * let gaia = A.catalogHiPS('http://axel.u-strasbg.fr/HiPSCatService/I/345/gaia2', {onClick: 'showTable', color: 'orange', name: 'Gaia', filter: myFilterFunction});
+ * let gaia = A.catalogHiPS('http://axel.cds.unistra.fr/HiPSCatService/I/345/gaia2', {onClick: 'showTable', color: 'orange', name: 'Gaia', filter: myFilterFunction});
* aladin.addCatalog(gaia)
*/
A.catalogHiPS = function (url, options) {
diff --git a/src/js/Aladin.js b/src/js/Aladin.js
index acca5f52..67242ab7 100644
--- a/src/js/Aladin.js
+++ b/src/js/Aladin.js
@@ -941,7 +941,7 @@ export let Aladin = (function () {
objectName +
"'";
var url =
- "//simbad.u-strasbg.fr/simbad/sim-tap/sync?query=" +
+ "//simbad.cds.unistra.fr/simbad/sim-tap/sync?query=" +
encodeURIComponent(query) +
"&request=doQuery&lang=adql&format=json&phase=run";
diff --git a/src/js/SimbadPointer.js b/src/js/SimbadPointer.js
index de06c8e2..c50f26e7 100644
--- a/src/js/SimbadPointer.js
+++ b/src/js/SimbadPointer.js
@@ -60,7 +60,7 @@ export let SimbadPointer = (function() {
if (Utils.isNumber(magnitude)) {
content += 'Mag: ' + magnitude + '
';
}
- content += '
Query in CDS portal';
+ content += '
Query in CDS portal';
content += '';
aladinInstance.showPopup(objCoo.lon, objCoo.lat, title, content);
diff --git a/src/js/gui/Box/StackBox.js b/src/js/gui/Box/StackBox.js
index 2ff537eb..c9c92a5a 100644
--- a/src/js/gui/Box/StackBox.js
+++ b/src/js/gui/Box/StackBox.js
@@ -75,7 +75,7 @@ export class OverlayStackBox extends Box {
};*/
static predefinedCats = {
simbad: {
- url: "https://axel.u-strasbg.fr/HiPSCatService/SIMBAD",
+ url: "https://axel.cds.unistra.fr/HiPSCatService/SIMBAD",
options: {
id: "simbad",
name: "SIMBAD",
@@ -98,7 +98,7 @@ export class OverlayStackBox extends Box {
},
},
gaia: {
- url: "https://axel.u-strasbg.fr/HiPSCatService/I/355/gaiadr3",
+ url: "https://axel.cds.unistra.fr/HiPSCatService/I/355/gaiadr3",
options: {
id: "gaia-dr3",
name: "Gaia DR3",
@@ -109,7 +109,7 @@ export class OverlayStackBox extends Box {
},
},
twomass: {
- url: "https://axel.u-strasbg.fr/HiPSCatService/II/246/out",
+ url: "https://axel.cds.unistra.fr/HiPSCatService/II/246/out",
options: {
id: "2mass",
name: "2MASS",
@@ -790,7 +790,7 @@ export class OverlayStackBox extends Box {
moreHiPSLink.addEventListener("click", (e) => {
e.preventDefault();
if (!self.hipsBrowser)
- self.hipsBrowser = new HiPSBrowserBox(aladin);
+ self.hipsBrowser = new HiPSBrowserBox(self.aladin);
self.hipsBrowser._show({ position: { anchor: "center center" } });
});