[Bf-blender-cvs] [7537cad5761] master: Volumes: add render settings for volume datablock

Brecht Van Lommel noreply at git.blender.org
Wed Mar 18 11:23:45 CET 2020


Commit: 7537cad5761e4778da7aed02410c5811114c24e5
Author: Brecht Van Lommel
Date:   Mon Mar 16 14:42:56 2020 +0100
Branches: master
https://developer.blender.org/rB7537cad5761e4778da7aed02410c5811114c24e5

Volumes: add render settings for volume datablock

* Space: volume density and step size in object or world space
* Step Size: override automatic step size
* Clipping: values below this are ignored for tighter volume bounds

The last two are Cycles only currently.

Ref T73201

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

M	intern/cycles/blender/blender_volume.cpp
M	intern/cycles/kernel/geom/geom_object.h
M	intern/cycles/kernel/kernel_volume.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/mesh_volume.cpp
M	intern/cycles/render/object.cpp
M	release/scripts/startup/bl_ui/properties_data_volume.py
M	source/blender/blenkernel/BKE_volume_render.h
M	source/blender/blenkernel/intern/volume_render.cc
M	source/blender/draw/engines/eevee/eevee_volumes.c
M	source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
M	source/blender/draw/engines/workbench/workbench_volume.c

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

diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index ee64796b393..6254a1a1b24 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -207,7 +207,7 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
       continue;
     }
 
-    mesh->volume_isovalue = b_domain.clipping();
+    mesh->volume_clipping = b_domain.clipping();
 
     Attribute *attr = mesh->attributes.add(std);
 
@@ -292,7 +292,11 @@ static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *s
   BL::Volume b_volume(b_ob.data());
   b_volume.grids.load(b_data.ptr.data);
 
-  mesh->volume_isovalue = 1e-3f; /* TODO: make user setting. */
+  BL::VolumeRender b_render(b_volume.render());
+
+  mesh->volume_clipping = b_render.clipping();
+  mesh->volume_step_size = b_render.step_size();
+  mesh->volume_object_space = (b_render.space() == BL::VolumeRender::space_OBJECT);
 
   /* Find grid with matching name. */
   BL::Volume::grids_iterator b_grid_iter;
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index c6d02ed9702..3aa68e1f84e 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -322,6 +322,15 @@ ccl_device_inline uint object_patch_map_offset(KernelGlobals *kg, int object)
 
 /* Volume step size */
 
+ccl_device_inline float object_volume_density(KernelGlobals *kg, int object)
+{
+  if (object == OBJECT_NONE) {
+    return 1.0f;
+  }
+
+  return kernel_tex_fetch(__objects, object).surface_area;
+}
+
 ccl_device_inline float object_volume_step_size(KernelGlobals *kg, int object)
 {
   if (object == OBJECT_NONE) {
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 035fcdbc8e1..b4f9d2186f4 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -48,7 +48,8 @@ ccl_device_inline bool volume_shader_extinction_sample(KernelGlobals *kg,
   shader_eval_volume(kg, sd, state, state->volume_stack, PATH_RAY_SHADOW);
 
   if (sd->flag & SD_EXTINCTION) {
-    *extinction = sd->closure_transparent_extinction;
+    const float density = object_volume_density(kg, sd->object);
+    *extinction = sd->closure_transparent_extinction * density;
     return true;
   }
   else {
@@ -84,6 +85,11 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals *kg,
     }
   }
 
+  const float density = object_volume_density(kg, sd->object);
+  coeff->sigma_s *= density;
+  coeff->sigma_t *= density;
+  coeff->emission *= density;
+
   return true;
 }
 
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index e80e87f2980..f855697b889 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -145,7 +145,9 @@ Mesh::Mesh() : Geometry(node_type, Geometry::MESH), subd_attributes(this, ATTR_P
 
   num_subd_verts = 0;
 
-  volume_isovalue = 0.001f;
+  volume_clipping = 0.001f;
+  volume_step_size = 0.0f;
+  volume_object_space = false;
 
   num_ngons = 0;
 
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 5583e9c0400..d0cf4d557aa 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -133,7 +133,9 @@ class Mesh : public Geometry {
   array<int> triangle_patch; /* must be < 0 for non subd triangles */
   array<float2> vert_patch_uv;
 
-  float volume_isovalue;
+  float volume_clipping;
+  float volume_step_size;
+  bool volume_object_space;
 
   array<SubdFace> subd_faces;
   array<int> subd_face_corners;
diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp
index 6087fba7a98..241be2d7592 100644
--- a/intern/cycles/render/mesh_volume.cpp
+++ b/intern/cycles/render/mesh_volume.cpp
@@ -450,7 +450,7 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
 
   /* Build bounding mesh around non-empty volume cells. */
   VolumeMeshBuilder builder(&volume_params);
-  const float isovalue = mesh->volume_isovalue;
+  const float clipping = mesh->volume_clipping;
 
   for (int z = 0; z < resolution.z; ++z) {
     for (int y = 0; y < resolution.y; ++y) {
@@ -462,7 +462,7 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
           const int channels = voxel_grid.channels;
 
           for (int c = 0; c < channels; c++) {
-            if (voxel_grid.data[voxel_index * channels + c] >= isovalue) {
+            if (voxel_grid.data[voxel_index * channels + c] >= clipping) {
               builder.add_node_with_padding(x, y, z);
               break;
             }
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index c84007823d2..342a641c0be 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -270,14 +270,20 @@ uint Object::visibility_for_tracing() const
 
 float Object::compute_volume_step_size() const
 {
-  if (!geometry->has_volume) {
+  if (geometry->type != Geometry::MESH) {
+    return FLT_MAX;
+  }
+
+  Mesh *mesh = static_cast<Mesh *>(geometry);
+
+  if (!mesh->has_volume) {
     return FLT_MAX;
   }
 
   /* Compute step rate from shaders. */
   float step_rate = FLT_MAX;
 
-  foreach (Shader *shader, geometry->used_shaders) {
+  foreach (Shader *shader, mesh->used_shaders) {
     if (shader->has_volume) {
       if ((shader->heterogeneous_volume && shader->has_volume_spatial_varying) ||
           (shader->has_volume_attribute_dependency)) {
@@ -293,7 +299,7 @@ float Object::compute_volume_step_size() const
   /* Compute step size from voxel grids. */
   float step_size = FLT_MAX;
 
-  foreach (Attribute &attr, geometry->attributes.attributes) {
+  foreach (Attribute &attr, mesh->attributes.attributes) {
     if (attr.element == ATTR_ELEMENT_VOXEL) {
       ImageHandle &handle = attr.data_voxel();
       const ImageMetaData &metadata = handle.metadata();
@@ -301,15 +307,26 @@ float Object::compute_volume_step_size() const
         continue;
       }
 
-      /* Step size is transformed from voxel to world space. */
-      Transform voxel_tfm = tfm;
-      if (metadata.use_transform_3d) {
-        voxel_tfm = tfm * transform_inverse(metadata.transform_3d);
-      }
+      /* User specified step size. */
+      float voxel_step_size = mesh->volume_step_size;
+
+      if (voxel_step_size == 0.0f) {
+        /* Auto detect step size. */
+        float3 size = make_float3(
+            1.0f / metadata.width, 1.0f / metadata.height, 1.0f / metadata.depth);
 
-      float3 size = make_float3(
-          1.0f / metadata.width, 1.0f / metadata.height, 1.0f / metadata.depth);
-      float voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size)));
+        /* Step size is transformed from voxel to world space. */
+        Transform voxel_tfm = tfm;
+        if (metadata.use_transform_3d) {
+          voxel_tfm = tfm * transform_inverse(metadata.transform_3d);
+        }
+        voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size)));
+      }
+      else if (mesh->volume_object_space) {
+        /* User specified step size in object space. */
+        float3 size = make_float3(voxel_step_size, voxel_step_size, voxel_step_size);
+        voxel_step_size = min3(fabs(transform_direction(&tfm, size)));
+      }
 
       if (voxel_step_size > 0.0f) {
         step_size = fminf(voxel_step_size, step_size);
@@ -352,12 +369,23 @@ static float object_surface_area(UpdateObjectTransformState *state,
     return 0.0f;
   }
 
+  Mesh *mesh = static_cast<Mesh *>(geom);
+  if (mesh->has_volume) {
+    /* Volume density automatically adjust to object scale. */
+    if (mesh->volume_object_space) {
+      const float3 unit = normalize(make_float3(1.0f, 1.0f, 1.0f));
+      return 1.0f / len(transform_direction(&tfm, unit));
+    }
+    else {
+      return 1.0f;
+    }
+  }
+
   /* Compute surface area. for uniform scale we can do avoid the many
    * transform calls and share computation for instances.
    *
    * TODO(brecht): Correct for displacement, and move to a better place.
    */
-  Mesh *mesh = static_cast<Mesh *>(geom);
   float surface_area = 0.0f;
   float uniform_scale;
   if (transform_uniform_scale(tfm, uniform_scale)) {
diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py
index bc098e81ffb..b10bb808edd 100644
--- a/release/scripts/startup/bl_ui/properties_data_volume.py
+++ b/release/scripts/startup/bl_ui/properties_data_volume.py
@@ -108,6 +108,29 @@ class DATA_PT_volume_grids(DataButtonsPanel, Panel):
         layout.template_list("VOLUME_UL_grids", "grids", volume, "grids", volume.grids, "active_index", rows=3)
 
 
+class DATA_PT_volume_render(DataButtonsPanel, Panel):
+    bl_label = "Render"
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        scene = context.scene
+        volume = context.volume
+        render = volume.render
+
+        col = layout.column(align=True)
+        col.prop(render, "space")
+
+        if scene.render.engine == 'CYCLES':
+            col.prop(render, "step_size")
+
+            col = layout.column(align=True)
+            col.prop(render, "clipping")
+
+
 class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel):
     bl_label = "Viewport Display"
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@@ -140,6 +163,7 @@ classes = (
     DATA_PT_volume_grids,
     DATA_PT_volume_file,
     DATA_PT_volume_viewport_display,
+    DATA_PT_volume_render,
     DATA_PT_custom_props_volume,
     VOLUME_UL_grids,
 )
diff --git a/source/blender/blenkernel/BKE_volume_render.h b/source/blender/blenkernel/BKE_volume_render.h
index 72360f316a0..53f683f0eaf 100644
--- a/source/blender/blenkernel/BKE_volume_render.h
+++ b/source/blender/blenkernel/BKE_volume_render.h
@@ -65,6 +65,10 @@ void BKE_volume_grid_wireframe(const struct Volume *volume,
                                BKE_volume_wireframe_cb cb,
                                void *cb_user

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list