12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- export default `
- // 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.
- ivec4 floatsToBytes(vec4 inputFloats, bool littleEndian) {
- ivec4 bytes = ivec4(inputFloats * 255.0);
- return (
- littleEndian
- ? 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, bool littleEndian) {
- ivec4 rgbaBytes = floatsToBytes(texelRGBA, littleEndian);
- bool bits[32];
- bytesToBits(rgbaBytes, bits);
- return bitsToFloat(bits);
- }
- `;
|