Improve low roughness significantly
Filament will now allow incomplete mipmap chains for the IBL and map the roughness to the available chain. This allows to create roughness cubemaps with a minim size for roughness==1, instead of always mapping it to 1x1. cmgen will now use 16x16 cubemaps for roughness==1, which improves the quality of rough objects significantly. The beauty of this is that there is no asset or API change. Old assets will continue to work like before.
This commit is contained in:
committed by
Mathias Agopian
parent
2c1454270e
commit
dbda77b091
@@ -5,6 +5,8 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## Next release
|
||||
|
||||
- Improve high roughness material rendering by default when regenerating environments maps
|
||||
|
||||
## v1.4.3
|
||||
|
||||
- Fixed an assertion when a parameter array occurs last in a material definition.
|
||||
|
||||
@@ -156,12 +156,6 @@ IndirectLight* IndirectLight::Builder::build(Engine& engine) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ASSERT_POSTCONDITION_NON_FATAL(mImpl->mReflectionsMap->getLevels() ==
|
||||
upcast(mImpl->mReflectionsMap)->getMaxLevelCount(),
|
||||
"reflection map must have %u mipmap levels",
|
||||
upcast(mImpl->mReflectionsMap)->getMaxLevelCount())) {
|
||||
return nullptr;
|
||||
}
|
||||
if (IBL_INTEGRATION == IBL_INTEGRATION_IMPORTANCE_SAMPLING) {
|
||||
mImpl->mReflectionsMap->generateMipmaps(engine);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ enum class ShFile {
|
||||
|
||||
static const size_t DFG_LUT_DEFAULT_SIZE = 128;
|
||||
static const size_t IBL_DEFAULT_SIZE = 256;
|
||||
static const size_t IBL_DEFAULT_MIN_LOD_SIZE = 16;
|
||||
|
||||
enum class OutputType {
|
||||
FACES, KTX, EQUIRECT, OCTAHEDRON
|
||||
@@ -71,6 +72,7 @@ static float g_extract_blur = 0.0;
|
||||
static utils::Path g_extract_dir;
|
||||
|
||||
static size_t g_output_size = 0;
|
||||
static size_t g_min_lod_size = 0;
|
||||
|
||||
static bool g_quiet = false;
|
||||
static bool g_debug = false;
|
||||
@@ -210,6 +212,8 @@ static void printUsage(char* name) {
|
||||
" Diffuse irradiance into <dir>\n\n"
|
||||
" --ibl-no-prefilter\n"
|
||||
" Use importance sampling instead of prefiltered importance sampling\n\n"
|
||||
" --ibl-min-lod-size\n"
|
||||
" Minimum LOD size [default: 16]\n\n"
|
||||
" --sh=bands\n"
|
||||
" SH decomposition of input cubemap\n\n"
|
||||
" --sh-output=filename.[exr|hdr|psd|rgbm|rgb32f|png|dds|txt]\n"
|
||||
@@ -240,7 +244,7 @@ static void license() {
|
||||
}
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[]) {
|
||||
static constexpr const char* OPTSTR = "hqidt:f:c:s:x:w:";
|
||||
static constexpr const char* OPTSTR = "hqidt:f:c:s:x:w:S:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "license", no_argument, nullptr, 'l' },
|
||||
@@ -264,6 +268,7 @@ static int handleCommandLineArgments(int argc, char* argv[]) {
|
||||
{ "ibl-dfg-multiscatter", no_argument, nullptr, 'u' },
|
||||
{ "ibl-dfg-cloth", no_argument, nullptr, 'C' },
|
||||
{ "ibl-no-prefilter", no_argument, nullptr, 'n' },
|
||||
{ "ibl-min-lod-size", required_argument, nullptr, 'S' },
|
||||
{ "ibl-samples", required_argument, nullptr, 'k' },
|
||||
{ "deploy", required_argument, nullptr, 'x' },
|
||||
{ "no-mirror", no_argument, nullptr, 'm' },
|
||||
@@ -353,6 +358,13 @@ static int handleCommandLineArgments(int argc, char* argv[]) {
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
g_min_lod_size = std::stoul(arg);
|
||||
if (!isPOT(g_min_lod_size)) {
|
||||
std::cerr << "min LOD size must be a power of two" << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
case 'z':
|
||||
g_sh_compute = 1;
|
||||
g_sh_output = true;
|
||||
@@ -877,8 +889,13 @@ void iblRoughnessPrefilter(
|
||||
const bool DEBUG_FULL_RESOLUTION = false;
|
||||
|
||||
const size_t baseExp = utils::ctz(g_output_size ? g_output_size : IBL_DEFAULT_SIZE);
|
||||
size_t minLod = utils::ctz(g_min_lod_size ? g_min_lod_size : IBL_DEFAULT_MIN_LOD_SIZE);
|
||||
if (minLod >= baseExp) {
|
||||
minLod = 0;
|
||||
}
|
||||
|
||||
size_t numSamples = g_num_samples;
|
||||
const size_t numLevels = baseExp + 1;
|
||||
const size_t numLevels = (baseExp + 1) - minLod;
|
||||
|
||||
// It's convenient to create an empty KTX bundle on the stack in this scope, regardless of
|
||||
// whether KTX is requested. It does not consume memory if empty.
|
||||
@@ -895,7 +912,7 @@ void iblRoughnessPrefilter(
|
||||
.pixelDepth = 0,
|
||||
};
|
||||
|
||||
for (ssize_t i = baseExp; i >= 0; --i) {
|
||||
for (ssize_t i = baseExp; i >= ssize_t((baseExp + 1) - numLevels) ; --i) {
|
||||
const size_t dim = 1U << (DEBUG_FULL_RESOLUTION ? baseExp : i); // NOLINT
|
||||
const size_t level = baseExp - i;
|
||||
if (level >= 2) {
|
||||
|
||||
Reference in New Issue
Block a user