Files
test/intern/cycles/scene/volume.h
Weizhen Huang 2b0a1cae06 Cycles: Add an option to use ray marching for volume rendering
Null Scattering currently has performance and noise issues, and it will
take time to address them. For now add the previous Ray Marching back as
an option.

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/146317
2025-09-26 12:14:45 +02:00

108 lines
3.1 KiB
C++

/* SPDX-FileCopyrightText: 2020-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
#include "graph/node.h"
#include "scene/mesh.h"
#ifdef WITH_OPENVDB
# include <openvdb/openvdb.h>
#endif
CCL_NAMESPACE_BEGIN
class Object;
class Octree;
enum VolumeRenderingAlgorithm {
NULL_SCATTERING,
RAY_MARCHING,
NONE,
};
class Volume : public Mesh {
public:
NODE_DECLARE
Volume();
NODE_SOCKET_API(float, step_size)
NODE_SOCKET_API(bool, object_space)
NODE_SOCKET_API(float, velocity_scale)
/* Merge attributes for efficiency, call right after creating them. */
void merge_grids(const Scene *scene);
void clear(bool preserve_shaders = false) override;
};
class VolumeManager {
public:
VolumeManager();
~VolumeManager();
void device_update(Device *, DeviceScene *, const Scene *, Progress &);
void device_free(DeviceScene *);
/* Tag volume octree for update when scene changes. */
void tag_update();
void tag_update(const Shader *shader);
void tag_update(const Object *object, const uint32_t flag);
void tag_update(const Geometry *geometry);
void tag_update_indices();
/* Check whether the shader is a homogeneous volume. */
static bool is_homogeneous_volume(const Object *, const Shader *);
private:
/* Initialize octrees from the volumes in the scene. */
void initialize_octree(const Scene *, Progress &);
/* Build octrees based on the volume density. */
void build_octree(Device *, Progress &);
/* Update the object and shader index of octree root nodes. */
void update_root_indices(DeviceScene *, const Scene *) const;
/* Converting the octrees into an array for uploading to the kernel. */
void flatten_octree(DeviceScene *, const Scene *) const;
/* Count all the nodes of the octrees. */
void update_num_octree_nodes();
int num_octree_nodes() const;
int num_octree_roots() const;
/* When running Blender with `--log-level debug`, an octree visualization is written to
* `filename`, which is a Python script that can be run inside Blender. */
std::string visualize_octree(const char *filename) const;
/* Step size for ray marching. */
void update_step_size(const Scene *, DeviceScene *) const;
/* One octree per object per shader. */
std::map<std::pair<const Object *, const Shader *>, std::shared_ptr<Octree>> object_octrees_;
bool update_root_indices_ = false;
bool need_rebuild_;
bool update_visualization_ = false;
int num_octree_nodes_;
int num_octree_roots_;
VolumeRenderingAlgorithm last_algorithm = NONE;
#ifdef WITH_OPENVDB
/* Create SDF grid for mesh volumes, to determine whether a certain point is in the
* interior of the mesh. This reduces evaluation time needed for heterogeneous volume. */
openvdb::BoolGrid::ConstPtr mesh_to_sdf_grid(const Mesh *mesh,
const Shader *shader,
const float half_width);
openvdb::BoolGrid::ConstPtr get_vdb(const Geometry *, const Shader *) const;
std::map<std::pair<const Geometry *, const Shader *>, openvdb::BoolGrid::ConstPtr> vdb_map_;
#endif
};
CCL_NAMESPACE_END