Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Yurkovich <jesse.y@gmail.com>2022-05-12 06:11:44 +0300
committerJesse Yurkovich <jesse.y@gmail.com>2022-05-12 06:11:44 +0300
commit578771ae4dcb8643214c69a7b9761ca154f40f63 (patch)
tree6f69d7ee0001034b7c6f7e359f1da80d80ae18d1 /intern/cycles/scene
parent8d9d5da13706b668b9bd0d631e00c9b00b73f3ea (diff)
UDIM: Add support for packing inside .blend files
This completes support for tiled texture packing on the Blender / Cycles side of things. Most of these changes fall into one of three categories: - Updating Image handling code to pack/unpack tiled and multi-view images - Updating Cycles to handle tiled textures through BlenderImageLoader - Updating OSL to properly handle textures with multiple slots Differential Revision: https://developer.blender.org/D14395
Diffstat (limited to 'intern/cycles/scene')
-rw-r--r--intern/cycles/scene/image.cpp51
-rw-r--r--intern/cycles/scene/image.h9
-rw-r--r--intern/cycles/scene/osl.cpp7
-rw-r--r--intern/cycles/scene/osl.h2
-rw-r--r--intern/cycles/scene/shader_nodes.cpp11
5 files changed, 67 insertions, 13 deletions
diff --git a/intern/cycles/scene/image.cpp b/intern/cycles/scene/image.cpp
index 21fde88915e..c61ad1f1d71 100644
--- a/intern/cycles/scene/image.cpp
+++ b/intern/cycles/scene/image.cpp
@@ -117,12 +117,12 @@ void ImageHandle::clear()
manager = NULL;
}
-bool ImageHandle::empty()
+bool ImageHandle::empty() const
{
return tile_slots.empty();
}
-int ImageHandle::num_tiles()
+int ImageHandle::num_tiles() const
{
return tile_slots.size();
}
@@ -154,6 +154,35 @@ int ImageHandle::svm_slot(const int tile_index) const
return tile_slots[tile_index];
}
+vector<int4> ImageHandle::get_svm_slots() const
+{
+ const size_t num_nodes = divide_up(tile_slots.size(), 2);
+
+ vector<int4> svm_slots;
+ svm_slots.reserve(num_nodes);
+ for (size_t i = 0; i < num_nodes; i++) {
+ int4 node;
+
+ int slot = tile_slots[2 * i];
+ node.x = manager->images[slot]->loader->get_tile_number();
+ node.y = slot;
+
+ if ((2 * i + 1) < tile_slots.size()) {
+ slot = tile_slots[2 * i + 1];
+ node.z = manager->images[slot]->loader->get_tile_number();
+ node.w = slot;
+ }
+ else {
+ node.z = -1;
+ node.w = -1;
+ }
+
+ svm_slots.push_back(node);
+ }
+
+ return svm_slots;
+}
+
device_texture *ImageHandle::image_memory(const int tile_index) const
{
if (tile_index >= tile_slots.size()) {
@@ -266,6 +295,11 @@ ustring ImageLoader::osl_filepath() const
return ustring();
}
+int ImageLoader::get_tile_number() const
+{
+ return 0;
+}
+
bool ImageLoader::equals(const ImageLoader *a, const ImageLoader *b)
{
if (a == NULL && b == NULL) {
@@ -397,6 +431,19 @@ ImageHandle ImageManager::add_image(ImageLoader *loader,
return handle;
}
+ImageHandle ImageManager::add_image(const vector<ImageLoader *> &loaders,
+ const ImageParams &params)
+{
+ ImageHandle handle;
+ for (ImageLoader *loader : loaders) {
+ const int slot = add_image_slot(loader, params, true);
+ handle.tile_slots.push_back(slot);
+ }
+
+ handle.manager = this;
+ return handle;
+}
+
int ImageManager::add_image_slot(ImageLoader *loader,
const ImageParams &params,
const bool builtin)
diff --git a/intern/cycles/scene/image.h b/intern/cycles/scene/image.h
index 4d0dee35eca..9edb6a7eaf5 100644
--- a/intern/cycles/scene/image.h
+++ b/intern/cycles/scene/image.h
@@ -112,6 +112,9 @@ class ImageLoader {
/* Optional for OSL texture cache. */
virtual ustring osl_filepath() const;
+ /* Optional for tiled textures loaded externally. */
+ virtual int get_tile_number() const;
+
/* Free any memory used for loading metadata and pixels. */
virtual void cleanup(){};
@@ -139,11 +142,12 @@ class ImageHandle {
void clear();
- bool empty();
- int num_tiles();
+ bool empty() const;
+ int num_tiles() const;
ImageMetaData metadata();
int svm_slot(const int tile_index = 0) const;
+ vector<int4> get_svm_slots() const;
device_texture *image_memory(const int tile_index = 0) const;
VDBImageLoader *vdb_loader(const int tile_index = 0) const;
@@ -169,6 +173,7 @@ class ImageManager {
const ImageParams &params,
const array<int> &tiles);
ImageHandle add_image(ImageLoader *loader, const ImageParams &params, const bool builtin = true);
+ ImageHandle add_image(const vector<ImageLoader *> &loaders, const ImageParams &params);
void device_update(Device *device, Scene *scene, Progress &progress);
void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress);
diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp
index ffa1a2f5623..6698e6e2cce 100644
--- a/intern/cycles/scene/osl.cpp
+++ b/intern/cycles/scene/osl.cpp
@@ -1211,14 +1211,15 @@ void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring
parameter(name, filename);
}
-void OSLCompiler::parameter_texture(const char *name, int svm_slot)
+void OSLCompiler::parameter_texture(const char *name, const ImageHandle &handle)
{
/* Texture loaded through SVM image texture system. We generate a unique
* name, which ends up being used in OSLRenderServices::get_texture_handle
* to get handle again. Note that this name must be unique between multiple
* render sessions as the render services are shared. */
ustring filename(string_printf("@svm%d", texture_shared_unique_id++).c_str());
- services->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::SVM, svm_slot));
+ services->textures.insert(filename,
+ new OSLTextureHandle(OSLTextureHandle::SVM, handle.get_svm_slots()));
parameter(name, filename);
}
@@ -1290,7 +1291,7 @@ void OSLCompiler::parameter_texture(const char * /* name */,
{
}
-void OSLCompiler::parameter_texture(const char * /* name */, int /* svm_slot */)
+void OSLCompiler::parameter_texture(const char * /* name */, const ImageHandle & /*handle*/)
{
}
diff --git a/intern/cycles/scene/osl.h b/intern/cycles/scene/osl.h
index f0f97dbcaad..bf27069b1b1 100644
--- a/intern/cycles/scene/osl.h
+++ b/intern/cycles/scene/osl.h
@@ -147,7 +147,7 @@ class OSLCompiler {
void parameter_attribute(const char *name, ustring s);
void parameter_texture(const char *name, ustring filename, ustring colorspace);
- void parameter_texture(const char *name, int svm_slot);
+ void parameter_texture(const char *name, const ImageHandle &handle);
void parameter_texture_ies(const char *name, int svm_slot);
ShaderType output_type()
diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp
index 9a61a8a753b..03c152928d5 100644
--- a/intern/cycles/scene/shader_nodes.cpp
+++ b/intern/cycles/scene/shader_nodes.cpp
@@ -453,14 +453,15 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
"filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
}
else {
- compiler.parameter_texture("filename", handle.svm_slot());
+ compiler.parameter_texture("filename", handle);
}
const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
alpha_type == IMAGE_ALPHA_IGNORE);
const bool is_tiled = (filename.find("<UDIM>") != string::npos ||
- filename.find("<UVTILE>") != string::npos);
+ filename.find("<UVTILE>") != string::npos) ||
+ handle.num_tiles() > 1;
compiler.parameter(this, "projection");
compiler.parameter(this, "projection_blend");
@@ -605,7 +606,7 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler)
"filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
}
else {
- compiler.parameter_texture("filename", handle.svm_slot());
+ compiler.parameter_texture("filename", handle);
}
compiler.parameter(this, "projection");
@@ -960,7 +961,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
compiler.parameter_array("nishita_data", sunsky.nishita_data, 10);
/* nishita texture */
if (sky_type == NODE_SKY_NISHITA) {
- compiler.parameter_texture("filename", handle.svm_slot());
+ compiler.parameter_texture("filename", handle);
}
compiler.add(this, "node_sky_texture");
}
@@ -1855,7 +1856,7 @@ void PointDensityTextureNode::compile(OSLCompiler &compiler)
handle = image_manager->add_image(filename.string(), image_params());
}
- compiler.parameter_texture("filename", handle.svm_slot());
+ compiler.parameter_texture("filename", handle);
if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
compiler.parameter("mapping", tfm);
compiler.parameter("use_mapping", 1);