diff --git a/README.md b/README.md index fbba91fed..481b1ee95 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,7 @@ To further leverage the inherent structure of some data, the preparation stage c - `meshopt_EncodeExpSeparate` does not share exponents and results in the largest output - `meshopt_EncodeExpSharedVector` shares exponents between different components of the same vector - `meshopt_EncodeExpSharedComponent` shares exponents between the same component in different vectors + - `meshopt_EncodeExpClamped` does not share exponents but clamps the exponent range to reduce exponent entropy Note that all filters are lossy and require the data to be deinterleaved with one attribute per stream; this faciliates efficient SIMD implementation of filter decoders, allowing the overall decompression speed to be close to that of the raw codec. diff --git a/js/README.md b/js/README.md index f115fc12c..b9fded936 100644 --- a/js/README.md +++ b/js/README.md @@ -93,7 +93,7 @@ To that end, three filter encoders are provided: octahedral (optimal for normal ```ts encodeFilterOct: (source: Float32Array, count: number, stride: number, bits: number) => Uint8Array; encodeFilterQuat: (source: Float32Array, count: number, stride: number, bits: number) => Uint8Array; -encodeFilterExp: (source: Float32Array, count: number, stride: number, bits: number) => Uint8Array; +encodeFilterExp: (source: Float32Array, count: number, stride: number, bits: number, mode?: string) => Uint8Array; ``` All these functions take a source floating point buffer as an input, and perform a complex transformation that, when reversed by a decoder, results in an optimally quantized decompressed output. Because of this these functions assume specific configuration of input and output data: @@ -103,6 +103,7 @@ All these functions take a source floating point buffer as an input, and perform - `encodeFilterQuat` takes each 4 floats from the source array (for a total of `count` 4-vectrors), treats them as a unit quaternion, and encodes them into `stride` bytes in a way that, when decoded, the result is stored as a normalized signed 4-vector representing the same rotation as the source quaternion. `stride` must be 8 (the round-trip result is 4 16-bit normalized values). `bits` represents the desired precision of each component and must be in `[4..16]` range, although using less than 9-10 bits is likely going to lead to significant deviation in rotations. - `encodeFilterExp` takes each K floats from the source array (where `K=stride/4`, for a total of `count` K-vectors), and encodes them into `stride` bytes in a way that, when decoded, the result is stored as K single-precision floating point values. This may seem redundant but it allows to trade some precision for a higher compression ratio due to reduced precision of stored components, controlled by `bits` which must be in `[1..24]` range, and a shared exponent encoding used by the function. +The `mode` parameter can be used to influence the exponent sharing and provides a tradeoff between compressed size and quality for various use cases, and can be one of 'Separate', 'SharedVector', 'SharedComponent' and 'Clamped' (defaulting to 'SharedVector'). Note that in all cases using the highest `bits` value allowed by the output `stride` won't change the size of the output array (which is always going to be `count * stride` bytes), but it *will* reduce compression efficiency, as such the lowest acceptable `bits` value is recommended to use. When multiple parts of the data require different levels of precision, encode filters can be called multiple times and the output of the same filter called with the same `stride` can be concatenated even if `bits` are different.