diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-02-10 03:57:57 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-02-10 03:57:57 +0300 |
commit | 7c1ddc7755c8af435fd58a5e3fc053862e0972f8 (patch) | |
tree | a0ab718b59467039819cd44b2c61f788f8977cd0 /intern/cycles/scene | |
parent | 4a5756bc35a4a0d84b04197a8239ef3a2ca01f30 (diff) | |
parent | 58761eb11a681abbde1809a01ab8dde75aa8f46e (diff) |
Merge branch 'master' into temp-abc-features
Diffstat (limited to 'intern/cycles/scene')
-rw-r--r-- | intern/cycles/scene/colorspace.cpp | 89 | ||||
-rw-r--r-- | intern/cycles/scene/colorspace.h | 6 | ||||
-rw-r--r-- | intern/cycles/scene/constant_fold.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/scene/geometry.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/scene/image.cpp | 16 | ||||
-rw-r--r-- | intern/cycles/scene/scene.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/scene/scene.h | 3 | ||||
-rw-r--r-- | intern/cycles/scene/shader_nodes.cpp | 73 | ||||
-rw-r--r-- | intern/cycles/scene/shader_nodes.h | 15 |
9 files changed, 173 insertions, 41 deletions
diff --git a/intern/cycles/scene/colorspace.cpp b/intern/cycles/scene/colorspace.cpp index c1a308fcbaa..f0b7eb724de 100644 --- a/intern/cycles/scene/colorspace.cpp +++ b/intern/cycles/scene/colorspace.cpp @@ -263,7 +263,9 @@ template<typename T> inline void cast_from_float4(T *data, float4 value) /* Slower versions for other all data types, which needs to convert to float and back. */ template<typename T, bool compress_as_srgb = false> -inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels, size_t num_pixels) +inline void processor_apply_pixels_rgba(const OCIO::Processor *processor, + T *pixels, + size_t num_pixels) { /* TODO: implement faster version for when we know the conversion * is a simple matrix transform between linear spaces. In that case @@ -310,25 +312,79 @@ inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels, } } } + +template<typename T, bool compress_as_srgb = false> +inline void processor_apply_pixels_grayscale(const OCIO::Processor *processor, + T *pixels, + size_t num_pixels) +{ + OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor(); + + /* Process large images in chunks to keep temporary memory requirement down. */ + const size_t chunk_size = std::min((size_t)(16 * 1024 * 1024), num_pixels); + vector<float> float_pixels(chunk_size * 3); + + for (size_t j = 0; j < num_pixels; j += chunk_size) { + size_t width = std::min(chunk_size, num_pixels - j); + + /* Convert to 3 channels, since that's the minimum required by OpenColorIO. */ + { + const T *pixel = pixels + j; + float *fpixel = float_pixels.data(); + for (size_t i = 0; i < width; i++, pixel++, fpixel += 3) { + const float f = util_image_cast_to_float<T>(*pixel); + fpixel[0] = f; + fpixel[1] = f; + fpixel[2] = f; + } + } + + OCIO::PackedImageDesc desc((float *)float_pixels.data(), width, 1, 3); + device_processor->apply(desc); + + { + T *pixel = pixels + j; + const float *fpixel = float_pixels.data(); + for (size_t i = 0; i < width; i++, pixel++, fpixel += 3) { + float f = average(make_float3(fpixel[0], fpixel[1], fpixel[2])); + if (compress_as_srgb) { + f = color_linear_to_srgb(f); + } + *pixel = util_image_cast_from_float<T>(f); + } + } + } +} + #endif template<typename T> -void ColorSpaceManager::to_scene_linear(ustring colorspace, - T *pixels, - size_t num_pixels, - bool compress_as_srgb) +void ColorSpaceManager::to_scene_linear( + ustring colorspace, T *pixels, size_t num_pixels, bool is_rgba, bool compress_as_srgb) { #ifdef WITH_OCIO const OCIO::Processor *processor = (const OCIO::Processor *)get_processor(colorspace); if (processor) { - if (compress_as_srgb) { - /* Compress output as sRGB. */ - processor_apply_pixels<T, true>(processor, pixels, num_pixels); + if (is_rgba) { + if (compress_as_srgb) { + /* Compress output as sRGB. */ + processor_apply_pixels_rgba<T, true>(processor, pixels, num_pixels); + } + else { + /* Write output as scene linear directly. */ + processor_apply_pixels_rgba<T>(processor, pixels, num_pixels); + } } else { - /* Write output as scene linear directly. */ - processor_apply_pixels<T>(processor, pixels, num_pixels); + if (compress_as_srgb) { + /* Compress output as sRGB. */ + processor_apply_pixels_grayscale<T, true>(processor, pixels, num_pixels); + } + else { + /* Write output as scene linear directly. */ + processor_apply_pixels_grayscale<T>(processor, pixels, num_pixels); + } } } #else @@ -348,6 +404,11 @@ void ColorSpaceManager::to_scene_linear(ColorSpaceProcessor *processor_, if (processor) { OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor(); + if (channels == 1) { + float3 rgb = make_float3(pixel[0], pixel[0], pixel[0]); + device_processor->applyRGB(&rgb.x); + pixel[0] = average(rgb); + } if (channels == 3) { device_processor->applyRGB(pixel); } @@ -390,9 +451,9 @@ void ColorSpaceManager::free_memory() } /* Template instantiations so we don't have to inline functions. */ -template void ColorSpaceManager::to_scene_linear(ustring, uchar *, size_t, bool); -template void ColorSpaceManager::to_scene_linear(ustring, ushort *, size_t, bool); -template void ColorSpaceManager::to_scene_linear(ustring, half *, size_t, bool); -template void ColorSpaceManager::to_scene_linear(ustring, float *, size_t, bool); +template void ColorSpaceManager::to_scene_linear(ustring, uchar *, size_t, bool, bool); +template void ColorSpaceManager::to_scene_linear(ustring, ushort *, size_t, bool, bool); +template void ColorSpaceManager::to_scene_linear(ustring, half *, size_t, bool, bool); +template void ColorSpaceManager::to_scene_linear(ustring, float *, size_t, bool, bool); CCL_NAMESPACE_END diff --git a/intern/cycles/scene/colorspace.h b/intern/cycles/scene/colorspace.h index 7f7bc604f07..f02c1231a44 100644 --- a/intern/cycles/scene/colorspace.h +++ b/intern/cycles/scene/colorspace.h @@ -43,10 +43,8 @@ class ColorSpaceManager { /* Convert pixels in the specified colorspace to scene linear color for * rendering. Must be a colorspace returned from detect_known_colorspace. */ template<typename T> - static void to_scene_linear(ustring colorspace, - T *pixels, - size_t num_pixels, - bool compress_as_srgb); + static void to_scene_linear( + ustring colorspace, T *pixels, size_t num_pixels, bool is_rgba, bool compress_as_srgb); /* Efficiently convert pixels to scene linear colorspace at render time, * for OSL where the image texture cache contains original pixels. The diff --git a/intern/cycles/scene/constant_fold.cpp b/intern/cycles/scene/constant_fold.cpp index a5fb68bf229..e9fb3426b70 100644 --- a/intern/cycles/scene/constant_fold.cpp +++ b/intern/cycles/scene/constant_fold.cpp @@ -441,9 +441,13 @@ void ConstantFolder::fold_mapping(NodeMappingType type) const if (is_zero(scale_in)) { make_zero(); } - else if ((is_zero(location_in) || type == NODE_MAPPING_TYPE_VECTOR || - type == NODE_MAPPING_TYPE_NORMAL) && - is_zero(rotation_in) && is_one(scale_in)) { + else if ( + /* Can't constant fold since we always need to normalize the output. */ + (type != NODE_MAPPING_TYPE_NORMAL) && + /* Check all use values are zero, note location is not used by vector and normal types. */ + (is_zero(location_in) || type == NODE_MAPPING_TYPE_VECTOR || + type == NODE_MAPPING_TYPE_NORMAL) && + is_zero(rotation_in) && is_one(scale_in)) { try_bypass_or_make_constant(vector_in); } } diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index 49d18d00dd7..90f1e1cb021 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -236,6 +236,7 @@ void Geometry::compute_bvh( BVHParams bparams; bparams.use_spatial_split = params->use_bvh_spatial_split; + bparams.use_compact_structure = params->use_bvh_compact_structure; bparams.bvh_layout = bvh_layout; bparams.use_unaligned_nodes = dscene->data.bvh.have_curves && params->use_bvh_unaligned_nodes; diff --git a/intern/cycles/scene/image.cpp b/intern/cycles/scene/image.cpp index 3595ca55a46..7aad46d253c 100644 --- a/intern/cycles/scene/image.cpp +++ b/intern/cycles/scene/image.cpp @@ -576,13 +576,13 @@ bool ImageManager::file_load_image(Image *img, int texture_limit) pixels[i * 4 + 3] = one; } } + } - if (img->metadata.colorspace != u_colorspace_raw && - img->metadata.colorspace != u_colorspace_srgb) { - /* Convert to scene linear. */ - ColorSpaceManager::to_scene_linear( - img->metadata.colorspace, pixels, num_pixels, img->metadata.compress_as_srgb); - } + if (img->metadata.colorspace != u_colorspace_raw && + img->metadata.colorspace != u_colorspace_srgb) { + /* Convert to scene linear. */ + ColorSpaceManager::to_scene_linear( + img->metadata.colorspace, pixels, num_pixels, is_rgba, img->metadata.compress_as_srgb); } /* Make sure we don't have buggy values. */ @@ -891,6 +891,10 @@ void ImageManager::device_free(Device *device) void ImageManager::collect_statistics(RenderStats *stats) { foreach (const Image *image, images) { + if (!image) { + /* Image may have been freed due to lack of users. */ + continue; + } stats->image.textures.add_entry( NamedSizeEntry(image->loader->name(), image->mem->memory_size())); } diff --git a/intern/cycles/scene/scene.cpp b/intern/cycles/scene/scene.cpp index 1963ebbbb19..b5b8eee24a7 100644 --- a/intern/cycles/scene/scene.cpp +++ b/intern/cycles/scene/scene.cpp @@ -570,7 +570,6 @@ static void log_kernel_features(const uint features) << "\n"; VLOG(2) << "Use Emission " << string_from_bool(features & KERNEL_FEATURE_NODE_EMISSION) << "\n"; VLOG(2) << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_NODE_VOLUME) << "\n"; - VLOG(2) << "Use Hair " << string_from_bool(features & KERNEL_FEATURE_NODE_HAIR) << "\n"; VLOG(2) << "Use Bump " << string_from_bool(features & KERNEL_FEATURE_NODE_BUMP) << "\n"; VLOG(2) << "Use Voronoi " << string_from_bool(features & KERNEL_FEATURE_NODE_VORONOI_EXTRA) << "\n"; diff --git a/intern/cycles/scene/scene.h b/intern/cycles/scene/scene.h index ec935b41be6..77268837070 100644 --- a/intern/cycles/scene/scene.h +++ b/intern/cycles/scene/scene.h @@ -160,6 +160,7 @@ class SceneParams { BVHType bvh_type; bool use_bvh_spatial_split; + bool use_bvh_compact_structure; bool use_bvh_unaligned_nodes; int num_bvh_time_steps; int hair_subdivisions; @@ -174,6 +175,7 @@ class SceneParams { bvh_layout = BVH_LAYOUT_BVH2; bvh_type = BVH_TYPE_DYNAMIC; use_bvh_spatial_split = false; + use_bvh_compact_structure = true; use_bvh_unaligned_nodes = true; num_bvh_time_steps = 0; hair_subdivisions = 3; @@ -187,6 +189,7 @@ class SceneParams { return !(shadingsystem == params.shadingsystem && bvh_layout == params.bvh_layout && bvh_type == params.bvh_type && use_bvh_spatial_split == params.use_bvh_spatial_split && + use_bvh_compact_structure == params.use_bvh_compact_structure && use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes && num_bvh_time_steps == params.num_bvh_time_steps && hair_subdivisions == params.hair_subdivisions && hair_shape == params.hair_shape && diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index e8316ad41b4..34675be8e80 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -32,6 +32,7 @@ #include "util/color.h" #include "util/foreach.h" #include "util/log.h" +#include "util/string.h" #include "util/transform.h" #include "kernel/tables.h" @@ -462,8 +463,12 @@ void ImageTextureNode::compile(OSLCompiler &compiler) const ustring known_colorspace = metadata.colorspace; if (handle.svm_slot() == -1) { + /* OIIO currently does not support <UVTILE> substitutions natively. Replace with a format they + * understand. */ + std::string osl_filename = filename.string(); + string_replace(osl_filename, "<UVTILE>", "<U>_<V>"); compiler.parameter_texture( - "filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace); + "filename", ustring(osl_filename), compress_as_srgb ? u_colorspace_raw : known_colorspace); } else { compiler.parameter_texture("filename", handle.svm_slot()); @@ -472,7 +477,8 @@ void ImageTextureNode::compile(OSLCompiler &compiler) const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) || alpha_type == IMAGE_ALPHA_CHANNEL_PACKED || alpha_type == IMAGE_ALPHA_IGNORE); - const bool is_tiled = (filename.find("<UDIM>") != string::npos); + const bool is_tiled = (filename.find("<UDIM>") != string::npos || + filename.find("<UVTILE>") != string::npos); compiler.parameter(this, "projection"); compiler.parameter(this, "projection_blend"); @@ -4388,9 +4394,6 @@ NODE_DEFINE(HairInfoNode) SOCKET_OUT_FLOAT(size, "Length"); SOCKET_OUT_FLOAT(thickness, "Thickness"); SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal"); -#if 0 /* Output for minimum hair width transparency - deactivated. */ - SOCKET_OUT_FLOAT(fade, "Fade"); -#endif SOCKET_OUT_FLOAT(index, "Random"); return type; @@ -4448,12 +4451,7 @@ void HairInfoNode::compile(SVMCompiler &compiler) if (!out->links.empty()) { compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out)); } -#if 0 - out = output("Fade"); - if(!out->links.empty()) { - compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out)); - } -#endif + out = output("Random"); if (!out->links.empty()) { int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM); @@ -4466,6 +4464,59 @@ void HairInfoNode::compile(OSLCompiler &compiler) compiler.add(this, "node_hair_info"); } +/* Point Info */ + +NODE_DEFINE(PointInfoNode) +{ + NodeType *type = NodeType::add("point_info", create, NodeType::SHADER); + + SOCKET_OUT_POINT(position, "Position"); + SOCKET_OUT_FLOAT(radius, "Radius"); + SOCKET_OUT_FLOAT(random, "Random"); + + return type; +} + +PointInfoNode::PointInfoNode() : ShaderNode(get_node_type()) +{ +} + +void PointInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) +{ + if (shader->has_surface_link()) { + if (!output("Random")->links.empty()) + attributes->add(ATTR_STD_POINT_RANDOM); + } + + ShaderNode::attributes(shader, attributes); +} + +void PointInfoNode::compile(SVMCompiler &compiler) +{ + ShaderOutput *out; + + out = output("Position"); + if (!out->links.empty()) { + compiler.add_node(NODE_POINT_INFO, NODE_INFO_POINT_POSITION, compiler.stack_assign(out)); + } + + out = output("Radius"); + if (!out->links.empty()) { + compiler.add_node(NODE_POINT_INFO, NODE_INFO_POINT_RADIUS, compiler.stack_assign(out)); + } + + out = output("Random"); + if (!out->links.empty()) { + int attr = compiler.attribute(ATTR_STD_POINT_RANDOM); + compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); + } +} + +void PointInfoNode::compile(OSLCompiler &compiler) +{ + compiler.add(this, "node_point_info"); +} + /* Volume Info */ NODE_DEFINE(VolumeInfoNode) diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h index 0faefd3041f..a8d5bdcf157 100644 --- a/intern/cycles/scene/shader_nodes.h +++ b/intern/cycles/scene/shader_nodes.h @@ -1005,9 +1005,20 @@ class HairInfoNode : public ShaderNode { { return true; } - virtual int get_feature() +}; + +class PointInfoNode : public ShaderNode { + public: + SHADER_NODE_CLASS(PointInfoNode) + + void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() + { + return true; + } + bool has_spatial_varying() { - return ShaderNode::get_feature() | KERNEL_FEATURE_NODE_HAIR; + return true; } }; |