1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2026-05-19 12:32:07 +00:00

hyperbolic eqidistant 3D now also works in spatial

This commit is contained in:
Zeno Rogue
2025-09-09 12:19:16 +02:00
parent 39a61cf567
commit 923da0b999
+45 -7
View File
@@ -257,7 +257,7 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
}
else if(among(pmodel, mdDisk, mdBall) && GDIM == 2 && vrhr::rendering() && !sphere && !(hyperbolic && pconf.alpha < 0 && pconf.alpha > -1)) {
shader_flags |= SF_DIRECT | SF_BOX;
vsh += "uniform mediump float uAlpha, uDepth, uDepthScaling, uCamera;";
vsh += "uniform mediump float uDepth, uAlpha, uDepthScaling, uCamera;";
if(hyperbolic) coordinator +=
"float zlev = sqrt(t.z*t.z-t.x*t.x-t.y*t.y);\n"
@@ -313,11 +313,21 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
if(dim3) shader_flags |= SF_ZFOG;
}
else if(pmodel == mdEquidistant && hyperbolic) {
shader_flags |= SF_BAND | SF_ORIENT | SF_BOX | SF_DIRECT | SF_NONSPATIAL;
shader_flags |= SF_BAND | SF_ORIENT | SF_BOX | SF_DIRECT;
coordinator += "t = uPP * t;", vsh += "uniform mediump mat4 uPP;";
if(dim2) coordinator += "mediump float zlev = zlevel(t); t /= zlev;\n";
if(dim2) coordinator += "mediump float r = length(t.xy); if(r > 0.) t.xy *= asinh(r) / r / 2.; t[2] = 0.; t[3] = 1.;\n";
if(dim3) coordinator += "mediump float r = length(t.xyz); if(r > 0.) t.xyz *= asinh(r) / r / 2.; t[3] = 1.;\n";
if(dim3) {
coordinator += "mediump float d = length(t.xyz); if(d > 0.) t.xyz *= asinh(d) / d / 2.; t[3] = 1.;\n";
}
else if(!spatial_graphics) {
coordinator += "mediump float d = length(t.xy); if(d > 0.) t.xy *= asinh(d) / d / 2.; t[2] = 0.; t[3] = 1.;\n";
}
else {
coordinator += "mediump float zlev = zlevel(t); t /= zlev;\n";
coordinator += "mediump float rad = length(t.xy);\n";
coordinator += "mediump float d = asinh(rad);\n";
coordinator += "mediump float df, zf; hypot_zlev(zlev, d, df, zf);\n";
coordinator += "if(d > 0.) t.xy *= d * df / rad / 2.; t[2] = 0.; t[3] = 1.;\n";
}
if(dim3) shader_flags |= SF_ZFOG;
}
else if(pmodel == mdHalfplane && hyperbolic) {
@@ -624,6 +634,7 @@ void display_data::set_projection(int ed, ld shift) {
if(in_h2xe()) id |= 1;
if(in_s2xe()) id |= 2;
if(WDIM == 2 && GDIM == 3 && hyperbolic && context_fog && cgi.emb->is_same_in_same()) id |= 1;
id <<= 1; id |= (spatial_graphics ? 1 : 0);
shared_ptr<glhr::GLprogram> selected;
if(matched_programs.count(id)) selected = matched_programs[id];
@@ -866,9 +877,20 @@ void display_data::set_projection(int ed, ld shift) {
}
}
EX void add_if(string& shader, const string& seek, const string& function) {
if(shader.find(seek) != string::npos)
EX bool add_if(string& shader, const string& seek, const string& function) {
if(shader.find(seek) != string::npos) {
shader = function + shader;
return true;
}
return false;
}
EX bool add_if_not(string& shader, const string& seek, const string& function) {
if(shader.find(seek) == string::npos) {
shader = function + shader;
return true;
}
return false;
}
EX void add_fixed_functions(string& shader) {
@@ -935,6 +957,21 @@ EX void add_fixed_functions(string& shader) {
"return ((1.0 + (e2 / 24.0 - 0.1 - 3.0 * e3 / 44.0) * e2+ e3 / 14.) / sqrt(mean));\n"
"}\n");
if(hyperbolic) add_if(shader, "hypot_zlev",
"void hypot_zlev(in mediump float zlev, inout mediump float d, out mediump float df, out mediump float zf) {\n"
" mediump float z = factor_to_lev(zlev);\n"
" mediump float tz = sinh(z);\n"
" mediump float td = sinh(d) * cosh(z);\n"
" mediump float h = length(vec2(tz, td));\n"
" zf = tz / h; df = td / h;\n"
" d = acosh(cosh(d) * cosh(z));\n"
" }\n"
);
if(hyperbolic) add_if(shader, "factor_to_lev",
"mediump float factor_to_lev(mediump float zlev) { return uDepth - atanh(tanh(uDepth) / zlev); }\n"
) && add_if_not(shader, "float uDepth", "uniform mediump float uDepth;\n");
add_if(shader, "tanh", "mediump float tanh(mediump float x) { return sinh(x) / cosh(x); }\n");
add_if(shader, "sinh", "mediump float sinh(mediump float x) { return (exp(x) - exp(-x)) / 2.0; }\n");
add_if(shader, "asin_clamp", "mediump float asin_clamp(mediump float x) { return x > 1. ? PI/2. : x < -1. ? -PI/2. : asin(x); }\n");
@@ -942,6 +979,7 @@ EX void add_fixed_functions(string& shader) {
add_if(shader, "asinh", "mediump float asinh(mediump float x) { return log(sqrt(x*x + 1.0) + x); }\n");
add_if(shader, "acosh", "mediump float acosh(mediump float x) { return log(sqrt(x*x - 1.0) + x); }\n");
add_if(shader, "atanh", "mediump float atanh(mediump float x) { return (log(1.+x)-log(1.-x))/2.; }\n");
// probably also if(hyperbolic)
add_if(shader, "zlevel", "mediump float zlevel(mediump vec4 h) { return (h[2] < 0.0 ? -1.0 : 1.0) * sqrt(h[2]*h[2] - h[0]*h[0] - h[1]*h[1]); }\n");
add_if(shader, "atan2", "mediump float atan2(mediump float y, mediump float x) {\n"
"if(x == 0.) return y > 0. ? PI/2. : -PI/2.;\n"