#pragma once #include #include #include "NormalQuantizer.h" #include "../../../core/BitHelper.h" NormalQuantizer::NormalQuantizer(unsigned8 bits): mBits(bits) { // Bits must be an even number, as there are two channels for an ONV assert(bits % 2 == 0); // Precalculate the channel mask unsigned32 channelStartHS = 32 - SmallNormal::BITS / 2; mChannelMask = BitHelper::GetHSMask(channelStartHS, channelStartHS + mBits / 2); } std::map* NormalQuantizer::QuantizeMaterials(std::vector normals) const { std::map* res = new std::map(); for (const SmallNormal& normal : normals) { res->insert(std::make_pair(normal, Quantize(normal))); } if (mBits <= QUANTIZE_ALL_UP_TO) { unsigned32 maxPerChannel = 1 << (mBits / 2); unsigned8 shift = (SmallNormal::BITS - mBits) / 2; for (unsigned32 x = 0; x < maxPerChannel; x++) for (unsigned32 y = 0; y < maxPerChannel; y++) { SmallNormal v; v.SetXComponent(x << shift); v.SetYComponent(y << shift); res->insert(std::make_pair(v, v)); } } return res; } SmallNormal NormalQuantizer::Quantize(const SmallNormal& normal) const { SmallNormal quantized; quantized.SetXComponent(normal.GetXComponent() & mChannelMask); quantized.SetYComponent(normal.GetYComponent() & mChannelMask); return quantized; } std::string NormalQuantizer::GetQuantizerDescriptor() const { return std::to_string(mBits); }