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:
-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