Fix #139718: Always treat OSL cameras as inside a volume
Cycles automatically tries to decide if the camera ray should be a surface or a volume + surface camera ray by checking to see if the scene contains a volumetric material, and if it does, is it near where the camera rays are expected to spawn. This step is done during scene intialization. With the OSL camera, it is impratical to predict where the camera rays will spawn during scene intialization, which makes it impratical to predict if the OSL camera ray will spawn near a volumetric object. So this commit marks all OSL cameras as "inside a volume", leading to the spawning of volume + surface camera rays for OSL cameras while the scene contains a volumetric material. This leads to increased render times ranging between 1% - 5% in scenes that use a OSL camera, has a volumetric object in it, and the volumetric object is far away from the camera. Every other scene should see no performance impact. Testing was done on a AMD Ryzen 9 5950X and a NVIDIA GeForce RTX 4090. Pull Request: https://projects.blender.org/blender/blender/pulls/142036
This commit is contained in:
committed by
Brecht Van Lommel
parent
89f966df4d
commit
736559f320
@@ -549,28 +549,34 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen
|
||||
|
||||
KernelIntegrator *kintegrator = &dscene->data.integrator;
|
||||
if (kintegrator->use_volumes) {
|
||||
BoundBox viewplane_boundbox = viewplane_bounds_get();
|
||||
if (camera_type == CAMERA_CUSTOM) {
|
||||
kernel_camera.is_inside_volume = 1;
|
||||
LOG_INFO << "Considering custom camera to be inside volume.";
|
||||
}
|
||||
else {
|
||||
BoundBox viewplane_boundbox = viewplane_bounds_get();
|
||||
|
||||
/* Parallel object update, with grain size to avoid too much threading overhead
|
||||
* for individual objects. */
|
||||
static const int OBJECTS_PER_TASK = 32;
|
||||
parallel_for(blocked_range<size_t>(0, scene->objects.size(), OBJECTS_PER_TASK),
|
||||
[&](const blocked_range<size_t> &r) {
|
||||
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||
Object *object = scene->objects[i];
|
||||
if (object->get_geometry()->has_volume &&
|
||||
viewplane_boundbox.intersects(object->bounds)) {
|
||||
/* TODO(sergey): Consider adding more grained check. */
|
||||
LOG_INFO << "Detected camera inside volume.";
|
||||
kernel_camera.is_inside_volume = 1;
|
||||
parallel_for_cancel();
|
||||
break;
|
||||
/* Parallel object update, with grain size to avoid too much threading overhead
|
||||
* for individual objects. */
|
||||
static const int OBJECTS_PER_TASK = 32;
|
||||
parallel_for(blocked_range<size_t>(0, scene->objects.size(), OBJECTS_PER_TASK),
|
||||
[&](const blocked_range<size_t> &r) {
|
||||
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||
Object *object = scene->objects[i];
|
||||
if (object->get_geometry()->has_volume &&
|
||||
viewplane_boundbox.intersects(object->bounds)) {
|
||||
/* TODO(sergey): Consider adding more grained check. */
|
||||
LOG_INFO << "Detected camera inside volume.";
|
||||
kernel_camera.is_inside_volume = 1;
|
||||
parallel_for_cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (!kernel_camera.is_inside_volume) {
|
||||
LOG_INFO << "Camera is outside of the volume.";
|
||||
if (!kernel_camera.is_inside_volume) {
|
||||
LOG_INFO << "Camera is outside of the volume.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
tests/files/render/camera/cycles_renders/osl_camera_offset_in_volume.png
(Stored with Git LFS)
BIN
tests/files/render/camera/cycles_renders/osl_camera_offset_in_volume.png
(Stored with Git LFS)
Binary file not shown.
Reference in New Issue
Block a user