void ProductionCompressorBC5_Luma::compressBlock(ColorSet & set, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) { BlockATI2 * block = new(output) BlockATI2; AlphaBlock4x4 tmp; tmp.init(set, /*channel=*/0); OptimalCompress::compressDXT5A(tmp, &block->x); // Decode block->x AlphaBlock4x4 decoded; block->x.decodeBlock(&decoded); const float R = 1.0f / 256.0f; // Maximum residual that we can represent. @@ Tweak this. // Compute residual block. for (int i = 0; i < 16; i++) { float in = set.color(i).x; // [0,1] float out = float(decoded.alpha[i]) / 255.0f; // [0,1] float residual = (out - in); // [-1,1], but usually [-R,R] // Normalize residual to [-1,1] range. residual /= R; // Pack in [0,1] range. residual = residual * 0.5f + 0.5f; tmp.alpha[i] = nv::ftoi_round(nv::saturate(residual) * 255.0f); } OptimalCompress::compressDXT5A(tmp, &block->y); }
void CompressorBC7::compressBlock(ColorSet & tile, AlphaMode alphaMode, const CompressionOptions::Private & compressionOptions, void * output) { // !!!UNDONE: support channel weights // !!!UNDONE: set flags once, not per block (this is especially sketchy since block compression is multithreaded...) AVPCL::mode_rgb = false; AVPCL::flag_premult = (alphaMode == AlphaMode_Premultiplied); AVPCL::flag_nonuniform = false; AVPCL::flag_nonuniform_ati = false; // Convert NVTT's tile struct to AVPCL's. AVPCL::Tile avpclTile(tile.w, tile.h); memset(avpclTile.data, 0, sizeof(avpclTile.data)); for (uint y = 0; y < tile.h; ++y) for (uint x = 0; x < tile.w; ++x) avpclTile.data[y][x] = tile.color(x, y) * 255.0f; AVPCL::compress(avpclTile, (char *)output); }
void CompressorBC6::compressBlock(ColorSet & tile, AlphaMode alphaMode, const CompressionOptions::Private & compressionOptions, void * output) { // !!!UNDONE: support channel weights // !!!UNDONE: set flags once, not per block (this is especially sketchy since block compression is multithreaded...) NV_UNUSED(alphaMode); // ZOH does not support alpha. if (compressionOptions.pixelType == PixelType_UnsignedFloat || compressionOptions.pixelType == PixelType_UnsignedNorm || compressionOptions.pixelType == PixelType_UnsignedInt) { ZOH::Utils::FORMAT = ZOH::UNSIGNED_F16; } else { ZOH::Utils::FORMAT = ZOH::SIGNED_F16; } // Convert NVTT's tile struct to ZOH's, and convert float to half. ZOH::Tile zohTile(tile.w, tile.h); memset(zohTile.data, 0, sizeof(zohTile.data)); memset(zohTile.importance_map, 0, sizeof(zohTile.importance_map)); for (uint y = 0; y < tile.h; ++y) { for (uint x = 0; x < tile.w; ++x) { Vector3 color = tile.color(x, y).xyz(); uint16 rHalf = to_half(color.x); uint16 gHalf = to_half(color.y); uint16 bHalf = to_half(color.z); zohTile.data[y][x].x = ZOH::Tile::half2float(rHalf); zohTile.data[y][x].y = ZOH::Tile::half2float(gHalf); zohTile.data[y][x].z = ZOH::Tile::half2float(bHalf); zohTile.importance_map[y][x] = 1.0f; } } ZOH::compress(zohTile, (char *)output); }