[Bf-blender-cvs] [342e12d6d92] blender-v3.2-release: Subdiv: support interpolating orco coordinates in subdivision surfaces

Brecht Van Lommel noreply at git.blender.org
Wed May 18 16:45:41 CEST 2022


Commit: 342e12d6d92198bba8355562600a2f97bb45fed5
Author: Brecht Van Lommel
Date:   Thu Jan 14 16:33:52 2021 +0100
Branches: blender-v3.2-release
https://developer.blender.org/rB342e12d6d92198bba8355562600a2f97bb45fed5

Subdiv: support interpolating orco coordinates in subdivision surfaces

This makes changes to the opensubdiv module to support additional vertex data
besides the vertex position, that is smootly interpolated the same way. This is
different than varying data which is interpolated linearly.

Fixes T96596: wrong generated texture coordinates with GPU subdivision. In that
bug lazy subdivision would not interpolate orcos.

Later on, this implementation can also be used to remove the modifier stack
mechanism where modifiers are evaluated a second time for orcos, which is messy
and inefficient. But that's a more risky change, this is just the part to fix
the bug in 3.2.

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

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

M	intern/opensubdiv/internal/evaluator/eval_output.h
M	intern/opensubdiv/internal/evaluator/eval_output_cpu.h
M	intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
M	intern/opensubdiv/internal/evaluator/eval_output_gpu.h
M	intern/opensubdiv/internal/evaluator/evaluator_capi.cc
M	intern/opensubdiv/internal/evaluator/evaluator_impl.cc
M	intern/opensubdiv/internal/evaluator/evaluator_impl.h
M	intern/opensubdiv/opensubdiv_evaluator_capi.h
M	intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc
M	source/blender/blenkernel/BKE_subdiv_eval.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/multires_reshape_smooth.c
M	source/blender/blenkernel/intern/subdiv_eval.c
M	source/blender/blenkernel/intern/subdiv_mesh.c

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

diff --git a/intern/opensubdiv/internal/evaluator/eval_output.h b/intern/opensubdiv/internal/evaluator/eval_output.h
index a55b89001a4..cff7c8d18c9 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output.h
@@ -46,6 +46,8 @@ class EvalOutputAPI::EvalOutput {
 
   virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices) = 0;
 
+  virtual void updateVertexData(const float *src, int start_vertex, int num_vertices) = 0;
+
   virtual void updateFaceVaryingData(const int face_varying_channel,
                                      const float *src,
                                      int start_vertex,
@@ -70,6 +72,11 @@ class EvalOutputAPI::EvalOutput {
                                   const int num_patch_coords,
                                   float *varying) = 0;
 
+  // NOTE: vertex_data must point to a memory of at least float*num_vertex_data.
+  virtual void evalPatchesVertexData(const PatchCoord *patch_coord,
+                                     const int num_patch_coords,
+                                     float *vertex_data) = 0;
+
   virtual void evalPatchesFaceVarying(const int face_varying_channel,
                                       const PatchCoord *patch_coord,
                                       const int num_patch_coords,
@@ -331,11 +338,13 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
                      const StencilTable *varying_stencils,
                      const vector<const StencilTable *> &all_face_varying_stencils,
                      const int face_varying_width,
+                     const int vertex_data_width,
                      const PatchTable *patch_table,
                      EvaluatorCache *evaluator_cache = NULL,
                      DEVICE_CONTEXT *device_context = NULL)
       : src_desc_(0, 3, 3),
         src_varying_desc_(0, 3, 3),
+        src_vertex_data_desc_(0, vertex_data_width, vertex_data_width),
         face_varying_width_(face_varying_width),
         evaluator_cache_(evaluator_cache),
         device_context_(device_context)
@@ -352,6 +361,16 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
                                                                       device_context_);
     varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
                                                                        device_context_);
+
+    // Optionally allocate additional data to be subdivided like vertex coordinates.
+    if (vertex_data_width > 0) {
+      src_vertex_data_ = SRC_VERTEX_BUFFER::Create(
+          vertex_data_width, num_total_vertices, device_context_);
+    }
+    else {
+      src_vertex_data_ = NULL;
+    }
+
     // Create evaluators for every face varying channel.
     face_varying_evaluators.reserve(all_face_varying_stencils.size());
     int face_varying_channel = 0;
@@ -370,6 +389,7 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
   {
     delete src_data_;
     delete src_varying_data_;
+    delete src_vertex_data_;
     delete patch_table_;
     delete vertex_stencils_;
     delete varying_stencils_;
@@ -390,6 +410,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
     src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
   }
 
+  void updateVertexData(const float *src, int start_vertex, int num_vertices) override
+  {
+    src_vertex_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
+  }
+
   void updateFaceVaryingData(const int face_varying_channel,
                              const float *src,
                              int start_vertex,
@@ -426,6 +451,22 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
                             vertex_stencils_,
                             eval_instance,
                             device_context_);
+
+    // Evaluate smoothly interpolated vertex data.
+    if (src_vertex_data_) {
+      BufferDescriptor dst_vertex_data_desc = src_vertex_data_desc_;
+      dst_vertex_data_desc.offset += num_coarse_vertices_ * src_vertex_data_desc_.stride;
+      const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+          evaluator_cache_, src_vertex_data_desc_, dst_vertex_data_desc, device_context_);
+      EVALUATOR::EvalStencils(src_vertex_data_,
+                              src_vertex_data_desc_,
+                              src_vertex_data_,
+                              dst_vertex_data_desc,
+                              vertex_stencils_,
+                              eval_instance,
+                              device_context_);
+    }
+
     // Evaluate varying data.
     if (hasVaryingData()) {
       BufferDescriptor dst_varying_desc = src_varying_desc_;
@@ -521,6 +562,27 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
                                   device_context_);
   }
 
+  // NOTE: data must point to a memory of at least float*num_vertex_data.
+  void evalPatchesVertexData(const PatchCoord *patch_coord,
+                             const int num_patch_coords,
+                             float *data) override
+  {
+    RawDataWrapperBuffer<float> vertex_data(data);
+    BufferDescriptor vertex_desc(0, src_vertex_data_desc_.length, src_vertex_data_desc_.length);
+    ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
+    const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
+        evaluator_cache_, src_vertex_data_desc_, vertex_desc, device_context_);
+    EVALUATOR::EvalPatches(src_vertex_data_,
+                           src_vertex_data_desc_,
+                           &vertex_data,
+                           vertex_desc,
+                           patch_coord_buffer.GetNumVertices(),
+                           &patch_coord_buffer,
+                           patch_table_,
+                           eval_instance,
+                           device_context_);
+  }
+
   void evalPatchesFaceVarying(const int face_varying_channel,
                               const PatchCoord *patch_coord,
                               const int num_patch_coords,
@@ -560,9 +622,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
  private:
   SRC_VERTEX_BUFFER *src_data_;
   SRC_VERTEX_BUFFER *src_varying_data_;
+  SRC_VERTEX_BUFFER *src_vertex_data_;
   PATCH_TABLE *patch_table_;
   BufferDescriptor src_desc_;
   BufferDescriptor src_varying_desc_;
+  BufferDescriptor src_vertex_data_desc_;
 
   int num_coarse_vertices_;
 
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_cpu.h b/intern/opensubdiv/internal/evaluator/eval_output_cpu.h
index 58bae7a322e..2b3c738d6ab 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_cpu.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output_cpu.h
@@ -44,6 +44,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
                 const StencilTable *varying_stencils,
                 const vector<const StencilTable *> &all_face_varying_stencils,
                 const int face_varying_width,
+                const int vertex_data_width,
                 const PatchTable *patch_table,
                 EvaluatorCache *evaluator_cache = NULL)
       : VolatileEvalOutput<CpuVertexBuffer,
@@ -54,6 +55,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
                                          varying_stencils,
                                          all_face_varying_stencils,
                                          face_varying_width,
+                                         vertex_data_width,
                                          patch_table,
                                          evaluator_cache)
   {
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
index b352ed2c014..566071d581b 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
+++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
@@ -45,6 +45,7 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils,
                              const StencilTable *varying_stencils,
                              const vector<const StencilTable *> &all_face_varying_stencils,
                              const int face_varying_width,
+                             const int vertex_data_width,
                              const PatchTable *patch_table,
                              VolatileEvalOutput::EvaluatorCache *evaluator_cache)
     : VolatileEvalOutput<GLVertexBuffer,
@@ -55,6 +56,7 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils,
                                              varying_stencils,
                                              all_face_varying_stencils,
                                              face_varying_width,
+                                             vertex_data_width,
                                              patch_table,
                                              evaluator_cache)
 {
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
index dc137e4322e..2306a87b87c 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
@@ -40,6 +40,7 @@ class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer,
                 const StencilTable *varying_stencils,
                 const vector<const StencilTable *> &all_face_varying_stencils,
                 const int face_varying_width,
+                const int vertex_data_width,
                 const PatchTable *patch_table,
                 EvaluatorCache *evaluator_cache = NULL);
 
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
index 567afd3a763..8a54ed653dc 100644
--- a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
+++ b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
@@ -36,6 +36,14 @@ void setCoarsePositions(OpenSubdiv_Evaluator *evaluator,
   evaluator->

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list