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-17 18:48:00 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2020-03-18 13:23:05 +0300
commit006025ead0b89de671363816cd0e962f10d21c50 (patch)
tree7126736cb18cbfef6239cdaff1894171252a5d44 /intern
parentfd53b72871e045dfebfb9ddbe2b3c491491aa913 (diff)
Cycles: support for different 3D transform per volume grid
This is not yet fully supported by automatic volume bounds but works fine in most cases that will have mostly matching bounds. Ref T73201
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_volume.cpp10
-rw-r--r--intern/cycles/kernel/geom/geom_volume.h13
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h26
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h15
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h12
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp4
-rw-r--r--intern/cycles/kernel/svm/svm_voxel.h2
-rw-r--r--intern/cycles/render/image.cpp8
-rw-r--r--intern/cycles/render/image.h5
-rw-r--r--intern/cycles/render/mesh_volume.cpp25
-rw-r--r--intern/cycles/util/util_texture.h6
11 files changed, 92 insertions, 34 deletions
diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 237c5d061e8..7f393fcb819 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -15,6 +15,7 @@
*/
#include "render/colorspace.h"
+#include "render/image.h"
#include "render/mesh.h"
#include "render/object.h"
@@ -68,6 +69,15 @@ class BlenderSmokeLoader : public ImageLoader {
metadata.height = resolution.y * amplify;
metadata.depth = resolution.z * amplify;
+ /* Create a matrix to transform from object space to mesh texture space.
+ * This does not work with deformations but that can probably only be done
+ * well with a volume grid mapping of coordinates. */
+ BL::Mesh b_mesh(b_ob.data());
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+ metadata.transform_3d = transform_translate(-loc) * transform_scale(size);
+ metadata.use_transform_3d = true;
+
return true;
}
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
index 96cf35a40dc..f43a7841b46 100644
--- a/intern/cycles/kernel/geom/geom_volume.h
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -51,10 +51,14 @@ ccl_device float volume_attribute_float(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc)
{
- float3 P = volume_normalized_position(kg, sd, sd->P);
+ /* todo: optimize this so we don't have to transform both here and in
+ * kernel_tex_image_interp_3d when possible. Also could optimize for the
+ * common case where transform is translation/scale only. */
+ float3 P = sd->P;
+ object_inverse_position_transform(kg, sd, &P);
InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
INTERPOLATION_NONE;
- float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
+ float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp);
return average(float4_to_float3(r));
}
@@ -62,10 +66,11 @@ ccl_device float3 volume_attribute_float3(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc)
{
- float3 P = volume_normalized_position(kg, sd, sd->P);
+ float3 P = sd->P;
+ object_inverse_position_transform(kg, sd, &P);
InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
INTERPOLATION_NONE;
- float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
+ float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp);
if (r.w > 1e-6f && r.w != 1.0f) {
/* For RGBA colors, unpremultiply after interpolation. */
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
index 7eb66b0b4ca..f87501db258 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
@@ -498,28 +498,34 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
}
}
-ccl_device float4 kernel_tex_image_interp_3d(
- KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
+ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg,
+ int id,
+ float3 P,
+ InterpolationType interp)
{
const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+ if (info.use_transform_3d) {
+ P = transform_point(&info.transform_3d, P);
+ }
+
switch (info.data_type) {
case IMAGE_DATA_TYPE_HALF:
- return TextureInterpolator<half>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<half>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_BYTE:
- return TextureInterpolator<uchar>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<uchar>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_USHORT:
- return TextureInterpolator<uint16_t>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<uint16_t>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_FLOAT:
- return TextureInterpolator<float>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<float>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_HALF4:
- return TextureInterpolator<half4>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<half4>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_BYTE4:
- return TextureInterpolator<uchar4>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<uchar4>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_USHORT4:
- return TextureInterpolator<ushort4>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<ushort4>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_FLOAT4:
- return TextureInterpolator<float4>::interp_3d(info, x, y, z, interp);
+ return TextureInterpolator<float4>::interp_3d(info, P.x, P.y, P.z, interp);
default:
assert(0);
return make_float4(
diff --git a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
index 24bc3c7b59e..1d425d132a1 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
+++ b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
@@ -149,10 +149,21 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
}
}
-ccl_device float4 kernel_tex_image_interp_3d(
- KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
+ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg,
+ int id,
+ float3 P,
+ InterpolationType interp)
{
const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+
+ if (info.use_transform_3d) {
+ P = transform_point(&info.transform_3d, P);
+ }
+
+ const float x = P.x;
+ const float y = P.y;
+ const float z = P.z;
+
CUtexObject tex = (CUtexObject)info.data;
uint interpolation = (interp == INTERPOLATION_NONE) ? info.interpolation : interp;
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
index f7dea383b82..89fcb0ae60f 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
@@ -202,11 +202,19 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
}
}
-ccl_device float4
-kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z, int interp)
+ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float3 P, int interp)
{
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
+ if (info->use_transform_3d) {
+ Transform tfm = info->transform_3d;
+ P = transform_point(&tfm, P);
+ }
+
+ const float x = P.x;
+ const float y = P.y;
+ const float z = P.z;
+
if (info->extension == EXTENSION_CLIP) {
if (x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 4354226ba06..2857de533f3 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -1222,8 +1222,8 @@ bool OSLRenderServices::texture3d(ustring filename,
ShaderData *sd = (ShaderData *)(sg->renderstate);
KernelGlobals *kernel_globals = sd->osl_globals;
int slot = handle->svm_slot;
- float4 rgba = kernel_tex_image_interp_3d(
- kernel_globals, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
+ float3 P_float3 = make_float3(P.x, P.y, P.z);
+ float4 rgba = kernel_tex_image_interp_3d(kernel_globals, slot, P_float3, INTERPOLATION_NONE);
result[0] = rgba[0];
if (nchannels > 1)
diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h
index b79be8e5bde..4bc14f82382 100644
--- a/intern/cycles/kernel/svm/svm_voxel.h
+++ b/intern/cycles/kernel/svm/svm_voxel.h
@@ -39,7 +39,7 @@ ccl_device void svm_node_tex_voxel(
co = transform_point(&tfm, co);
}
- float4 r = kernel_tex_image_interp_3d(kg, id, co.x, co.y, co.z, INTERPOLATION_NONE);
+ float4 r = kernel_tex_image_interp_3d(kg, id, co, INTERPOLATION_NONE);
#else
float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
#endif
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index df8226fb79f..23f97ba5aa3 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -183,6 +183,7 @@ ImageMetaData::ImageMetaData()
type(IMAGE_DATA_NUM_TYPES),
colorspace(u_colorspace_raw),
colorspace_file_format(""),
+ use_transform_3d(false),
compress_as_srgb(false)
{
}
@@ -190,8 +191,9 @@ ImageMetaData::ImageMetaData()
bool ImageMetaData::operator==(const ImageMetaData &other) const
{
return channels == other.channels && width == other.width && height == other.height &&
- depth == other.depth && type == other.type && colorspace == other.colorspace &&
- compress_as_srgb == other.compress_as_srgb;
+ depth == other.depth && use_transform_3d == other.use_transform_3d &&
+ (!use_transform_3d || transform_3d == other.transform_3d) && type == other.type &&
+ colorspace == other.colorspace && compress_as_srgb == other.compress_as_srgb;
}
bool ImageMetaData::is_float() const
@@ -626,6 +628,8 @@ void ImageManager::device_load_image(Device *device, Scene *scene, int slot, Pro
img->mem = new device_texture(
device, img->mem_name.c_str(), slot, type, img->params.interpolation, img->params.extension);
+ img->mem->info.use_transform_3d = img->metadata.use_transform_3d;
+ img->mem->info.transform_3d = img->metadata.transform_3d;
/* Create new texture. */
if (type == IMAGE_DATA_TYPE_FLOAT4) {
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 734bb83f774..00ab12afd7a 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -24,6 +24,7 @@
#include "util/util_string.h"
#include "util/util_thread.h"
+#include "util/util_transform.h"
#include "util/util_unique_ptr.h"
#include "util/util_vector.h"
@@ -81,6 +82,10 @@ class ImageMetaData {
ustring colorspace;
const char *colorspace_file_format;
+ /* Optional transform for 3D images. */
+ bool use_transform_3d;
+ Transform transform_3d;
+
/* Automatically set. */
bool compress_as_srgb;
diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp
index 3c91aba511d..6087fba7a98 100644
--- a/intern/cycles/render/mesh_volume.cpp
+++ b/intern/cycles/render/mesh_volume.cpp
@@ -373,13 +373,15 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
VolumeParams volume_params;
volume_params.resolution = make_int3(0, 0, 0);
+ Transform transform = transform_identity();
+
foreach (Attribute &attr, mesh->attributes.attributes) {
if (attr.element != ATTR_ELEMENT_VOXEL) {
continue;
}
ImageHandle &handle = attr.data_voxel();
- device_memory *image_memory = handle.image_memory();
+ device_texture *image_memory = handle.image_memory();
int3 resolution = make_int3(
image_memory->data_width, image_memory->data_height, image_memory->data_depth);
@@ -387,14 +389,20 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
volume_params.resolution = resolution;
}
else if (volume_params.resolution != resolution) {
- VLOG(1) << "Can't create volume mesh, all voxel grid resolutions must be equal\n";
- return;
+ /* TODO: support this as it's common for OpenVDB. */
+ VLOG(1) << "Can't create accurate volume mesh, all voxel grid resolutions must be equal\n";
+ continue;
}
VoxelAttributeGrid voxel_grid;
voxel_grid.data = static_cast<float *>(image_memory->host_pointer);
voxel_grid.channels = image_memory->data_elements;
voxel_grids.push_back(voxel_grid);
+
+ /* TODO: support multiple transforms. */
+ if (image_memory->info.use_transform_3d) {
+ transform = image_memory->info.transform_3d;
+ }
}
if (voxel_grids.empty()) {
@@ -427,17 +435,14 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
}
/* Compute start point and cell size from transform. */
- Attribute *attr = mesh->attributes.find(ATTR_STD_GENERATED_TRANSFORM);
const int3 resolution = volume_params.resolution;
float3 start_point = make_float3(0.0f, 0.0f, 0.0f);
float3 cell_size = make_float3(1.0f / resolution.x, 1.0f / resolution.y, 1.0f / resolution.z);
- if (attr) {
- const Transform *tfm = attr->data_transform();
- const Transform itfm = transform_inverse(*tfm);
- start_point = transform_point(&itfm, start_point);
- cell_size = transform_direction(&itfm, cell_size);
- }
+ /* TODO: support arbitrary transforms, not just scale + translate. */
+ const Transform itfm = transform_inverse(transform);
+ start_point = transform_point(&itfm, start_point);
+ cell_size = transform_direction(&itfm, cell_size);
volume_params.start_point = start_point;
volume_params.cell_size = cell_size;
diff --git a/intern/cycles/util/util_texture.h b/intern/cycles/util/util_texture.h
index d0672886cba..863c2ea3124 100644
--- a/intern/cycles/util/util_texture.h
+++ b/intern/cycles/util/util_texture.h
@@ -17,6 +17,8 @@
#ifndef __UTIL_TEXTURE_H__
#define __UTIL_TEXTURE_H__
+#include "util_transform.h"
+
CCL_NAMESPACE_BEGIN
/* Texture limits on devices. */
@@ -99,7 +101,9 @@ typedef struct TextureInfo {
uint interpolation, extension;
/* Dimensions. */
uint width, height, depth;
- uint pad[3];
+ /* Transform for 3D textures. */
+ uint use_transform_3d;
+ Transform transform_3d;
} TextureInfo;
CCL_NAMESPACE_END