Improvements to CMGEN handling of cubemaps
- cmgen now creates reflections maps for all input assets by default instead of just for equirectangular images. - equirectangular decode doesn't mirror -- that's done by the mirroring code now. - mirroring can be turned of with --no-mirror - option --mirror is gone - faster mirroring code (do it before generating mipmaps) - added labels to faces of debug.png environment - added a debug equirectangular image in third_party (creative commons license)
This commit is contained in:
committed by
Mathias Agopian
parent
1396cc751c
commit
09830cd126
Binary file not shown.
|
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 232 KiB |
1
third_party/environments/URL.txt
vendored
1
third_party/environments/URL.txt
vendored
@@ -1 +1,2 @@
|
||||
https://hdrihaven.com/
|
||||
https://mapswire.com/world/physical-maps/
|
||||
|
||||
BIN
third_party/environments/earth.png
vendored
Normal file
BIN
third_party/environments/earth.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
@@ -51,14 +51,14 @@ void CubemapUtils::equirectangularToCubemap(Cubemap& dst, const Image& src) {
|
||||
[&](EmptyState&, size_t y, Cubemap::Face f, Cubemap::Texel* data, size_t dim) {
|
||||
for (size_t x=0 ; x<dim ; ++x, ++data) {
|
||||
// calculate how many samples we need based on dx, dy in the source
|
||||
// x = cos(phi) sin(theta)
|
||||
// y = -sin(phi)
|
||||
// z = -cos(phi) cos(theta)
|
||||
// x = cos(phi) sin(theta)
|
||||
// y = sin(phi)
|
||||
// z = cos(phi) cos(theta)
|
||||
const double3 s0(dst.getDirectionFor(f, x, y));
|
||||
const double t0 = std::atan2(s0.x, -s0.z);
|
||||
const double t0 = std::atan2(s0.x, s0.z);
|
||||
const double p0 = std::asin(s0.y);
|
||||
const double3 s1(dst.getDirectionFor(f, x+1, y+1));
|
||||
const double t1 = std::atan2(s1.x, -s1.z);
|
||||
const double t1 = std::atan2(s1.x, s1.z);
|
||||
const double p1 = std::asin(s1.y);
|
||||
const double dt = std::abs(t1 - t0);
|
||||
const double dp = std::abs(p1 - p0);
|
||||
@@ -72,10 +72,10 @@ void CubemapUtils::equirectangularToCubemap(Cubemap& dst, const Image& src) {
|
||||
// Generate numSamples in our destination pixels and map them to input pixels
|
||||
const double2 h = hammersley(uint32_t(sample), iNumSamples);
|
||||
const double3 s(dst.getDirectionFor(f, x + h.x, y + h.y));
|
||||
float xf = float(std::atan2(s.x, -s.z) * M_1_PI); // range [-1.0, 1.0]
|
||||
float yf = float(std::asin(-s.y) * (2 * M_1_PI)); // range [-1.0, 1.0]
|
||||
float xf = float(std::atan2(s.x, s.z) * M_1_PI); // range [-1.0, 1.0]
|
||||
float yf = float(std::asin(s.y) * (2 * M_1_PI)); // range [-1.0, 1.0]
|
||||
xf = (xf + 1) * 0.5f * (width -1); // range [0, width [
|
||||
yf = (yf + 1) * 0.5f * (height-1); // range [0, height[
|
||||
yf = (1 - yf) * 0.5f * (height-1); // range [0, height[
|
||||
// we can't use filterAt() here because it reads past the width/height
|
||||
// which is okay for cubmaps but not for square images
|
||||
c += Cubemap::sampleAt(src.getPixelRef((uint32_t)xf, (uint32_t)yf));
|
||||
|
||||
@@ -149,8 +149,8 @@ static void printUsage(char* name) {
|
||||
" Extract faces of the cubemap into <dir>\n\n"
|
||||
" --extract-blur=roughness\n"
|
||||
" Blurs the cubemap before saving the faces using the roughness blur\n\n"
|
||||
" --mirror\n"
|
||||
" Mirrors generated cubemaps for reflections\n\n"
|
||||
" --no-mirror\n"
|
||||
" Skip mirroring of generated cubemaps (for assets with mirroring already backed in)\n\n"
|
||||
" --ibl-samples=numSamples\n"
|
||||
" Number of samples to use for IBL integrations (default 1024)\n\n"
|
||||
"\n"
|
||||
@@ -211,7 +211,7 @@ static int handleCommandLineArgments(int argc, char* argv[]) {
|
||||
{ "ibl-dfg-multiscatter", no_argument, nullptr, 'u' },
|
||||
{ "ibl-samples", required_argument, nullptr, 'k' },
|
||||
{ "deploy", required_argument, nullptr, 'x' },
|
||||
{ "mirror", no_argument, nullptr, 'm' },
|
||||
{ "no-mirror", no_argument, nullptr, 'm' },
|
||||
{ "debug", no_argument, nullptr, 'd' },
|
||||
{ nullptr, 0, 0, 0 } // termination of the option list
|
||||
};
|
||||
@@ -449,7 +449,6 @@ int main(int argc, char* argv[]) {
|
||||
Image temp;
|
||||
Cubemap cml = CubemapUtils::create(temp, dim, isHorizontal);
|
||||
CubemapUtils::copyImage(temp, inputImage);
|
||||
cml.makeSeamless();
|
||||
images.push_back(std::move(temp));
|
||||
levels.push_back(std::move(cml));
|
||||
} else if (width == 2 * height) {
|
||||
@@ -461,7 +460,6 @@ int main(int argc, char* argv[]) {
|
||||
Image temp;
|
||||
Cubemap cml = CubemapUtils::create(temp, dim);
|
||||
CubemapUtils::equirectangularToCubemap(cml, inputImage);
|
||||
cml.makeSeamless();
|
||||
images.push_back(std::move(temp));
|
||||
levels.push_back(std::move(cml));
|
||||
} else {
|
||||
@@ -492,36 +490,33 @@ int main(int argc, char* argv[]) {
|
||||
CubemapUtils::generateUVGrid(cml, 1);
|
||||
}
|
||||
|
||||
cml.makeSeamless();
|
||||
images.push_back(std::move(temp));
|
||||
levels.push_back(std::move(cml));
|
||||
}
|
||||
|
||||
// Now generate all the mipmap levels
|
||||
generateMipmaps(levels, images);
|
||||
|
||||
// we mirror by default -- the mirror option in fact un-mirrors.
|
||||
g_mirror = !g_mirror;
|
||||
if (g_mirror) {
|
||||
if (!g_quiet) {
|
||||
std::cout << "Mirroring..." << std::endl;
|
||||
}
|
||||
|
||||
std::vector<Cubemap> mirrorLevels;
|
||||
std::vector<Image> mirrorImages;
|
||||
|
||||
for (auto& level : levels) {
|
||||
Image temp;
|
||||
Cubemap cml = CubemapUtils::create(temp, level.getDimensions());
|
||||
CubemapUtils::mirrorCubemap(cml, level);
|
||||
cml.makeSeamless();
|
||||
|
||||
mirrorImages.push_back(std::move(temp));
|
||||
mirrorLevels.push_back(std::move(cml));
|
||||
Image temp;
|
||||
Cubemap cml = CubemapUtils::create(temp, levels[0].getDimensions());
|
||||
CubemapUtils::mirrorCubemap(cml, levels[0]);
|
||||
std::swap(levels[0], cml);
|
||||
std::swap(images[0], temp);
|
||||
} else {
|
||||
if (!g_quiet) {
|
||||
std::cout << "Skipped mirroring." << std::endl;
|
||||
}
|
||||
|
||||
std::swap(levels, mirrorLevels);
|
||||
std::swap(images, mirrorImages);
|
||||
}
|
||||
|
||||
// make the cubemap seamless
|
||||
levels[0].makeSeamless();
|
||||
|
||||
// Now generate all the mipmap levels
|
||||
generateMipmaps(levels, images);
|
||||
|
||||
if (g_sh_compute) {
|
||||
if (!g_quiet) {
|
||||
std::cout << "Spherical harmonics..." << std::endl;
|
||||
|
||||
Reference in New Issue
Block a user