[Bf-blender-cvs] [b0c7dda4a75] temp-udim-images: Try to detect unused tiles when rendering with Cycles and skip loading them

Lukas Stockner noreply at git.blender.org
Sat Jun 16 13:49:51 CEST 2018


Commit: b0c7dda4a75e4f5b999cb1101685263fa6c0aa39
Author: Lukas Stockner
Date:   Sat Jun 16 13:39:56 2018 +0200
Branches: temp-udim-images
https://developer.blender.org/rBb0c7dda4a75e4f5b999cb1101685263fa6c0aa39

Try to detect unused tiles when rendering with Cycles and skip loading them

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

M	intern/cycles/blender/blender_shader.cpp
M	intern/cycles/blender/blender_sync.cpp
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/graph.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	intern/cycles/render/scene.h
M	intern/cycles/render/shader.cpp

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

diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index f4f6f4fe310..0bcbcbb4991 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -1269,7 +1269,7 @@ void BlenderSync::sync_materials(BL::Depsgraph& b_depsgraph, bool update_all)
 
 		/* test if we need to sync */
 		if(shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) {
-			ShaderGraph *graph = new ShaderGraph();
+			ShaderGraph *graph = new ShaderGraph(shader);
 
 			shader->name = b_mat.name().c_str();
 			shader->pass_id = b_mat.pass_index();
@@ -1344,7 +1344,7 @@ void BlenderSync::sync_world(BL::Depsgraph& b_depsgraph, bool update_all)
 
 	if(world_recalc || update_all || b_world.ptr.data != world_map) {
 		Shader *shader = scene->default_background;
-		ShaderGraph *graph = new ShaderGraph();
+		ShaderGraph *graph = new ShaderGraph(shader);
 
 		/* create nodes */
 		if(b_world && b_world.use_nodes() && b_world.node_tree()) {
@@ -1442,7 +1442,7 @@ void BlenderSync::sync_lamps(BL::Depsgraph& b_depsgraph, bool update_all)
 
 		/* test if we need to sync */
 		if(shader_map.sync(&shader, b_lamp) || update_all) {
-			ShaderGraph *graph = new ShaderGraph();
+			ShaderGraph *graph = new ShaderGraph(shader);
 
 			/* create nodes */
 			if(b_lamp.use_nodes() && b_lamp.node_tree()) {
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 0c27786f241..6affacdeca0 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -611,6 +611,8 @@ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
 
 	params.bvh_layout = DebugFlags().cpu.bvh_layout;
 
+	params.background = background;
+
 	return params;
 }
 
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 8b179f742c4..b29bf98c23e 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -193,7 +193,8 @@ bool ShaderNode::equals(const ShaderNode& other)
 
 /* Graph */
 
-ShaderGraph::ShaderGraph()
+ShaderGraph::ShaderGraph(Shader *shader)
+ : shader(shader)
 {
 	finalized = false;
 	simplified = false;
@@ -557,7 +558,7 @@ void ShaderGraph::constant_fold(Scene *scene)
 void ShaderGraph::simplify_settings(Scene *scene)
 {
 	foreach(ShaderNode *node, nodes) {
-		node->simplify_settings(scene);
+		node->simplify_settings(scene, shader);
 	}
 }
 
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 5d986ae4827..8fd47324941 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -147,7 +147,7 @@ public:
 	/* Simplify settings used by artists to the ones which are simpler to
 	 * evaluate in the kernel but keep the final result unchanged.
 	 */
-	virtual void simplify_settings(Scene * /*scene*/) {};
+	virtual void simplify_settings(Scene * /*scene*/, Shader * /*shader*/) {};
 
 	virtual bool has_surface_emission() { return false; }
 	virtual bool has_surface_transparent() { return false; }
@@ -246,8 +246,9 @@ public:
 	bool finalized;
 	bool simplified;
 	string displacement_hash;
+	Shader *shader;
 
-	ShaderGraph();
+	ShaderGraph(Shader *shader);
 	~ShaderGraph();
 
 	ShaderNode *add(ShaderNode *node);
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 0b0ff11f0b1..787814dba6b 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -661,6 +661,61 @@ void Mesh::add_subd_face(int* corners, int num_corners, int shader_, bool smooth
 	subd_faces.push_back_reserved(face);
 }
 
+static void get_uv_tiles_from_attribute(Attribute *attr, int num, vector<bool> &tiles)
+{
+	if(!attr) {
+		return;
+	}
+
+	const float3 *uv = attr->data_float3();
+	int size = tiles.size();
+	for(int i = 0; i < num; i++, uv++) {
+		float u = uv->x, v = uv->y;
+
+		if(u < 0.0f || v < 0.0f || u > 10.0f) continue;
+
+		int x = (int) u, y = (int) v;
+
+		/* Be conservative in corners - precisely touching the right-upper corner of a tile
+		* should not load its right-upper neighbor as well. */
+		if(x && (u == x)) x--;
+		if(y && (v == y)) y--;
+
+		int id = y*10 + x;
+		if(id >= size) {
+			tiles.resize(id+1);
+			size = id;
+		}
+		tiles[id] = true;
+	}
+}
+
+void Mesh::get_uv_tiles(ustring map, vector<bool> &tiles)
+{
+	if(map.empty()) {
+		get_uv_tiles_from_attribute(attributes.find(ATTR_STD_UV),
+		                            num_triangles()*3,
+		                            tiles);
+		get_uv_tiles_from_attribute(subd_attributes.find(ATTR_STD_UV),
+		                            subd_face_corners.size() + num_ngons,
+		                            tiles);
+		get_uv_tiles_from_attribute(curve_attributes.find(ATTR_STD_UV),
+		                            num_curves(),
+		                            tiles);
+	}
+	else {
+		get_uv_tiles_from_attribute(attributes.find(map),
+		                            num_triangles()*3,
+		                            tiles);
+		get_uv_tiles_from_attribute(subd_attributes.find(map),
+		                            subd_face_corners.size() + num_ngons,
+		                            tiles);
+		get_uv_tiles_from_attribute(curve_attributes.find(map),
+		                            num_curves(),
+		                            tiles);
+	}
+}
+
 void Mesh::compute_bounds()
 {
 	BoundBox bnds = BoundBox::empty;
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index e370f8a2021..113bbb74960 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -279,6 +279,8 @@ public:
 	void add_vertex_normals();
 	void add_undisplaced();
 
+	void get_uv_tiles(ustring map, vector<bool> &tiles);
+
 	void pack_shaders(Scene *scene, uint *shader);
 	void pack_normals(float4 *vnormal);
 	void pack_verts(const vector<uint>& tri_prim_index,
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 6a3e27f9aee..95bd19d236a 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -18,6 +18,7 @@
 #include "render/image.h"
 #include "render/integrator.h"
 #include "render/light.h"
+#include "render/mesh.h"
 #include "render/nodes.h"
 #include "render/scene.h"
 #include "render/svm.h"
@@ -275,6 +276,49 @@ ShaderNode *ImageTextureNode::clone() const
 	return node;
 }
 
+void ImageTextureNode::simplify_settings(Scene *scene, Shader *shader)
+{
+	if(!scene->params.background) {
+		/* During interactive renders, all tiles are loaded.
+		 * While we could support updating this when UVs change, that could lead
+		 * to annoying interruptions when loading images while editing UVs. */
+		return;
+	}
+
+	ShaderInput *vector_in = input("Vector");
+	ustring attribute;
+	if(vector_in->link) {
+		ShaderNode *node = vector_in->link->parent;
+		if(node->type == UVMapNode::node_type) {
+			UVMapNode *uvmap = (UVMapNode*) node;
+			attribute = uvmap->attribute;
+		}
+		else if(node->type == TextureCoordinateNode::node_type) {
+			if(vector_in->link != node->output("UV")) {
+				return;
+			}
+		}
+		else {
+			return;
+		}
+	}
+
+	ccl::vector<bool> used_tiles;
+	foreach(Mesh *mesh, scene->meshes) {
+		if(std::find(mesh->used_shaders.begin(), mesh->used_shaders.end(), shader) != mesh->used_shaders.end()) {
+			mesh->get_uv_tiles(attribute, used_tiles);
+		}
+	}
+
+	ccl::vector<int> new_tiles;
+	foreach(int tile, tiles) {
+		if (tile < used_tiles.size() && used_tiles[tile]) {
+			new_tiles.push_back(tile);
+		}
+	}
+	tiles.swap(new_tiles);
+}
+
 void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
 {
 #ifdef WITH_PTEX
@@ -307,6 +351,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
 			else {
 				tile_name = string_printf(filename.c_str(), 1001 + tile);
 			}
+			printf("Loading %s\n", tile_name.c_str());
 			ImageMetaData metadata;
 			slots.push_back(image_manager->add_image(tile_name,
 			                                         builtin_data,
@@ -2057,7 +2102,7 @@ GlossyBsdfNode::GlossyBsdfNode()
 	distribution_orig = NBUILTIN_CLOSURES;
 }
 
-void GlossyBsdfNode::simplify_settings(Scene *scene)
+void GlossyBsdfNode::simplify_settings(Scene *scene, Shader * /*shader*/)
 {
 	if(distribution_orig == NBUILTIN_CLOSURES) {
 		roughness_orig = roughness;
@@ -2152,7 +2197,7 @@ GlassBsdfNode::GlassBsdfNode()
 	distribution_orig = NBUILTIN_CLOSURES;
 }
 
-void GlassBsdfNode::simplify_settings(Scene *scene)
+void GlassBsdfNode::simplify_settings(Scene *scene, Shader * /*shader*/)
 {
 	if(distribution_orig == NBUILTIN_CLOSURES) {
 		roughness_orig = roughness;
@@ -2247,7 +2292,7 @@ RefractionBsdfNode::RefractionBsdfNode()
 	distribution_orig = NBUILTIN_CLOSURES;
 }
 
-void RefractionBsdfNode::simplify_settings(Scene *scene)
+void RefractionBsdfNode::simplify_settings(Scene *scene, Shader * /*shader*/)
 {
 	if(distribution_orig == NBUILTIN_CLOSURES) {
 		roughness_orig = roughness;
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 7d234fe240a..e633c057f71 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -84,6 +84,7 @@ public:
 	ShaderNode *clone() const;
 	void attributes(Shader *shader, AttributeRequestSet *attributes);
 	bool has_attribute_dependency() { return true; }
+	void simplify_settings(Scene *scene, Shader *shader);
 
 	ImageManager *image_manager;
 	bool is_float;
@@ -449,7 +450,7 @@ class GlossyBsdfNode : public BsdfNode {
 public:
 	SHADER_NODE_CLASS(GlossyBsdfNode)
 
-	void simplify_settings(Scene *scene);
+	void simplify_settings(Scene *scene, Shader *shader);
 	bool has_integrator_dependency();
 	ClosureType get_closure_type() { return distribution; }
 
@@ -461,7 +462,7 @@ class GlassBsdfNode : public BsdfNode {
 public:
 	SHADER_NODE_CLASS(GlassBsdfNode)
 
-	void simplify_settings(Scene *scene);
+	void simplify_settings(Scene *scene, Shader *shader);
 	bool has_integrator_dependency();
 	ClosureType get_closure_type() { return distribution; }
 
@@ -473,7 +474,7 @@ class RefractionBsdfNode : public BsdfNode {
 public:
 	SHADER_NODE_CLASS(RefractionBsdfNode)
 
-	void simplify_settings(Scene *scene);
+	void simplify_settings(Scene *scene, Shader *shader);
 	bool has_integrator_dependency();
 	ClosureType get_closure_type() { return distribution; 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list