[Bf-blender-cvs] [272412f9] master: Cycles: Implement texture size limit simplify option

Sergey Sharybin noreply at git.blender.org
Tue Nov 22 12:03:11 CET 2016


Commit: 272412f9c0d26f630c5e1e7d07d4ff417b7218e5
Author: Sergey Sharybin
Date:   Thu Nov 17 12:13:22 2016 +0100
Branches: master
https://developer.blender.org/rB272412f9c0d26f630c5e1e7d07d4ff417b7218e5

Cycles: Implement texture size limit simplify option

Main intention is to give some quick way to control scene's memory
usage by clamping textures which are too big. This is really handy
on the early production stages when you first create really nice
looking hi-res textures and only when it all works and approved
start investing time on optimizing your scene.

This is a new option in Scene Simplify panel and it acts as
following: when texture size is bigger than the given value it'll
be scaled down by half for until it fits into given limit.

There are various possible improvements, such as:

- Use threaded scaling using our own task manager.

  This is actually one of the main reasons why image resize is
  manually-implemented instead of using OIIO's resize. Other
  reason here is that API seems limited to construct 3D texture
  description easily.

- Vectorization of uchar4/float4/half4 textures.

- Use something smarter than box filter.

  Was playing with some other filters, but not sure they are
  really better: they kind of causes more fuzzy edges.

Even with such a TODOs in the code the option is already quite
useful.

Reviewers: brecht

Reviewed By: brecht

Subscribers: jtheninja, Blendify, gregzaal, venomgfx

Differential Revision: https://developer.blender.org/D2362

===================================================================

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/blender_sync.cpp
M	intern/cycles/render/image.cpp
M	intern/cycles/render/image.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/scene.cpp
M	intern/cycles/render/scene.h
M	intern/cycles/util/CMakeLists.txt
M	intern/cycles/util/util_image.h
A	intern/cycles/util/util_image_impl.h

===================================================================

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index b53f85c..fed1524 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -129,6 +129,16 @@ enum_device_type = (
     ('OPENCL', "OpenCL", "OpenCL", 2)
     )
 
+enum_texture_limit = (
+    ('OFF', "No Limit", "No texture size limit", 0),
+    ('128', "128", "Limit texture size to 128 pixels", 1),
+    ('256', "256", "Limit texture size to 256 pixels", 2),
+    ('512', "512", "Limit texture size to 512 pixels", 3),
+    ('1024', "1024", "Limit texture size to 1024 pixels", 4),
+    ('2048', "2048", "Limit texture size to 2048 pixels", 5),
+    ('4096', "4096", "Limit texture size to 4096 pixels", 6),
+    ('8192', "8192", "Limit texture size to 8192 pixels", 7),
+    )
 
 class CyclesRenderSettings(bpy.types.PropertyGroup):
     @classmethod
@@ -608,6 +618,20 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
             min=0.0, max=1.0,
             )
 
+        cls.texture_limit = EnumProperty(
+            name="Viewport Texture Limit",
+            default='OFF',
+            description="Limit texture size used by viewport rendering",
+            items=enum_texture_limit
+            )
+
+        cls.texture_limit_render = EnumProperty(
+            name="Render Texture Limit",
+            default='OFF',
+            description="Limit texture size used by final rendering",
+            items=enum_texture_limit
+            )
+
         # Various fine-tuning debug flags
 
         def devices_update_callback(self, context):
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 1856b27..3f7730e 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1587,29 +1587,40 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
         cscene = scene.cycles
 
         layout.active = rd.use_simplify
-        split = layout.split()
 
-        col = split.column()
-        col.label(text="Viewport:")
-        col.prop(rd, "simplify_subdivision", text="Subdivision")
-        col.prop(rd, "simplify_child_particles", text="Child Particles")
+        col = layout.column(align=True)
+        col.label(text="Subdivision")
+        row = col.row(align=True)
+        row.prop(rd, "simplify_subdivision", text="Viewport")
+        row.prop(rd, "simplify_subdivision_render", text="Render")
 
-        col = split.column()
-        col.label(text="Render:")
-        col.prop(rd, "simplify_subdivision_render", text="Subdivision")
-        col.prop(rd, "simplify_child_particles_render", text="Child Particles")
+        col = layout.column(align=True)
+        col.label(text="Child Particles")
+        row = col.row(align=True)
+        row.prop(rd, "simplify_child_particles", text="Viewport")
+        row.prop(rd, "simplify_child_particles_render", text="Render")
 
-        layout.separator()
+        col = layout.column(align=True)
+        split = col.split()
+        sub = split.column()
+        sub.label(text="Texture Limit Viewport")
+        sub.prop(cscene, "texture_limit", text="")
+        sub = split.column()
+        sub.label(text="Texture Limit Render")
+        sub.prop(cscene, "texture_limit_render", text="")
 
         split = layout.split()
-
         col = split.column()
         col.prop(cscene, "use_camera_cull")
-        col.prop(cscene, "camera_cull_margin", text="Margin")
+        row = col.row()
+        row.active = cscene.use_camera_cull
+        row.prop(cscene, "camera_cull_margin")
 
         col = split.column()
         col.prop(cscene, "use_distance_cull")
-        col.prop(cscene, "distance_cull_margin", text="Distance")
+        row = col.row()
+        row.active = cscene.use_distance_cull
+        row.prop(cscene, "distance_cull_margin", text="Distance")
 
 def draw_device(self, context):
     scene = context.scene
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 6118cc7..38b2ce1 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -504,6 +504,20 @@ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
 	else
 		params.persistent_data = false;
 
+	int texture_limit;
+	if(background) {
+		texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
+	}
+	else {
+		texture_limit = RNA_enum_get(&cscene, "texture_limit");
+	}
+	if(texture_limit > 0 && b_scene.render().use_simplify()) {
+		params.texture_limit = 1 << (texture_limit + 6);
+	}
+	else {
+		params.texture_limit = 0;
+	}
+
 #if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
 	if(is_cpu) {
 		params.use_qbvh = DebugFlags().cpu.qbvh && system_cpu_support_sse2();
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 7465fbd..11193bf 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -19,6 +19,7 @@
 #include "scene.h"
 
 #include "util_foreach.h"
+#include "util_logging.h"
 #include "util_path.h"
 #include "util_progress.h"
 #include "util_texture.h"
@@ -476,6 +477,7 @@ template<TypeDesc::BASETYPE FileFormat,
          typename DeviceType>
 bool ImageManager::file_load_image(Image *img,
                                    ImageDataType type,
+                                   int texture_limit,
                                    device_vector<DeviceType>& tex_img)
 {
 	const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
@@ -485,9 +487,15 @@ bool ImageManager::file_load_image(Image *img,
 		return false;
 	}
 	/* Read RGBA pixels. */
-	StorageType *pixels = (StorageType*)tex_img.resize(width, height, depth);
-	if(pixels == NULL) {
-		return false;
+	vector<StorageType> pixels_storage;
+	StorageType *pixels;
+	const size_t max_size = max(max(width, height), depth);
+	if(texture_limit > 0 && max_size > texture_limit) {
+		pixels_storage.resize(((size_t)width)*height*depth*4);
+		pixels = &pixels_storage[0];
+	}
+	else {
+		pixels = (StorageType*)tex_img.resize(width, height, depth);
 	}
 	bool cmyk = false;
 	if(in) {
@@ -526,12 +534,12 @@ bool ImageManager::file_load_image(Image *img,
 		if(FileFormat == TypeDesc::FLOAT) {
 			builtin_image_float_pixels_cb(img->filename,
 			                              img->builtin_data,
-			                              (float*)pixels);
+			                              (float*)&pixels[0]);
 		}
 		else if(FileFormat == TypeDesc::UINT8) {
 			builtin_image_pixels_cb(img->filename,
 			                        img->builtin_data,
-			                        (uchar*)pixels);
+			                        (uchar*)&pixels[0]);
 		}
 		else {
 			/* TODO(dingto): Support half for ImBuf. */
@@ -540,10 +548,10 @@ bool ImageManager::file_load_image(Image *img,
 	/* Check if we actually have a float4 slot, in case components == 1,
 	 * but device doesn't support single channel textures.
 	 */
-	if(type == IMAGE_DATA_TYPE_FLOAT4 ||
-	   type == IMAGE_DATA_TYPE_HALF4 ||
-	   type == IMAGE_DATA_TYPE_BYTE4)
-	{
+	bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
+	                type == IMAGE_DATA_TYPE_HALF4 ||
+	                type == IMAGE_DATA_TYPE_BYTE4);
+	if(is_rgba) {
 		size_t num_pixels = ((size_t)width) * height * depth;
 		if(cmyk) {
 			/* CMYK */
@@ -587,14 +595,41 @@ bool ImageManager::file_load_image(Image *img,
 			}
 		}
 	}
+	if(pixels_storage.size() > 0) {
+		float scale_factor = 1.0f;
+		while(max_size * scale_factor > texture_limit) {
+			scale_factor *= 0.5f;
+		}
+		VLOG(1) << "Scaling image " << img->filename
+		        << " by a factor of " << scale_factor << ".";
+		vector<StorageType> scaled_pixels;
+		size_t scaled_width, scaled_height, scaled_depth;
+		util_image_resize_pixels(pixels_storage,
+		                         width, height, depth,
+		                         is_rgba ? 4 : 1,
+		                         scale_factor,
+		                         &scaled_pixels,
+		                         &scaled_width, &scaled_height, &scaled_depth);
+		StorageType *texture_pixels = (StorageType*)tex_img.resize(scaled_width,
+		                                                           scaled_height,
+		                                                           scaled_depth);
+		memcpy(texture_pixels,
+		       &scaled_pixels[0],
+		       scaled_pixels.size() * sizeof(StorageType));
+	}
 	return true;
 }
 
-void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot, Progress *progress)
+void ImageManager::device_load_image(Device *device,
+                                     DeviceScene *dscene,
+                                     Scene *scene,
+                                     ImageDataType type,
+                                     int slot,
+                                     Progress *progress)
 {
 	if(progress->get_cancel())
 		return;
-	
+
 	Image *img = images[type][slot];
 
 	if(osl_texture_system && !img->builtin_data)
@@ -603,6 +638,8 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
 	string filename = path_filename(images[type][slot]->filename);
 	progress->set_status("Updating Images", "Loading " + filename);
 
+	const int texture_limit = scene->params.texture_limit;
+
 	/* Slot assignment */
 	int flat_slot = type_index_to_flattened_slot(slot, type);
 
@@ -622,7 +659,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
 			device->tex_free(tex_img);
 		}
 
-		if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
+		if(!file_load_image<TypeDesc::FLOAT, float>(img,
+		                                            type,
+		                                            texture_limit,
+		                                            tex_img))
+		{
 			/* on failure to load, we set a 1x1 pixels pink image */
 			float *pixels = (float*)tex_img.resize(1, 1);
 
@@ -648,7 +689,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
 			device->tex_free(tex_img);
 		}
 
-		if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
+		if(!file_load_image<TypeDesc::FLOAT, float>(img,
+		                                            t

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list