diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_volume.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_volume.h | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h | 26 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h | 15 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h | 12 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_voxel.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/image.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/render/image.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/mesh_volume.cpp | 25 | ||||
-rw-r--r-- | intern/cycles/util/util_texture.h | 6 |
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 |