Files
OpenSpace/shaders/floatoperations.glsl
2017-03-02 18:20:05 +01:00

94 lines
3.6 KiB
GLSL

/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef _FLOATOPERATIONS_GLSL_
#define _FLOATOPERATIONS_GLSL_
/**
* Convert a positive floating point distance [0, 10^27]
* (size of observable universe)
* to a float in the range [-1, 1], suitable for depth buffer storage.
* Note: This needs to be a monotonic function, so that the value can
* still be used for depth comparison.
*/
float normalizeFloat(float inpt) {
if (inpt > 1.0) {
return inpt / pow(10, 27);
} else {
return inpt - 1.0;
}
}
float denormalizeFloat(float inpt) {
if (inpt < 0.0) {
return inpt + 1.0;
} else {
return inpt * pow(10, 27);
}
}
/**
* Compute the length of a vector.
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
*/
float safeLength(vec4 v) {
float m = max(max(max(abs(v.x), abs(v.y)), abs(v.z)), abs(v.w));
if (m > 0.0) {
return length(v / m) * m;
} else {
return 0;
}
}
float safeLength(vec3 v) {
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
if (m > 0.0) {
return length(v / m) * m;
} else {
return 0;
}
}
float safeLength(vec2 v) {
float m = max(abs(v.x), abs(v.y));
if (m > 0.0) {
return length(v / m) * m;
} else {
return 0;
}
}
/**
* Normalize a vector
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
*/
vec3 safeNormalize(vec3 v) {
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
return normalize(v / m);
}
#endif