|
@@ -17,146 +17,18 @@ uniform bool uLittleEndian;
|
|
|
uniform float uWidth;
|
|
|
|
|
|
#ifdef CUMULATIVE
|
|
|
-uniform sampler2D tCumulativeSum;
|
|
|
+ uniform sampler2D tCumulativeSum;
|
|
|
#endif
|
|
|
|
|
|
{UNIFORMS}
|
|
|
|
|
|
{UTILS}
|
|
|
|
|
|
-//////////////////////////////////////////////////////////
|
|
|
-
|
|
|
-// floatToRgba adapted from https://github.com/equinor/glsl-float-to-rgba
|
|
|
-// MIT License, Copyright (c) 2020 Equinor
|
|
|
-
|
|
|
-float shiftRight (float v, float amt) {
|
|
|
- v = floor(v) + 0.5;
|
|
|
- return floor(v / exp2(amt));
|
|
|
-}
|
|
|
-float shiftLeft (float v, float amt) {
|
|
|
- return floor(v * exp2(amt) + 0.5);
|
|
|
-}
|
|
|
-float maskLast (float v, float bits) {
|
|
|
- return mod(v, shiftLeft(1.0, bits));
|
|
|
-}
|
|
|
-float extractBits (float num, float from, float to) {
|
|
|
- from = floor(from + 0.5); to = floor(to + 0.5);
|
|
|
- return maskLast(shiftRight(num, from), to - from);
|
|
|
-}
|
|
|
-
|
|
|
-vec4 floatToRgba(float texelFloat) {
|
|
|
- if (texelFloat == 0.0) return vec4(0, 0, 0, 0);
|
|
|
- float sign = texelFloat > 0.0 ? 0.0 : 1.0;
|
|
|
- texelFloat = abs(texelFloat);
|
|
|
- float exponent = floor(log2(texelFloat));
|
|
|
- float biased_exponent = exponent + 127.0;
|
|
|
- float fraction = ((texelFloat / exp2(exponent)) - 1.0) * 8388608.0;
|
|
|
- float t = biased_exponent / 2.0;
|
|
|
- float last_bit_of_biased_exponent = fract(t) * 2.0;
|
|
|
- float remaining_bits_of_biased_exponent = floor(t);
|
|
|
- float byte4 = extractBits(fraction, 0.0, 8.0) / 255.0;
|
|
|
- float byte3 = extractBits(fraction, 8.0, 16.0) / 255.0;
|
|
|
- float byte2 = (last_bit_of_biased_exponent * 128.0 + extractBits(fraction, 16.0, 23.0)) / 255.0;
|
|
|
- float byte1 = (sign * 128.0 + remaining_bits_of_biased_exponent) / 255.0;
|
|
|
- return (
|
|
|
- uLittleEndian
|
|
|
- ? vec4(byte4, byte3, byte2, byte1)
|
|
|
- : vec4(byte1, byte2, byte3, byte4)
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
-///////////////////////////////////////////////////////
|
|
|
-
|
|
|
-// rgbaToFloat adapted from https://github.com/ihmeuw/glsl-rgba-to-float
|
|
|
-// BSD 3-Clause License
|
|
|
-//
|
|
|
-// Copyright (c) 2019, Institute for Health Metrics and Evaluation All rights reserved.
|
|
|
-// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
|
-// - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
|
-// - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
|
-// - Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
|
-//
|
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
|
-// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
|
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
|
-// OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
-
|
|
|
+#include float_to_rgba
|
|
|
#ifdef CUMULATIVE
|
|
|
-
|
|
|
-ivec4 floatsToBytes(vec4 inputFloats) {
|
|
|
- ivec4 bytes = ivec4(inputFloats * 255.0);
|
|
|
- return (
|
|
|
- uLittleEndian
|
|
|
- ? bytes.abgr
|
|
|
- : bytes
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
-// Break the four bytes down into an array of 32 bits.
|
|
|
-void bytesToBits(const in ivec4 bytes, out bool bits[32]) {
|
|
|
- for (int channelIndex = 0; channelIndex < 4; ++channelIndex) {
|
|
|
- float acc = float(bytes[channelIndex]);
|
|
|
- for (int indexInByte = 7; indexInByte >= 0; --indexInByte) {
|
|
|
- float powerOfTwo = exp2(float(indexInByte));
|
|
|
- bool bit = acc >= powerOfTwo;
|
|
|
- bits[channelIndex * 8 + (7 - indexInByte)] = bit;
|
|
|
- acc = mod(acc, powerOfTwo);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Compute the exponent of the 32-bit float.
|
|
|
-float getExponent(bool bits[32]) {
|
|
|
- const int startIndex = 1;
|
|
|
- const int bitStringLength = 8;
|
|
|
- const int endBeforeIndex = startIndex + bitStringLength;
|
|
|
- float acc = 0.0;
|
|
|
- int pow2 = bitStringLength - 1;
|
|
|
- for (int bitIndex = startIndex; bitIndex < endBeforeIndex; ++bitIndex) {
|
|
|
- acc += float(bits[bitIndex]) * exp2(float(pow2--));
|
|
|
- }
|
|
|
- return acc;
|
|
|
-}
|
|
|
-
|
|
|
-// Compute the mantissa of the 32-bit float.
|
|
|
-float getMantissa(bool bits[32], bool subnormal) {
|
|
|
- const int startIndex = 9;
|
|
|
- const int bitStringLength = 23;
|
|
|
- const int endBeforeIndex = startIndex + bitStringLength;
|
|
|
- // Leading/implicit/hidden bit convention:
|
|
|
- // If the number is not subnormal (with exponent 0), we add a leading 1 digit.
|
|
|
- float acc = float(!subnormal) * exp2(float(bitStringLength));
|
|
|
- int pow2 = bitStringLength - 1;
|
|
|
- for (int bitIndex = startIndex; bitIndex < endBeforeIndex; ++bitIndex) {
|
|
|
- acc += float(bits[bitIndex]) * exp2(float(pow2--));
|
|
|
- }
|
|
|
- return acc;
|
|
|
-}
|
|
|
-
|
|
|
-// Parse the float from its 32 bits.
|
|
|
-float bitsToFloat(bool bits[32]) {
|
|
|
- float signBit = float(bits[0]) * -2.0 + 1.0;
|
|
|
- float exponent = getExponent(bits);
|
|
|
- bool subnormal = abs(exponent - 0.0) < 0.01;
|
|
|
- float mantissa = getMantissa(bits, subnormal);
|
|
|
- float exponentBias = 127.0;
|
|
|
- return signBit * mantissa * exp2(exponent - exponentBias - 23.0);
|
|
|
-}
|
|
|
-
|
|
|
-float rgbaToFloat(vec4 texelRGBA) {
|
|
|
- ivec4 rgbaBytes = floatsToBytes(texelRGBA);
|
|
|
- bool bits[32];
|
|
|
- bytesToBits(rgbaBytes, bits);
|
|
|
- return bitsToFloat(bits);
|
|
|
-}
|
|
|
-
|
|
|
+ #include rgba_to_float
|
|
|
#endif
|
|
|
|
|
|
-///////////////////////////////////////////////////////
|
|
|
-
|
|
|
float intDiv(float a, float b) { return float(int(a) / int(b)); }
|
|
|
float intMod(float a, float b) { return a - b * float(int(a) / int(b)); }
|
|
|
|
|
@@ -174,8 +46,8 @@ void main(void) {
|
|
|
{MAIN}
|
|
|
|
|
|
#ifdef CUMULATIVE
|
|
|
- float current = rgbaToFloat(texture2D(tCumulativeSum, gl_FragCoord.xy / vec2(uWidth, uWidth)));
|
|
|
+ float current = rgbaToFloat(texture2D(tCumulativeSum, gl_FragCoord.xy / vec2(uWidth, uWidth)), uLittleEndian);
|
|
|
#endif
|
|
|
- gl_FragColor = floatToRgba({RETURN});
|
|
|
+ gl_FragColor = floatToRgba({RETURN}, uLittleEndian);
|
|
|
}
|
|
|
`;
|