From 006025ead0b89de671363816cd0e962f10d21c50 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 17 Mar 2020 16:48:00 +0100 Subject: 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 --- intern/cycles/kernel/geom/geom_volume.h | 13 +++++++---- .../cycles/kernel/kernels/cpu/kernel_cpu_image.h | 26 +++++++++++++--------- .../cycles/kernel/kernels/cuda/kernel_cuda_image.h | 15 +++++++++++-- .../kernel/kernels/opencl/kernel_opencl_image.h | 12 ++++++++-- intern/cycles/kernel/osl/osl_services.cpp | 4 ++-- intern/cycles/kernel/svm/svm_voxel.h | 2 +- 6 files changed, 51 insertions(+), 21 deletions(-) (limited to 'intern/cycles/kernel') 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::interp_3d(info, x, y, z, interp); + return TextureInterpolator::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_BYTE: - return TextureInterpolator::interp_3d(info, x, y, z, interp); + return TextureInterpolator::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_USHORT: - return TextureInterpolator::interp_3d(info, x, y, z, interp); + return TextureInterpolator::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_FLOAT: - return TextureInterpolator::interp_3d(info, x, y, z, interp); + return TextureInterpolator::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_HALF4: - return TextureInterpolator::interp_3d(info, x, y, z, interp); + return TextureInterpolator::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_BYTE4: - return TextureInterpolator::interp_3d(info, x, y, z, interp); + return TextureInterpolator::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_USHORT4: - return TextureInterpolator::interp_3d(info, x, y, z, interp); + return TextureInterpolator::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_FLOAT4: - return TextureInterpolator::interp_3d(info, x, y, z, interp); + return TextureInterpolator::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 -- cgit v1.2.3