diff options
-rw-r--r-- | intern/cycles/blender/volume.cpp | 22 | ||||
-rw-r--r-- | intern/cycles/device/cuda/device_impl.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/device/hip/device_impl.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/device/memory.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/device/cpu/image.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/device/gpu/image.h | 13 | ||||
-rw-r--r-- | intern/cycles/scene/image.cpp | 11 | ||||
-rw-r--r-- | intern/cycles/scene/image_oiio.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/scene/image_vdb.cpp | 31 | ||||
-rw-r--r-- | intern/cycles/scene/image_vdb.h | 1 | ||||
-rw-r--r-- | intern/cycles/scene/object.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/util/texture.h | 2 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_volume.py | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_volume_defaults.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_volume_types.h | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_volume.c | 15 |
16 files changed, 119 insertions, 13 deletions
diff --git a/intern/cycles/blender/volume.cpp b/intern/cycles/blender/volume.cpp index 8dd2d45c0b6..a9a2c474f40 100644 --- a/intern/cycles/blender/volume.cpp +++ b/intern/cycles/blender/volume.cpp @@ -219,7 +219,10 @@ static void sync_smoke_volume( class BlenderVolumeLoader : public VDBImageLoader { public: - BlenderVolumeLoader(BL::BlendData &b_data, BL::Volume &b_volume, const string &grid_name) + BlenderVolumeLoader(BL::BlendData &b_data, + BL::Volume &b_volume, + const string &grid_name, + BL::VolumeRender::precision_enum precision_) : VDBImageLoader(grid_name), b_volume(b_volume) { b_volume.grids.load(b_data.ptr.data); @@ -241,6 +244,20 @@ class BlenderVolumeLoader : public VDBImageLoader { } } #endif +#ifdef WITH_NANOVDB + switch (precision_) { + case BL::VolumeRender::precision_FULL: + precision = 32; + break; + case BL::VolumeRender::precision_HALF: + precision = 16; + break; + default: + case BL::VolumeRender::precision_VARIABLE: + precision = 0; + break; + } +#endif } BL::Volume b_volume; @@ -318,7 +335,8 @@ static void sync_volume_object(BL::BlendData &b_data, volume->attributes.add(std) : volume->attributes.add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL); - ImageLoader *loader = new BlenderVolumeLoader(b_data, b_volume, name.string()); + ImageLoader *loader = new BlenderVolumeLoader( + b_data, b_volume, name.string(), b_render.precision()); ImageParams params; params.frame = b_volume.grids.frame(); diff --git a/intern/cycles/device/cuda/device_impl.cpp b/intern/cycles/device/cuda/device_impl.cpp index 6908ae5ead3..75177566901 100644 --- a/intern/cycles/device/cuda/device_impl.cpp +++ b/intern/cycles/device/cuda/device_impl.cpp @@ -1084,7 +1084,9 @@ void CUDADevice::tex_alloc(device_texture &mem) need_texture_info = true; if (mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT && - mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) { + mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 && + mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FPN && + mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FP16) { CUDA_RESOURCE_DESC resDesc; memset(&resDesc, 0, sizeof(resDesc)); diff --git a/intern/cycles/device/hip/device_impl.cpp b/intern/cycles/device/hip/device_impl.cpp index 7159277b325..f8fdb86ca29 100644 --- a/intern/cycles/device/hip/device_impl.cpp +++ b/intern/cycles/device/hip/device_impl.cpp @@ -1042,7 +1042,9 @@ void HIPDevice::tex_alloc(device_texture &mem) need_texture_info = true; if (mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT && - mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) { + mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 && + mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FPN && + mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FP16) { /* Bindless textures. */ hipResourceDesc resDesc; memset(&resDesc, 0, sizeof(resDesc)); diff --git a/intern/cycles/device/memory.cpp b/intern/cycles/device/memory.cpp index 4c068dbdd3e..40cf2573cfb 100644 --- a/intern/cycles/device/memory.cpp +++ b/intern/cycles/device/memory.cpp @@ -165,6 +165,8 @@ device_texture::device_texture(Device *device, case IMAGE_DATA_TYPE_BYTE: case IMAGE_DATA_TYPE_NANOVDB_FLOAT: case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: + case IMAGE_DATA_TYPE_NANOVDB_FPN: + case IMAGE_DATA_TYPE_NANOVDB_FP16: data_type = TYPE_UCHAR; data_elements = 1; break; diff --git a/intern/cycles/kernel/device/cpu/image.h b/intern/cycles/kernel/device/cpu/image.h index 3b714a3e580..4963a732916 100644 --- a/intern/cycles/kernel/device/cpu/image.h +++ b/intern/cycles/kernel/device/cpu/image.h @@ -817,6 +817,14 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg, } case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: return NanoVDBInterpolator<nanovdb::Vec3f>::interp_3d(info, P.x, P.y, P.z, interp); + case IMAGE_DATA_TYPE_NANOVDB_FPN: { + const float f = NanoVDBInterpolator<nanovdb::FpN, float>::interp_3d(info, P.x, P.y, P.z, interp); + return make_float4(f, f, f, 1.0f); + } + case IMAGE_DATA_TYPE_NANOVDB_FP16: { + const float f = NanoVDBInterpolator<nanovdb::Fp16, float>::interp_3d(info, P.x, P.y, P.z, interp); + return make_float4(f, f, f, 1.0f); + } #endif default: assert(0); diff --git a/intern/cycles/kernel/device/gpu/image.h b/intern/cycles/kernel/device/gpu/image.h index c5bc7d88e02..29d851ae478 100644 --- a/intern/cycles/kernel/device/gpu/image.h +++ b/intern/cycles/kernel/device/gpu/image.h @@ -125,7 +125,8 @@ kernel_tex_image_interp_tricubic(ccl_global const TextureInfo &info, float x, fl #ifdef WITH_NANOVDB template<typename T, typename S> -ccl_device T kernel_tex_image_interp_tricubic_nanovdb(S &s, float x, float y, float z) +ccl_device typename nanovdb::NanoGrid<T>::ValueType kernel_tex_image_interp_tricubic_nanovdb( + S &s, float x, float y, float z) { float px = floorf(x); float py = floorf(y); @@ -157,7 +158,7 @@ ccl_device T kernel_tex_image_interp_tricubic_nanovdb(S &s, float x, float y, fl } template<typename T> -ccl_device_noinline T kernel_tex_image_interp_nanovdb( +ccl_device_noinline typename nanovdb::NanoGrid<T>::ValueType kernel_tex_image_interp_nanovdb( ccl_global const TextureInfo &info, float x, float y, float z, uint interpolation) { using namespace nanovdb; @@ -238,6 +239,14 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg, info, x, y, z, interpolation); return make_float4(f[0], f[1], f[2], 1.0f); } + if (texture_type == IMAGE_DATA_TYPE_NANOVDB_FPN) { + float f = kernel_tex_image_interp_nanovdb<nanovdb::FpN>(info, x, y, z, interpolation); + return make_float4(f, f, f, 1.0f); + } + if (texture_type == IMAGE_DATA_TYPE_NANOVDB_FP16) { + float f = kernel_tex_image_interp_nanovdb<nanovdb::Fp16>(info, x, y, z, interpolation); + return make_float4(f, f, f, 1.0f); + } #endif if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 || texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) { diff --git a/intern/cycles/scene/image.cpp b/intern/cycles/scene/image.cpp index c61ad1f1d71..2aa9a6bc1a1 100644 --- a/intern/cycles/scene/image.cpp +++ b/intern/cycles/scene/image.cpp @@ -64,6 +64,10 @@ const char *name_from_type(ImageDataType type) return "nanovdb_float"; case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: return "nanovdb_float3"; + case IMAGE_DATA_TYPE_NANOVDB_FPN: + return "nanovdb_fpn"; + case IMAGE_DATA_TYPE_NANOVDB_FP16: + return "nanovdb_fp16"; case IMAGE_DATA_NUM_TYPES: assert(!"System enumerator type, should never be used"); return ""; @@ -378,7 +382,9 @@ void ImageManager::load_image_metadata(Image *img) metadata.detect_colorspace(); assert(features.has_nanovdb || (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT || - metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3)); + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 || + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FPN || + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FP16)); img->need_metadata = false; } @@ -796,7 +802,8 @@ void ImageManager::device_load_image(Device *device, Scene *scene, int slot, Pro } } #ifdef WITH_NANOVDB - else if (type == IMAGE_DATA_TYPE_NANOVDB_FLOAT || type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3) { + else if (type == IMAGE_DATA_TYPE_NANOVDB_FLOAT || type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3 || + type == IMAGE_DATA_TYPE_NANOVDB_FPN || type == IMAGE_DATA_TYPE_NANOVDB_FP16) { thread_scoped_lock device_lock(device_mutex); void *pixels = img->mem->alloc(img->metadata.byte_size, 0); diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp index 3f825afbe90..1b7f8f49696 100644 --- a/intern/cycles/scene/image_oiio.cpp +++ b/intern/cycles/scene/image_oiio.cpp @@ -199,6 +199,8 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata, break; case IMAGE_DATA_TYPE_NANOVDB_FLOAT: case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: + case IMAGE_DATA_TYPE_NANOVDB_FPN: + case IMAGE_DATA_TYPE_NANOVDB_FP16: case IMAGE_DATA_NUM_TYPES: break; } diff --git a/intern/cycles/scene/image_vdb.cpp b/intern/cycles/scene/image_vdb.cpp index b6f0911fa2c..d0b41a239df 100644 --- a/intern/cycles/scene/image_vdb.cpp +++ b/intern/cycles/scene/image_vdb.cpp @@ -44,14 +44,30 @@ struct ToDenseOp { # ifdef WITH_NANOVDB struct ToNanoOp { nanovdb::GridHandle<> nanogrid; + int precision; template<typename GridType, typename FloatGridType, typename FloatDataType, int channels> bool operator()(const openvdb::GridBase::ConstPtr &grid) { if constexpr (!std::is_same_v<GridType, openvdb::MaskGrid>) { try { - nanogrid = nanovdb::openToNanoVDB( - FloatGridType(*openvdb::gridConstPtrCast<GridType>(grid))); + FloatGridType floatgrid(*openvdb::gridConstPtrCast<GridType>(grid)); + if constexpr (std::is_same_v<FloatGridType, openvdb::FloatGrid>) { + if (precision == 0) { + nanogrid = nanovdb::openToNanoVDB<nanovdb::HostBuffer, + typename FloatGridType::TreeType, + nanovdb::FpN>(floatgrid); + return true; + } + else if (precision == 16) { + nanogrid = nanovdb::openToNanoVDB<nanovdb::HostBuffer, + typename FloatGridType::TreeType, + nanovdb::Fp16>(floatgrid); + return true; + } + } + + nanogrid = nanovdb::openToNanoVDB(floatgrid); } catch (const std::exception &e) { VLOG(1) << "Error converting OpenVDB to NanoVDB grid: " << e.what(); @@ -102,6 +118,7 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet openvdb::tools::pruneInactive(pruned_grid.tree()); nanogrid = nanovdb::openToNanoVDB(pruned_grid);*/ ToNanoOp op; + op.precision = precision; if (!openvdb::grid_type_operation(grid, op)) { return false; } @@ -124,7 +141,15 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet if (nanogrid) { metadata.byte_size = nanogrid.size(); if (metadata.channels == 1) { - metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT; + if (precision == 0) { + metadata.type = IMAGE_DATA_TYPE_NANOVDB_FPN; + } + else if (precision == 16) { + metadata.type = IMAGE_DATA_TYPE_NANOVDB_FP16; + } + else { + metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT; + } } else { metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT3; diff --git a/intern/cycles/scene/image_vdb.h b/intern/cycles/scene/image_vdb.h index a5fd51915ef..ea5f6b0b3d9 100644 --- a/intern/cycles/scene/image_vdb.h +++ b/intern/cycles/scene/image_vdb.h @@ -51,6 +51,7 @@ class VDBImageLoader : public ImageLoader { #endif #ifdef WITH_NANOVDB nanovdb::GridHandle<> nanogrid; + int precision = 0; #endif }; diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp index 8015be6393b..ddd89a16640 100644 --- a/intern/cycles/scene/object.cpp +++ b/intern/cycles/scene/object.cpp @@ -327,9 +327,11 @@ float Object::compute_volume_step_size() const /* Auto detect step size. */ float3 size = one_float3(); #ifdef WITH_NANOVDB - /* Dimensions were not applied to image transform with NanOVDB (see image_vdb.cpp) */ + /* Dimensions were not applied to image transform with NanoVDB (see image_vdb.cpp) */ if (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT && - metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 && + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FPN && + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FP16) #endif size /= make_float3(metadata.width, metadata.height, metadata.depth); diff --git a/intern/cycles/util/texture.h b/intern/cycles/util/texture.h index e8bb058a3c9..90e842933c2 100644 --- a/intern/cycles/util/texture.h +++ b/intern/cycles/util/texture.h @@ -37,6 +37,8 @@ typedef enum ImageDataType { IMAGE_DATA_TYPE_USHORT = 7, IMAGE_DATA_TYPE_NANOVDB_FLOAT = 8, IMAGE_DATA_TYPE_NANOVDB_FLOAT3 = 9, + IMAGE_DATA_TYPE_NANOVDB_FPN = 10, + IMAGE_DATA_TYPE_NANOVDB_FP16 = 11, IMAGE_DATA_NUM_TYPES } ImageDataType; diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py index 678972a677c..98855d4b516 100644 --- a/release/scripts/startup/bl_ui/properties_data_volume.py +++ b/release/scripts/startup/bl_ui/properties_data_volume.py @@ -115,6 +115,9 @@ class DATA_PT_volume_render(DataButtonsPanel, Panel): col = layout.column(align=True) col.prop(render, "clipping") + col = layout.column() + col.prop(render, "precision") + col = layout.column(align=False) col.prop(volume, "velocity_grid") diff --git a/source/blender/makesdna/DNA_volume_defaults.h b/source/blender/makesdna/DNA_volume_defaults.h index ee98f0ea4fd..1057fc75d34 100644 --- a/source/blender/makesdna/DNA_volume_defaults.h +++ b/source/blender/makesdna/DNA_volume_defaults.h @@ -23,6 +23,7 @@ #define _DNA_DEFAULT_VolumeRender \ { \ + .precision = VOLUME_PRECISION_HALF, \ .space = VOLUME_SPACE_OBJECT, \ .step_size = 0.0f, \ .clipping = 0.001f, \ diff --git a/source/blender/makesdna/DNA_volume_types.h b/source/blender/makesdna/DNA_volume_types.h index a2e558aa790..a25bfe0ebec 100644 --- a/source/blender/makesdna/DNA_volume_types.h +++ b/source/blender/makesdna/DNA_volume_types.h @@ -126,6 +126,13 @@ typedef enum VolumeWireframeDetail { VOLUME_WIREFRAME_FINE = 1, } VolumeWireframeDetail; +/** #VolumeRender.precision */ +typedef enum VolumeRenderPrecision { + VOLUME_PRECISION_HALF = 0, + VOLUME_PRECISION_FULL = 1, + VOLUME_PRECISION_VARIABLE = 2, +} VolumeRenderPrecision; + /** #VolumeRender.space */ typedef enum VolumeRenderSpace { VOLUME_SPACE_OBJECT = 0, diff --git a/source/blender/makesrna/intern/rna_volume.c b/source/blender/makesrna/intern/rna_volume.c index 12cb35b239d..0c32ed45dce 100644 --- a/source/blender/makesrna/intern/rna_volume.c +++ b/source/blender/makesrna/intern/rna_volume.c @@ -485,6 +485,21 @@ static void rna_def_volume_render(BlenderRNA *brna) RNA_def_struct_sdna(srna, "VolumeRender"); RNA_def_struct_path_func(srna, "rna_VolumeRender_path"); + static const EnumPropertyItem precision_items[] = { + {VOLUME_PRECISION_FULL, "FULL", 0, "Full", "Full float (Use 32 bit for all data)"}, + {VOLUME_PRECISION_HALF, "HALF", 0, "Half", "Half float (Use 16 bit for all data)"}, + {VOLUME_PRECISION_VARIABLE, "VARIABLE", 0, "Variable", "Use variable bit quantization"}, + {0, NULL, 0, NULL, NULL}, + }; + + prop = RNA_def_property(srna, "precision", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, precision_items); + RNA_def_property_ui_text(prop, + "Precision", + "Specify volume data precision. Lower values reduce memory consumption " + "at the cost of detail"); + RNA_def_property_update(prop, 0, "rna_Volume_update_display"); + static const EnumPropertyItem space_items[] = { {VOLUME_SPACE_OBJECT, "OBJECT", |