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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2020-03-16 16:42:56 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2020-03-18 13:23:05 +0300
commit7537cad5761e4778da7aed02410c5811114c24e5 (patch)
tree94b0187257e08ecaeaad5cef9eaaa4ec49aa04fd /intern
parent1162ba206dd7792414d3ae716877ba1383de8dab (diff)
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
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_volume.cpp8
-rw-r--r--intern/cycles/kernel/geom/geom_object.h9
-rw-r--r--intern/cycles/kernel/kernel_volume.h8
-rw-r--r--intern/cycles/render/mesh.cpp4
-rw-r--r--intern/cycles/render/mesh.h4
-rw-r--r--intern/cycles/render/mesh_volume.cpp4
-rw-r--r--intern/cycles/render/object.cpp52
7 files changed, 70 insertions, 19 deletions
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)) {