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:
authorMai Lavelle <mai.lavelle@gmail.com>2016-09-17 01:07:24 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-09-22 13:33:32 +0300
commit7da7611c0b9ddea0be5fd9a512523ab46bf257b2 (patch)
treec73dbb66e6189edb19ca3e3d457ee59536274958
parentd14603021ce825a579a297312c2cc7031a34ccd4 (diff)
Cycles: Adaptive isolation
Idea here is to select the lowest isolation level that wont compromise quality. By using the lowest level we save memory and processing time. This will also help avoid precision issues that have been showing up from using the highest level (T49179, T49257). This is a pretty simple heuristic that gives ok results. There's more we could do here, such as filtering for vertices/edges adjacent geometric features that need isolation instead of checking them all, but the logic there could get a bit involved. There's potential for slight popping of edges during animation if the dice rate is low, but I don't think this should be a problem since low dice rates really shouldn't be used in animation anyways. Reviewed By: brecht, sergey Differential Revision: https://developer.blender.org/D2240
-rw-r--r--intern/cycles/render/mesh_subdivision.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp
index 3b4841f5b20..0ae5ff742c2 100644
--- a/intern/cycles/render/mesh_subdivision.cpp
+++ b/intern/cycles/render/mesh_subdivision.cpp
@@ -16,12 +16,14 @@
#include "mesh.h"
#include "attribute.h"
+#include "camera.h"
#include "subd_split.h"
#include "subd_patch.h"
#include "subd_patch_table.h"
#include "util_foreach.h"
+#include "util_algorithm.h"
CCL_NAMESPACE_BEGIN
@@ -177,7 +179,7 @@ public:
Far::TopologyRefinerFactory<Mesh>::Options(type, options));
/* adaptive refinement */
- int max_isolation = 10;
+ int max_isolation = calculate_max_isolation();
refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
/* create patch table */
@@ -248,6 +250,42 @@ public:
}
}
+ int calculate_max_isolation()
+ {
+ /* loop over all edges to find longest in screen space */
+ const Far::TopologyLevel& level = refiner->GetLevel(0);
+ Transform objecttoworld = mesh->subd_params->objecttoworld;
+ Camera* cam = mesh->subd_params->camera;
+
+ float longest_edge = 0.0f;
+
+ for(size_t i = 0; i < level.GetNumEdges(); i++) {
+ Far::ConstIndexArray verts = level.GetEdgeVertices(i);
+
+ float3 a = mesh->verts[verts[0]];
+ float3 b = mesh->verts[verts[1]];
+
+ float edge_len;
+
+ if(cam) {
+ a = transform_point(&objecttoworld, a);
+ b = transform_point(&objecttoworld, b);
+
+ edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f);
+ }
+ else {
+ edge_len = len(a - b);
+ }
+
+ longest_edge = max(longest_edge, edge_len);
+ }
+
+ /* calculate isolation level */
+ int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f);
+
+ return min(isolation, 10);
+ }
+
friend struct OsdPatch;
friend class Mesh;
};