compress skyboxes

This commit is contained in:
SamGondelman 2018-05-16 18:06:12 -07:00
parent 6b268191c8
commit 12b91a2ab7
4 changed files with 46 additions and 10 deletions

View file

@ -14,7 +14,7 @@ buildscript {
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.1.0' classpath 'com.android.tools.build:gradle:3.0.1'
} }
} }
@ -126,8 +126,8 @@ def packages = [
], ],
polyvox: [ polyvox: [
file: 'polyvox_armv8-libcpp.tgz', file: 'polyvox_armv8-libcpp.tgz',
versionId: 'UmHp.EOFiepdXnv2YxwNXNO3J6nVsBkE', versionId: 'A2kbKiNhpIenGq23bKRRzg7IMAI5BI92',
checksum: '5c918288741ee754c16aeb12bb46b9e1', checksum: 'dba88b3a098747af4bb169e9eb9af57e',
sharedLibFolder: 'lib', sharedLibFolder: 'lib',
includeLibs: ['Release/libPolyVoxCore.so', 'libPolyVoxUtil.so'], includeLibs: ['Release/libPolyVoxCore.so', 'libPolyVoxUtil.so'],
], ],

View file

@ -14,7 +14,7 @@ macro(TARGET_ETC2COMP)
select_library_configurations(ETC2COMP) select_library_configurations(ETC2COMP)
else() else()
add_dependency_external_projects(etc2comp) add_dependency_external_projects(etc2comp)
find_package(ETC2COMP REQUIRED) find_package(Etc2Comp REQUIRED)
endif() endif()
target_include_directories(${TARGET_NAME} PRIVATE ${ETC2COMP_INCLUDE_DIRS}) target_include_directories(${TARGET_NAME} PRIVATE ${ETC2COMP_INCLUDE_DIRS})

View file

@ -684,9 +684,9 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
PROFILE_RANGE(render_gpu, "sphericalHarmonicsFromTexture"); PROFILE_RANGE(render_gpu, "sphericalHarmonicsFromTexture");
#ifndef USE_GLES
auto mipFormat = cubeTexture.getStoredMipFormat(); auto mipFormat = cubeTexture.getStoredMipFormat();
std::function<glm::vec3(uint32)> unpackFunc; std::function<glm::vec3(uint32)> unpackFunc;
switch (mipFormat.getSemantic()) { switch (mipFormat.getSemantic()) {
case gpu::R11G11B10: case gpu::R11G11B10:
unpackFunc = glm::unpackF2x11_1x10; unpackFunc = glm::unpackF2x11_1x10;
@ -698,6 +698,7 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
assert(false); assert(false);
break; break;
} }
#endif
const uint sqOrder = order*order; const uint sqOrder = order*order;
@ -732,7 +733,11 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) { for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) {
PROFILE_RANGE(render_gpu, "ProcessFace"); PROFILE_RANGE(render_gpu, "ProcessFace");
#ifndef USE_GLES
auto data = reinterpret_cast<const uint32*>( cubeTexture.accessStoredMipFace(0, face)->readData() ); auto data = reinterpret_cast<const uint32*>( cubeTexture.accessStoredMipFace(0, face)->readData() );
#else
auto data = cubeTexture.accessStoredMipFace(0, face)->readData();
#endif
if (data == nullptr) { if (data == nullptr) {
continue; continue;
} }
@ -816,8 +821,15 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
glm::vec3 color{ 0.0f, 0.0f, 0.0f }; glm::vec3 color{ 0.0f, 0.0f, 0.0f };
for (int i = 0; i < stride; ++i) { for (int i = 0; i < stride; ++i) {
for (int j = 0; j < stride; ++j) { for (int j = 0; j < stride; ++j) {
#ifndef USE_GLES
int k = (int)(x + i - halfStride + (y + j - halfStride) * width); int k = (int)(x + i - halfStride + (y + j - halfStride) * width);
color += unpackFunc(data[k]); color += unpackFunc(data[k]);
#else
const int NUM_COMPONENTS_PER_PIXEL = 4;
int k = NUM_COMPONENTS_PER_PIXEL * (int)(x + i - halfStride + (y + j - halfStride) * width);
// BGRA -> RGBA
color += glm::pow(glm::vec3(data[k + 2], data[k + 1], data[k]) / 255.0f, glm::vec3(2.2f));
#endif
} }
} }

View file

@ -84,7 +84,13 @@ const QStringList getSupportedFormats() {
return stringFormats; return stringFormats;
} }
// On GLES, we don't use HDR skyboxes
#ifndef USE_GLES
QImage::Format QIMAGE_HDR_FORMAT = QImage::Format_RGB30; QImage::Format QIMAGE_HDR_FORMAT = QImage::Format_RGB30;
#else
QImage::Format QIMAGE_HDR_FORMAT = QImage::Format_RGB32;
#endif
TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, const QVariantMap& options) { TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, const QVariantMap& options) {
switch (type) { switch (type) {
@ -557,7 +563,7 @@ void generateLDRMips(gpu::Texture* texture, QImage&& image, const std::atomic<bo
// https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f18-for-consume-parameters-pass-by-x-and-stdmove-the-parameter // https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f18-for-consume-parameters-pass-by-x-and-stdmove-the-parameter
QImage localCopy = std::move(image); QImage localCopy = std::move(image);
if (localCopy.format() != QImage::Format_ARGB32) { if (localCopy.format() != QImage::Format_ARGB32 && localCopy.format() != QIMAGE_HDR_FORMAT) {
localCopy = localCopy.convertToFormat(QImage::Format_ARGB32); localCopy = localCopy.convertToFormat(QImage::Format_ARGB32);
} }
@ -757,11 +763,15 @@ void generateMips(gpu::Texture* texture, QImage&& image, const std::atomic<bool>
#if CPU_MIPMAPS #if CPU_MIPMAPS
PROFILE_RANGE(resource_parse, "generateMips"); PROFILE_RANGE(resource_parse, "generateMips");
#ifndef USE_GLES
if (image.format() == QIMAGE_HDR_FORMAT) { if (image.format() == QIMAGE_HDR_FORMAT) {
generateHDRMips(texture, std::move(image), abortProcessing, face); generateHDRMips(texture, std::move(image), abortProcessing, face);
} else { } else {
generateLDRMips(texture, std::move(image), abortProcessing, face); generateLDRMips(texture, std::move(image), abortProcessing, face);
} }
#else
generateLDRMips(texture, std::move(image), abortProcessing, face);
#endif
#else #else
texture->setAutoGenerateMips(true); texture->setAutoGenerateMips(true);
#endif #endif
@ -1354,18 +1364,25 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(QImage&& srcI
QImage image = processSourceImage(std::move(localCopy), true); QImage image = processSourceImage(std::move(localCopy), true);
if (image.format() != QIMAGE_HDR_FORMAT) { if (image.format() != QIMAGE_HDR_FORMAT) {
#ifndef USE_GLES
image = convertToHDRFormat(std::move(image), HDR_FORMAT); image = convertToHDRFormat(std::move(image), HDR_FORMAT);
#else
image = image.convertToFormat(QImage::Format_RGB32);
#endif
} }
gpu::Element formatMip; gpu::Element formatMip;
gpu::Element formatGPU; gpu::Element formatGPU;
if (isCubeTexturesCompressionEnabled()) { if (isCubeTexturesCompressionEnabled()) {
formatMip = gpu::Element::COLOR_COMPRESSED_BCX_HDR_RGB;
formatGPU = gpu::Element::COLOR_COMPRESSED_BCX_HDR_RGB; formatGPU = gpu::Element::COLOR_COMPRESSED_BCX_HDR_RGB;
} else { } else {
formatMip = HDR_FORMAT; #ifdef USE_GLES
formatGPU = gpu::Element::COLOR_COMPRESSED_ETC2_SRGB;
#else
formatGPU = HDR_FORMAT; formatGPU = HDR_FORMAT;
#endif
} }
formatMip = formatGPU;
// Find the layout of the cubemap in the 2D image // Find the layout of the cubemap in the 2D image
// Use the original image size since processSourceImage may have altered the size / aspect ratio // Use the original image size since processSourceImage may have altered the size / aspect ratio
@ -1412,9 +1429,16 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(QImage&& srcI
// Generate irradiance while we are at it // Generate irradiance while we are at it
if (generateIrradiance) { if (generateIrradiance) {
PROFILE_RANGE(resource_parse, "generateIrradiance"); PROFILE_RANGE(resource_parse, "generateIrradiance");
auto irradianceTexture = gpu::Texture::createCube(HDR_FORMAT, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); gpu::Element irradianceFormat;
// TODO: we could locally compress the irradiance texture on Android, but we don't need to
#ifndef USE_GLES
irradianceFormat = HDR_FORMAT;
#else
irradianceFormat = gpu::Element::COLOR_SRGBA_32;
#endif
auto irradianceTexture = gpu::Texture::createCube(irradianceFormat, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP));
irradianceTexture->setSource(srcImageName); irradianceTexture->setSource(srcImageName);
irradianceTexture->setStoredMipFormat(HDR_FORMAT); irradianceTexture->setStoredMipFormat(irradianceFormat);
for (uint8 face = 0; face < faces.size(); ++face) { for (uint8 face = 0; face < faces.size(); ++face) {
irradianceTexture->assignStoredMipFace(0, face, faces[face].byteCount(), faces[face].constBits()); irradianceTexture->assignStoredMipFace(0, face, faces[face].byteCount(), faces[face].constBits());
} }