Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/curves.cpp110
-rw-r--r--intern/cycles/render/curves.h62
-rw-r--r--intern/cycles/render/denoising.cpp6
-rw-r--r--intern/cycles/render/geometry.cpp41
-rw-r--r--intern/cycles/render/hair.cpp1
-rw-r--r--intern/cycles/render/hair.h1
-rw-r--r--intern/cycles/render/image.cpp1
-rw-r--r--intern/cycles/render/image.h2
-rw-r--r--intern/cycles/render/image_sky.cpp91
-rw-r--r--intern/cycles/render/image_sky.h49
-rw-r--r--intern/cycles/render/integrator.cpp1
-rw-r--r--intern/cycles/render/light.cpp140
-rw-r--r--intern/cycles/render/nodes.cpp199
-rw-r--r--intern/cycles/render/nodes.h9
-rw-r--r--intern/cycles/render/object.cpp82
-rw-r--r--intern/cycles/render/scene.cpp13
-rw-r--r--intern/cycles/render/scene.h12
-rw-r--r--intern/cycles/render/session.cpp46
-rw-r--r--intern/cycles/render/session.h14
-rw-r--r--intern/cycles/render/shader.cpp1
-rw-r--r--intern/cycles/render/svm.cpp3
22 files changed, 490 insertions, 396 deletions
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index 472b5a0c101..e37a0407976 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SRC
hair.cpp
image.cpp
image_oiio.cpp
+ image_sky.cpp
image_vdb.cpp
integrator.cpp
jitter.cpp
@@ -64,6 +65,7 @@ set(SRC_HEADERS
hair.h
image.h
image_oiio.h
+ image_sky.h
image_vdb.h
integrator.h
light.h
diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp
index 1907bb33d06..db48d8b6430 100644
--- a/intern/cycles/render/curves.cpp
+++ b/intern/cycles/render/curves.cpp
@@ -36,13 +36,12 @@ void curvebounds(float *lower, float *upper, float3 *p, int dim)
float *p2 = &p[2].x;
float *p3 = &p[3].x;
- float fc = 0.71f;
+ /* Catmull-Rom weights. */
float curve_coef[4];
curve_coef[0] = p1[dim];
- curve_coef[1] = -fc * p0[dim] + fc * p2[dim];
- curve_coef[2] = 2.0f * fc * p0[dim] + (fc - 3.0f) * p1[dim] + (3.0f - 2.0f * fc) * p2[dim] -
- fc * p3[dim];
- curve_coef[3] = -fc * p0[dim] + (2.0f - fc) * p1[dim] + (fc - 2.0f) * p2[dim] + fc * p3[dim];
+ curve_coef[1] = 0.5f * (-p0[dim] + p2[dim]);
+ curve_coef[2] = 0.5f * (2 * p0[dim] - 5 * p1[dim] + 4 * p2[dim] - p3[dim]);
+ curve_coef[3] = 0.5f * (-p0[dim] + 3 * p1[dim] - 3 * p2[dim] + p3[dim]);
float discroot = curve_coef[2] * curve_coef[2] - 3 * curve_coef[3] * curve_coef[1];
float ta = -1.0f;
@@ -77,105 +76,4 @@ void curvebounds(float *lower, float *upper, float3 *p, int dim)
*lower = min(*lower, min(exa, exb));
}
-/* Hair System Manager */
-
-CurveSystemManager::CurveSystemManager()
-{
- primitive = CURVE_LINE_SEGMENTS;
- curve_shape = CURVE_THICK;
- line_method = CURVE_CORRECTED;
- triangle_method = CURVE_CAMERA_TRIANGLES;
- resolution = 3;
- subdivisions = 3;
-
- use_curves = true;
- use_encasing = true;
- use_backfacing = false;
- use_tangent_normal_geometry = false;
-
- need_update = true;
- need_mesh_update = false;
-}
-
-CurveSystemManager::~CurveSystemManager()
-{
-}
-
-void CurveSystemManager::device_update(Device *device,
- DeviceScene *dscene,
- Scene * /*scene*/,
- Progress &progress)
-{
- if (!need_update)
- return;
-
- device_free(device, dscene);
-
- progress.set_status("Updating Hair settings", "Copying Hair settings to device");
-
- KernelCurves *kcurve = &dscene->data.curve;
-
- kcurve->curveflags = 0;
-
- if (use_curves) {
- if (primitive == CURVE_SEGMENTS || primitive == CURVE_RIBBONS)
- kcurve->curveflags |= CURVE_KN_INTERPOLATE;
- if (primitive == CURVE_RIBBONS)
- kcurve->curveflags |= CURVE_KN_RIBBONS;
-
- if (line_method == CURVE_ACCURATE)
- kcurve->curveflags |= CURVE_KN_ACCURATE;
- else if (line_method == CURVE_CORRECTED)
- kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION;
-
- if (use_tangent_normal_geometry)
- kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL;
- if (use_backfacing)
- kcurve->curveflags |= CURVE_KN_BACKFACING;
- if (use_encasing)
- kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER;
-
- kcurve->subdivisions = subdivisions;
- }
-
- if (progress.get_cancel())
- return;
-
- need_update = false;
-}
-
-void CurveSystemManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
-{
-}
-
-bool CurveSystemManager::modified(const CurveSystemManager &CurveSystemManager)
-{
- return !(
- curve_shape == CurveSystemManager.curve_shape &&
- line_method == CurveSystemManager.line_method && primitive == CurveSystemManager.primitive &&
- use_encasing == CurveSystemManager.use_encasing &&
- use_tangent_normal_geometry == CurveSystemManager.use_tangent_normal_geometry &&
- use_backfacing == CurveSystemManager.use_backfacing &&
- triangle_method == CurveSystemManager.triangle_method &&
- resolution == CurveSystemManager.resolution && use_curves == CurveSystemManager.use_curves &&
- subdivisions == CurveSystemManager.subdivisions);
-}
-
-bool CurveSystemManager::modified_mesh(const CurveSystemManager &CurveSystemManager)
-{
- return !(
- primitive == CurveSystemManager.primitive && curve_shape == CurveSystemManager.curve_shape &&
- triangle_method == CurveSystemManager.triangle_method &&
- resolution == CurveSystemManager.resolution && use_curves == CurveSystemManager.use_curves);
-}
-
-void CurveSystemManager::tag_update(Scene * /*scene*/)
-{
- need_update = true;
-}
-
-void CurveSystemManager::tag_update_mesh()
-{
- need_mesh_update = true;
-}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h
index ade289a402e..c52fcb9c882 100644
--- a/intern/cycles/render/curves.h
+++ b/intern/cycles/render/curves.h
@@ -20,6 +20,8 @@
#include "util/util_array.h"
#include "util/util_types.h"
+#include "render/hair.h"
+
CCL_NAMESPACE_BEGIN
class Device;
@@ -29,33 +31,6 @@ class Scene;
void curvebounds(float *lower, float *upper, float3 *p, int dim);
-typedef enum CurvePrimitiveType {
- CURVE_TRIANGLES = 0,
- CURVE_LINE_SEGMENTS = 1,
- CURVE_SEGMENTS = 2,
- CURVE_RIBBONS = 3,
-
- CURVE_NUM_PRIMITIVE_TYPES,
-} CurvePrimitiveType;
-
-typedef enum CurveShapeType {
- CURVE_RIBBON = 0,
- CURVE_THICK = 1,
-
- CURVE_NUM_SHAPE_TYPES,
-} CurveShapeType;
-
-typedef enum CurveTriangleMethod {
- CURVE_CAMERA_TRIANGLES,
- CURVE_TESSELATED_TRIANGLES
-} CurveTriangleMethod;
-
-typedef enum CurveLineMethod {
- CURVE_ACCURATE,
- CURVE_CORRECTED,
- CURVE_UNCORRECTED
-} CurveLineMethod;
-
class ParticleCurveData {
public:
@@ -75,43 +50,12 @@ class ParticleCurveData {
array<int> curve_keynum;
array<float> curve_length;
array<float2> curve_uv;
- array<float3> curve_vcol;
+ array<float4> curve_vcol;
array<float3> curvekey_co;
array<float> curvekey_time;
};
-/* HairSystem Manager */
-
-class CurveSystemManager {
- public:
- CurvePrimitiveType primitive;
- CurveShapeType curve_shape;
- CurveLineMethod line_method;
- CurveTriangleMethod triangle_method;
- int resolution;
- int subdivisions;
-
- bool use_curves;
- bool use_encasing;
- bool use_backfacing;
- bool use_tangent_normal_geometry;
-
- bool need_update;
- bool need_mesh_update;
-
- CurveSystemManager();
- ~CurveSystemManager();
-
- void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
- void device_free(Device *device, DeviceScene *dscene);
- bool modified(const CurveSystemManager &CurveSystemManager);
- bool modified_mesh(const CurveSystemManager &CurveSystemManager);
-
- void tag_update(Scene *scene);
- void tag_update_mesh();
-};
-
CCL_NAMESPACE_END
#endif /* __CURVES_H__ */
diff --git a/intern/cycles/render/denoising.cpp b/intern/cycles/render/denoising.cpp
index 4d819d1119e..4055bc4773b 100644
--- a/intern/cycles/render/denoising.cpp
+++ b/intern/cycles/render/denoising.cpp
@@ -21,6 +21,7 @@
#include "util/util_foreach.h"
#include "util/util_map.h"
#include "util/util_system.h"
+#include "util/util_task.h"
#include "util/util_time.h"
#include <OpenImageIO/filesystem.h>
@@ -377,8 +378,9 @@ void DenoiseTask::create_task(DeviceTask &task)
/* Denoising parameters. */
task.denoising = denoiser->params;
- task.denoising_do_filter = true;
- task.denoising_write_passes = false;
+ task.denoising.type = DENOISER_NLM;
+ task.denoising.use = true;
+ task.denoising.store_passes = false;
task.denoising_from_render = false;
task.denoising_frames.resize(neighbor_frames.size());
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index d46ed430c4f..3d1b6e1d865 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -16,10 +16,9 @@
#include "bvh/bvh.h"
#include "bvh/bvh_build.h"
+#include "bvh/bvh_embree.h"
-#ifdef WITH_EMBREE
-# include "bvh/bvh_embree.h"
-#endif
+#include "device/device.h"
#include "render/attribute.h"
#include "render/camera.h"
@@ -212,8 +211,7 @@ void Geometry::compute_bvh(
bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
bparams.num_motion_curve_steps = params->num_bvh_time_steps;
bparams.bvh_type = params->bvh_type;
- bparams.curve_flags = dscene->data.curve.curveflags;
- bparams.curve_subdivisions = dscene->data.curve.subdivisions;
+ bparams.curve_subdivisions = params->curve_subdivisions();
delete bvh;
bvh = BVH::create(bparams, geometry, objects);
@@ -1027,28 +1025,18 @@ void GeometryManager::device_update_bvh(Device *device,
bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps;
bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps;
bparams.bvh_type = scene->params.bvh_type;
- bparams.curve_flags = dscene->data.curve.curveflags;
- bparams.curve_subdivisions = dscene->data.curve.subdivisions;
+ bparams.curve_subdivisions = scene->params.curve_subdivisions();
VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
-#ifdef WITH_EMBREE
- if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
- if (dscene->data.bvh.scene) {
- BVHEmbree::destroy(dscene->data.bvh.scene);
- }
- }
-#endif
-
BVH *bvh = BVH::create(bparams, scene->geometry, scene->objects);
bvh->build(progress, &device->stats);
if (progress.get_cancel()) {
#ifdef WITH_EMBREE
- if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
- if (dscene->data.bvh.scene) {
- BVHEmbree::destroy(dscene->data.bvh.scene);
- }
+ if (dscene->data.bvh.scene) {
+ BVHEmbree::destroy(dscene->data.bvh.scene);
+ dscene->data.bvh.scene = NULL;
}
#endif
delete bvh;
@@ -1104,6 +1092,7 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->data.bvh.root = pack.root_index;
dscene->data.bvh.bvh_layout = bparams.bvh_layout;
dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
+ dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
bvh->copy_to_device(progress, dscene);
@@ -1146,6 +1135,12 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
create_volume_mesh(mesh, progress);
}
}
+
+ if (geom->type == Geometry::HAIR) {
+ /* Set curve shape, still a global scene setting for now. */
+ Hair *hair = static_cast<Hair *>(geom);
+ hair->curve_shape = scene->params.hair_shape;
+ }
}
need_flags_update = false;
@@ -1413,6 +1408,14 @@ void GeometryManager::device_update(Device *device,
void GeometryManager::device_free(Device *device, DeviceScene *dscene)
{
+#ifdef WITH_EMBREE
+ if (dscene->data.bvh.scene) {
+ if (dscene->data.bvh.bvh_layout == BVH_LAYOUT_EMBREE)
+ BVHEmbree::destroy(dscene->data.bvh.scene);
+ dscene->data.bvh.scene = NULL;
+ }
+#endif
+
dscene->bvh_nodes.free();
dscene->bvh_leaf_nodes.free();
dscene->object_node.free();
diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp
index 3daa4cc1e35..816c15cf4ef 100644
--- a/intern/cycles/render/hair.cpp
+++ b/intern/cycles/render/hair.cpp
@@ -294,6 +294,7 @@ NODE_DEFINE(Hair)
Hair::Hair() : Geometry(node_type, Geometry::HAIR)
{
curvekey_offset = 0;
+ curve_shape = CURVE_RIBBON;
}
Hair::~Hair()
diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h
index 79f77a78753..39d6a34d799 100644
--- a/intern/cycles/render/hair.h
+++ b/intern/cycles/render/hair.h
@@ -96,6 +96,7 @@ class Hair : public Geometry {
/* BVH */
size_t curvekey_offset;
+ CurveShapeType curve_shape;
/* Constructor/Destructor */
Hair();
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 75050b66bf2..8d187814d64 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -27,6 +27,7 @@
#include "util/util_logging.h"
#include "util/util_path.h"
#include "util/util_progress.h"
+#include "util/util_task.h"
#include "util/util_texture.h"
#include "util/util_unique_ptr.h"
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 2000582ce70..fffe7c5152a 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -17,7 +17,6 @@
#ifndef __IMAGE_H__
#define __IMAGE_H__
-#include "device/device.h"
#include "device/device_memory.h"
#include "render/colorspace.h"
@@ -31,6 +30,7 @@
CCL_NAMESPACE_BEGIN
class Device;
+class DeviceInfo;
class ImageHandle;
class ImageKey;
class ImageMetaData;
diff --git a/intern/cycles/render/image_sky.cpp b/intern/cycles/render/image_sky.cpp
new file mode 100644
index 00000000000..442e1d7941f
--- /dev/null
+++ b/intern/cycles/render/image_sky.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "render/image_sky.h"
+
+#include "util/util_image.h"
+#include "util/util_logging.h"
+#include "util/util_path.h"
+#include "util/util_sky_model.h"
+#include "util/util_task.h"
+
+CCL_NAMESPACE_BEGIN
+
+SkyLoader::SkyLoader(
+ float sun_elevation, int altitude, float air_density, float dust_density, float ozone_density)
+ : sun_elevation(sun_elevation),
+ altitude(altitude),
+ air_density(air_density),
+ dust_density(dust_density),
+ ozone_density(ozone_density)
+{
+}
+
+SkyLoader::~SkyLoader(){};
+
+bool SkyLoader::load_metadata(ImageMetaData &metadata)
+{
+ metadata.width = 512;
+ metadata.height = 128;
+ metadata.channels = 3;
+ metadata.depth = 1;
+ metadata.type = IMAGE_DATA_TYPE_FLOAT4;
+ metadata.compress_as_srgb = false;
+ return true;
+}
+
+bool SkyLoader::load_pixels(const ImageMetaData &metadata,
+ void *pixels,
+ const size_t /*pixels_size*/,
+ const bool /*associate_alpha*/)
+{
+ /* definitions */
+ int width = metadata.width;
+ int height = metadata.height;
+ float *pixel_data = (float *)pixels;
+ float altitude_f = (float)altitude;
+
+ /* precompute sky texture */
+ const int rows_per_task = divide_up(1024, width);
+ parallel_for(blocked_range<size_t>(0, height, rows_per_task),
+ [&](const blocked_range<size_t> &r) {
+ nishita_skymodel_precompute_texture(pixel_data,
+ metadata.channels,
+ r.begin(),
+ r.end(),
+ width,
+ height,
+ sun_elevation,
+ altitude_f,
+ air_density,
+ dust_density,
+ ozone_density);
+ });
+
+ return true;
+}
+
+string SkyLoader::name() const
+{
+ return "sky_nishita";
+}
+
+bool SkyLoader::equals(const ImageLoader & /*other*/) const
+{
+ return false;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image_sky.h b/intern/cycles/render/image_sky.h
new file mode 100644
index 00000000000..cf4a3e8942c
--- /dev/null
+++ b/intern/cycles/render/image_sky.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "render/image.h"
+
+CCL_NAMESPACE_BEGIN
+
+class SkyLoader : public ImageLoader {
+ private:
+ float sun_elevation;
+ int altitude;
+ float air_density;
+ float dust_density;
+ float ozone_density;
+
+ public:
+ SkyLoader(float sun_elevation,
+ int altitude,
+ float air_density,
+ float dust_density,
+ float ozone_density);
+ ~SkyLoader();
+
+ bool load_metadata(ImageMetaData &metadata) override;
+
+ bool load_pixels(const ImageMetaData &metadata,
+ void *pixels,
+ const size_t /*pixels_size*/,
+ const bool /*associate_alpha*/) override;
+
+ string name() const override;
+
+ bool equals(const ImageLoader & /*other*/) const override;
+};
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index d4beb06e57b..eff416efa2b 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -29,6 +29,7 @@
#include "util/util_foreach.h"
#include "util/util_hash.h"
#include "util/util_logging.h"
+#include "util/util_task.h"
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index cb7474017fa..c0615c6217b 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -31,6 +31,7 @@
#include "util/util_logging.h"
#include "util/util_path.h"
#include "util/util_progress.h"
+#include "util/util_task.h"
CCL_NAMESPACE_BEGIN
@@ -450,6 +451,7 @@ void LightManager::device_update_distribution(Device *,
/* update device */
KernelIntegrator *kintegrator = &dscene->data.integrator;
+ KernelBackground *kbackground = &dscene->data.background;
KernelFilm *kfilm = &dscene->data.film;
kintegrator->use_direct_light = (totarea > 0.0f);
@@ -493,15 +495,18 @@ void LightManager::device_update_distribution(Device *,
/* Portals */
if (num_portals > 0) {
- kintegrator->portal_offset = light_index;
- kintegrator->num_portals = num_portals;
- kintegrator->portal_pdf = background_mis ? 0.5f : 1.0f;
+ kbackground->portal_offset = light_index;
+ kbackground->num_portals = num_portals;
+ kbackground->portal_weight = 1.0f;
}
else {
- kintegrator->num_portals = 0;
- kintegrator->portal_offset = 0;
- kintegrator->portal_pdf = 0.0f;
+ kbackground->num_portals = 0;
+ kbackground->portal_offset = 0;
+ kbackground->portal_weight = 0.0f;
}
+
+ /* Map */
+ kbackground->map_weight = background_mis ? 1.0f : 0.0f;
}
else {
dscene->light_distribution.free();
@@ -511,9 +516,12 @@ void LightManager::device_update_distribution(Device *,
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
kintegrator->use_lamp_mis = false;
- kintegrator->num_portals = 0;
- kintegrator->portal_offset = 0;
- kintegrator->portal_pdf = 0.0f;
+
+ kbackground->num_portals = 0;
+ kbackground->portal_offset = 0;
+ kbackground->portal_weight = 0.0f;
+ kbackground->sun_weight = 0.0f;
+ kbackground->map_weight = 0.0f;
kfilm->pass_shadow_scale = 1.0f;
}
@@ -562,7 +570,7 @@ void LightManager::device_update_background(Device *device,
Scene *scene,
Progress &progress)
{
- KernelIntegrator *kintegrator = &dscene->data.integrator;
+ KernelBackground *kbackground = &dscene->data.background;
Light *background_light = NULL;
/* find background light */
@@ -575,31 +583,79 @@ void LightManager::device_update_background(Device *device,
/* no background light found, signal renderer to skip sampling */
if (!background_light || !background_light->is_enabled) {
- kintegrator->pdf_background_res_x = 0;
- kintegrator->pdf_background_res_y = 0;
+ kbackground->map_res_x = 0;
+ kbackground->map_res_y = 0;
+ kbackground->map_weight = 0.0f;
+ kbackground->sun_weight = 0.0f;
+ kbackground->use_mis = (kbackground->portal_weight > 0.0f);
return;
}
progress.set_status("Updating Lights", "Importance map");
- assert(kintegrator->use_direct_light);
+ assert(dscene->data.integrator.use_direct_light);
+
+ int2 environment_res = make_int2(0, 0);
+ Shader *shader = scene->background->get_shader(scene);
+ int num_suns = 0;
+ foreach (ShaderNode *node, shader->graph->nodes) {
+ if (node->type == EnvironmentTextureNode::node_type) {
+ EnvironmentTextureNode *env = (EnvironmentTextureNode *)node;
+ ImageMetaData metadata;
+ if (!env->handle.empty()) {
+ ImageMetaData metadata = env->handle.metadata();
+ environment_res.x = max(environment_res.x, metadata.width);
+ environment_res.y = max(environment_res.y, metadata.height);
+ }
+ }
+ if (node->type == SkyTextureNode::node_type) {
+ SkyTextureNode *sky = (SkyTextureNode *)node;
+ if (sky->type == NODE_SKY_NISHITA && sky->sun_disc) {
+ /* Ensure that the input coordinates aren't transformed before they reach the node.
+ * If that is the case, the logic used for sampling the sun's location does not work
+ * and we have to fall back to map-based sampling. */
+ const ShaderInput *vec_in = sky->input("Vector");
+ if (vec_in && vec_in->link && vec_in->link->parent) {
+ ShaderNode *vec_src = vec_in->link->parent;
+ if ((vec_src->type != TextureCoordinateNode::node_type) ||
+ (vec_in->link != vec_src->output("Generated"))) {
+ environment_res.x = max(environment_res.x, 4096);
+ environment_res.y = max(environment_res.y, 2048);
+ continue;
+ }
+ }
+
+ float latitude = sky->sun_elevation;
+ float longitude = M_2PI_F - sky->sun_rotation + M_PI_2_F;
+ float half_angle = sky->sun_size * 0.5f;
+ kbackground->sun = make_float4(cosf(latitude) * cosf(longitude),
+ cosf(latitude) * sinf(longitude),
+ sinf(latitude),
+ half_angle);
+ kbackground->sun_weight = 4.0f;
+ environment_res.x = max(environment_res.x, 512);
+ environment_res.y = max(environment_res.y, 256);
+ num_suns++;
+ }
+ }
+ }
+
+ /* If there's more than one sun, fall back to map sampling instead. */
+ if (num_suns != 1) {
+ kbackground->sun_weight = 0.0f;
+ environment_res.x = max(environment_res.x, 4096);
+ environment_res.y = max(environment_res.y, 2048);
+ }
+
+ /* Enable MIS for background sampling if any strategy is active. */
+ kbackground->use_mis = (kbackground->portal_weight + kbackground->map_weight +
+ kbackground->sun_weight) > 0.0f;
/* get the resolution from the light's size (we stuff it in there) */
int2 res = make_int2(background_light->map_resolution, background_light->map_resolution / 2);
/* If the resolution isn't set manually, try to find an environment texture. */
if (res.x == 0) {
- Shader *shader = scene->background->get_shader(scene);
- foreach (ShaderNode *node, shader->graph->nodes) {
- if (node->type == EnvironmentTextureNode::node_type) {
- EnvironmentTextureNode *env = (EnvironmentTextureNode *)node;
- ImageMetaData metadata;
- if (!env->handle.empty()) {
- ImageMetaData metadata = env->handle.metadata();
- res.x = max(res.x, metadata.width);
- res.y = max(res.y, metadata.height);
- }
- }
- }
+ res = environment_res;
if (res.x > 0 && res.y > 0) {
VLOG(2) << "Automatically set World MIS resolution to " << res.x << " by " << res.y << "\n";
}
@@ -609,8 +665,8 @@ void LightManager::device_update_background(Device *device,
res = make_int2(1024, 512);
VLOG(2) << "Setting World MIS resolution to default\n";
}
- kintegrator->pdf_background_res_x = res.x;
- kintegrator->pdf_background_res_y = res.y;
+ kbackground->map_res_x = res.x;
+ kbackground->map_res_y = res.y;
vector<float3> pixels;
shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
@@ -624,29 +680,13 @@ void LightManager::device_update_background(Device *device,
float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_width * res.y);
double time_start = time_dt();
- if (max(res.x, res.y) < 512) {
- /* Small enough resolution, faster to do single-threaded. */
- background_cdf(0, res.y, res.x, res.y, &pixels, cond_cdf);
- }
- else {
- /* Threaded evaluation for large resolution. */
- const int num_blocks = TaskScheduler::num_threads();
- const int chunk_size = res.y / num_blocks;
- int start_row = 0;
- TaskPool pool;
- for (int i = 0; i < num_blocks; ++i) {
- const int current_chunk_size = (i != num_blocks - 1) ? chunk_size : (res.y - i * chunk_size);
- pool.push(function_bind(&background_cdf,
- start_row,
- start_row + current_chunk_size,
- res.x,
- res.y,
- &pixels,
- cond_cdf));
- start_row += current_chunk_size;
- }
- pool.wait_work();
- }
+
+ /* Create CDF in parallel. */
+ const int rows_per_task = divide_up(10240, res.x);
+ parallel_for(blocked_range<size_t>(0, res.y, rows_per_task),
+ [&](const blocked_range<size_t> &r) {
+ background_cdf(r.begin(), r.end(), res.x, res.y, &pixels, cond_cdf);
+ });
/* marginal CDFs (column, V direction, sum of rows) */
marg_cdf[0].x = cond_cdf[res.x].x;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index cdcaeb246dd..ab392839e52 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -19,6 +19,7 @@
#include "render/constant_fold.h"
#include "render/film.h"
#include "render/image.h"
+#include "render/image_sky.h"
#include "render/integrator.h"
#include "render/light.h"
#include "render/mesh.h"
@@ -630,7 +631,7 @@ typedef struct SunSky {
/* Parameter */
float radiance_x, radiance_y, radiance_z;
- float config_x[9], config_y[9], config_z[9];
+ float config_x[9], config_y[9], config_z[9], nishita_data[9];
} SunSky;
/* Preetham model */
@@ -640,7 +641,7 @@ static float sky_perez_function(float lam[6], float theta, float gamma)
(1.0f + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma));
}
-static void sky_texture_precompute_old(SunSky *sunsky, float3 dir, float turbidity)
+static void sky_texture_precompute_preetham(SunSky *sunsky, float3 dir, float turbidity)
{
/*
* We re-use the SunSky struct of the new model, to avoid extra variables
@@ -703,10 +704,10 @@ static void sky_texture_precompute_old(SunSky *sunsky, float3 dir, float turbidi
}
/* Hosek / Wilkie */
-static void sky_texture_precompute_new(SunSky *sunsky,
- float3 dir,
- float turbidity,
- float ground_albedo)
+static void sky_texture_precompute_hosek(SunSky *sunsky,
+ float3 dir,
+ float turbidity,
+ float ground_albedo)
{
/* Calculate Sun Direction and save coordinates */
float2 spherical = sky_spherical_coordinates(dir);
@@ -743,6 +744,34 @@ static void sky_texture_precompute_new(SunSky *sunsky,
arhosekskymodelstate_free(sky_state);
}
+/* Nishita improved */
+static void sky_texture_precompute_nishita(SunSky *sunsky,
+ bool sun_disc,
+ float sun_size,
+ float sun_elevation,
+ float sun_rotation,
+ int altitude,
+ float air_density,
+ float dust_density)
+{
+ /* sample 2 sun pixels */
+ float pixel_bottom[3];
+ float pixel_top[3];
+ float altitude_f = (float)altitude;
+ nishita_skymodel_precompute_sun(
+ sun_elevation, sun_size, altitude_f, air_density, dust_density, pixel_bottom, pixel_top);
+ /* send data to svm_sky */
+ sunsky->nishita_data[0] = pixel_bottom[0];
+ sunsky->nishita_data[1] = pixel_bottom[1];
+ sunsky->nishita_data[2] = pixel_bottom[2];
+ sunsky->nishita_data[3] = pixel_top[0];
+ sunsky->nishita_data[4] = pixel_top[1];
+ sunsky->nishita_data[5] = pixel_top[2];
+ sunsky->nishita_data[6] = sun_elevation;
+ sunsky->nishita_data[7] = M_2PI_F - sun_rotation;
+ sunsky->nishita_data[8] = sun_disc ? sun_size : 0.0f;
+}
+
NODE_DEFINE(SkyTextureNode)
{
NodeType *type = NodeType::add("sky_texture", create, NodeType::SHADER);
@@ -750,13 +779,22 @@ NODE_DEFINE(SkyTextureNode)
TEXTURE_MAPPING_DEFINE(SkyTextureNode);
static NodeEnum type_enum;
- type_enum.insert("preetham", NODE_SKY_OLD);
- type_enum.insert("hosek_wilkie", NODE_SKY_NEW);
- SOCKET_ENUM(type, "Type", type_enum, NODE_SKY_NEW);
+ type_enum.insert("preetham", NODE_SKY_PREETHAM);
+ type_enum.insert("hosek_wilkie", NODE_SKY_HOSEK);
+ type_enum.insert("nishita_improved", NODE_SKY_NISHITA);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_SKY_NISHITA);
SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f));
SOCKET_FLOAT(turbidity, "Turbidity", 2.2f);
SOCKET_FLOAT(ground_albedo, "Ground Albedo", 0.3f);
+ SOCKET_BOOLEAN(sun_disc, "Sun Disc", true);
+ SOCKET_FLOAT(sun_size, "Sun Size", 0.009512f);
+ SOCKET_FLOAT(sun_elevation, "Sun Elevation", M_PI_2_F);
+ SOCKET_FLOAT(sun_rotation, "Sun Rotation", 0.0f);
+ SOCKET_INT(altitude, "Altitude", 0);
+ SOCKET_FLOAT(air_density, "Air", 1.0f);
+ SOCKET_FLOAT(dust_density, "Dust", 1.0f);
+ SOCKET_FLOAT(ozone_density, "Ozone", 1.0f);
SOCKET_IN_POINT(
vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
@@ -776,10 +814,32 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
ShaderOutput *color_out = output("Color");
SunSky sunsky;
- if (type == NODE_SKY_OLD)
- sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
- else if (type == NODE_SKY_NEW)
- sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
+ if (type == NODE_SKY_PREETHAM)
+ sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
+ else if (type == NODE_SKY_HOSEK)
+ sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
+ else if (type == NODE_SKY_NISHITA) {
+ sky_texture_precompute_nishita(&sunsky,
+ sun_disc,
+ sun_size,
+ sun_elevation,
+ sun_rotation,
+ altitude,
+ air_density,
+ dust_density);
+ /* precomputed texture image parameters */
+ ImageManager *image_manager = compiler.scene->image_manager;
+ ImageParams impar;
+ impar.interpolation = INTERPOLATION_LINEAR;
+ impar.extension = EXTENSION_EXTEND;
+
+ /* precompute sky texture */
+ if (handle.empty()) {
+ SkyLoader *loader = new SkyLoader(
+ sun_elevation, altitude, air_density, dust_density, ozone_density);
+ handle = image_manager->add_image(loader, impar);
+ }
+ }
else
assert(false);
@@ -787,38 +847,52 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
compiler.stack_assign(color_out);
compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), type);
- compiler.add_node(__float_as_uint(sunsky.phi),
- __float_as_uint(sunsky.theta),
- __float_as_uint(sunsky.radiance_x),
- __float_as_uint(sunsky.radiance_y));
- compiler.add_node(__float_as_uint(sunsky.radiance_z),
- __float_as_uint(sunsky.config_x[0]),
- __float_as_uint(sunsky.config_x[1]),
- __float_as_uint(sunsky.config_x[2]));
- compiler.add_node(__float_as_uint(sunsky.config_x[3]),
- __float_as_uint(sunsky.config_x[4]),
- __float_as_uint(sunsky.config_x[5]),
- __float_as_uint(sunsky.config_x[6]));
- compiler.add_node(__float_as_uint(sunsky.config_x[7]),
- __float_as_uint(sunsky.config_x[8]),
- __float_as_uint(sunsky.config_y[0]),
- __float_as_uint(sunsky.config_y[1]));
- compiler.add_node(__float_as_uint(sunsky.config_y[2]),
- __float_as_uint(sunsky.config_y[3]),
- __float_as_uint(sunsky.config_y[4]),
- __float_as_uint(sunsky.config_y[5]));
- compiler.add_node(__float_as_uint(sunsky.config_y[6]),
- __float_as_uint(sunsky.config_y[7]),
- __float_as_uint(sunsky.config_y[8]),
- __float_as_uint(sunsky.config_z[0]));
- compiler.add_node(__float_as_uint(sunsky.config_z[1]),
- __float_as_uint(sunsky.config_z[2]),
- __float_as_uint(sunsky.config_z[3]),
- __float_as_uint(sunsky.config_z[4]));
- compiler.add_node(__float_as_uint(sunsky.config_z[5]),
- __float_as_uint(sunsky.config_z[6]),
- __float_as_uint(sunsky.config_z[7]),
- __float_as_uint(sunsky.config_z[8]));
+ /* nishita doesn't need this data */
+ if (type != NODE_SKY_NISHITA) {
+ compiler.add_node(__float_as_uint(sunsky.phi),
+ __float_as_uint(sunsky.theta),
+ __float_as_uint(sunsky.radiance_x),
+ __float_as_uint(sunsky.radiance_y));
+ compiler.add_node(__float_as_uint(sunsky.radiance_z),
+ __float_as_uint(sunsky.config_x[0]),
+ __float_as_uint(sunsky.config_x[1]),
+ __float_as_uint(sunsky.config_x[2]));
+ compiler.add_node(__float_as_uint(sunsky.config_x[3]),
+ __float_as_uint(sunsky.config_x[4]),
+ __float_as_uint(sunsky.config_x[5]),
+ __float_as_uint(sunsky.config_x[6]));
+ compiler.add_node(__float_as_uint(sunsky.config_x[7]),
+ __float_as_uint(sunsky.config_x[8]),
+ __float_as_uint(sunsky.config_y[0]),
+ __float_as_uint(sunsky.config_y[1]));
+ compiler.add_node(__float_as_uint(sunsky.config_y[2]),
+ __float_as_uint(sunsky.config_y[3]),
+ __float_as_uint(sunsky.config_y[4]),
+ __float_as_uint(sunsky.config_y[5]));
+ compiler.add_node(__float_as_uint(sunsky.config_y[6]),
+ __float_as_uint(sunsky.config_y[7]),
+ __float_as_uint(sunsky.config_y[8]),
+ __float_as_uint(sunsky.config_z[0]));
+ compiler.add_node(__float_as_uint(sunsky.config_z[1]),
+ __float_as_uint(sunsky.config_z[2]),
+ __float_as_uint(sunsky.config_z[3]),
+ __float_as_uint(sunsky.config_z[4]));
+ compiler.add_node(__float_as_uint(sunsky.config_z[5]),
+ __float_as_uint(sunsky.config_z[6]),
+ __float_as_uint(sunsky.config_z[7]),
+ __float_as_uint(sunsky.config_z[8]));
+ }
+ else {
+ compiler.add_node(__float_as_uint(sunsky.nishita_data[0]),
+ __float_as_uint(sunsky.nishita_data[1]),
+ __float_as_uint(sunsky.nishita_data[2]),
+ __float_as_uint(sunsky.nishita_data[3]));
+ compiler.add_node(__float_as_uint(sunsky.nishita_data[4]),
+ __float_as_uint(sunsky.nishita_data[5]),
+ __float_as_uint(sunsky.nishita_data[6]),
+ __float_as_uint(sunsky.nishita_data[7]));
+ compiler.add_node(__float_as_uint(sunsky.nishita_data[8]), handle.svm_slot(), 0, 0);
+ }
tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
@@ -828,10 +902,32 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
tex_mapping.compile(compiler);
SunSky sunsky;
- if (type == NODE_SKY_OLD)
- sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
- else if (type == NODE_SKY_NEW)
- sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
+ if (type == NODE_SKY_PREETHAM)
+ sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
+ else if (type == NODE_SKY_HOSEK)
+ sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
+ else if (type == NODE_SKY_NISHITA) {
+ sky_texture_precompute_nishita(&sunsky,
+ sun_disc,
+ sun_size,
+ sun_elevation,
+ sun_rotation,
+ altitude,
+ air_density,
+ dust_density);
+ /* precomputed texture image parameters */
+ ImageManager *image_manager = compiler.scene->image_manager;
+ ImageParams impar;
+ impar.interpolation = INTERPOLATION_LINEAR;
+ impar.extension = EXTENSION_EXTEND;
+
+ /* precompute sky texture */
+ if (handle.empty()) {
+ SkyLoader *loader = new SkyLoader(
+ sun_elevation, altitude, air_density, dust_density, ozone_density);
+ handle = image_manager->add_image(loader, impar);
+ }
+ }
else
assert(false);
@@ -843,6 +939,11 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
compiler.parameter_array("config_x", sunsky.config_x, 9);
compiler.parameter_array("config_y", sunsky.config_y, 9);
compiler.parameter_array("config_z", sunsky.config_z, 9);
+ compiler.parameter_array("nishita_data", sunsky.nishita_data, 9);
+ /* nishita texture */
+ if (type == NODE_SKY_NISHITA) {
+ compiler.parameter_texture("filename", handle.svm_slot());
+ }
compiler.add(this, "node_sky_texture");
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 83c3ad071ae..846ba7423e5 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -168,7 +168,16 @@ class SkyTextureNode : public TextureNode {
float3 sun_direction;
float turbidity;
float ground_albedo;
+ bool sun_disc;
+ float sun_size;
+ float sun_elevation;
+ float sun_rotation;
+ int altitude;
+ float air_density;
+ float dust_density;
+ float ozone_density;
float3 vector;
+ ImageHandle handle;
};
class OutputNode : public ShaderNode {
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 61deef4cd76..c45ae5553a8 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -31,6 +31,7 @@
#include "util/util_murmurhash.h"
#include "util/util_progress.h"
#include "util/util_set.h"
+#include "util/util_task.h"
#include "util/util_vector.h"
#include "subd/subd_patch_table.h"
@@ -77,7 +78,6 @@ struct UpdateObjectTransformState {
Scene *scene;
/* Some locks to keep everything thread-safe. */
- thread_spin_lock queue_lock;
thread_spin_lock surface_area_lock;
/* First unused object index in the queue. */
@@ -219,7 +219,6 @@ void Object::tag_update(Scene *scene)
}
scene->camera->need_flags_update = true;
- scene->curve_system_manager->need_update = true;
scene->geometry_manager->need_update = true;
scene->object_manager->need_update = true;
}
@@ -550,41 +549,6 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
}
}
-bool ObjectManager::device_update_object_transform_pop_work(UpdateObjectTransformState *state,
- int *start_index,
- int *num_objects)
-{
- /* Tweakable parameter, number of objects per chunk.
- * Too small value will cause some extra overhead due to spin lock,
- * too big value might not use all threads nicely.
- */
- static const int OBJECTS_PER_TASK = 32;
- bool have_work = false;
- state->queue_lock.lock();
- int num_scene_objects = state->scene->objects.size();
- if (state->queue_start_object < num_scene_objects) {
- int count = min(OBJECTS_PER_TASK, num_scene_objects - state->queue_start_object);
- *start_index = state->queue_start_object;
- *num_objects = count;
- state->queue_start_object += count;
- have_work = true;
- }
- state->queue_lock.unlock();
- return have_work;
-}
-
-void ObjectManager::device_update_object_transform_task(UpdateObjectTransformState *state)
-{
- int start_index, num_objects;
- while (device_update_object_transform_pop_work(state, &start_index, &num_objects)) {
- for (int i = 0; i < num_objects; ++i) {
- const int object_index = start_index + i;
- Object *ob = state->scene->objects[object_index];
- device_update_object_transform(state, ob);
- }
- }
-}
-
void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
{
UpdateObjectTransformState state;
@@ -630,28 +594,19 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
numparticles += psys->particles.size();
}
- /* NOTE: If it's just a handful of objects we deal with them in a single
- * thread to avoid threading overhead. However, this threshold is might
- * need some tweaks to make mid-complex scenes optimal.
- */
- if (scene->objects.size() < 64) {
- foreach (Object *ob, scene->objects) {
- device_update_object_transform(&state, ob);
- if (progress.get_cancel()) {
- return;
- }
- }
- }
- else {
- const int num_threads = TaskScheduler::num_threads();
- TaskPool pool;
- for (int i = 0; i < num_threads; ++i) {
- pool.push(function_bind(&ObjectManager::device_update_object_transform_task, this, &state));
- }
- pool.wait_work();
- if (progress.get_cancel()) {
- return;
- }
+ /* 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 *ob = state.scene->objects[i];
+ device_update_object_transform(&state, ob);
+ }
+ });
+
+ if (progress.get_cancel()) {
+ return;
}
dscene->objects.copy_to_device();
@@ -664,7 +619,6 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
dscene->data.bvh.have_motion = state.have_motion;
dscene->data.bvh.have_curves = state.have_curves;
- dscene->data.bvh.have_instancing = true;
}
void ObjectManager::device_update(Device *device,
@@ -839,7 +793,6 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
bool motion_blur = need_motion == Scene::MOTION_BLUR;
bool apply_to_motion = need_motion != Scene::MOTION_PASS;
int i = 0;
- bool have_instancing = false;
foreach (Object *object, scene->objects) {
map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
@@ -885,22 +838,15 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
if (geom->transform_negative_scaled)
object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
}
- else
- have_instancing = true;
}
- else
- have_instancing = true;
i++;
}
-
- dscene->data.bvh.have_instancing = have_instancing;
}
void ObjectManager::tag_update(Scene *scene)
{
need_update = true;
- scene->curve_system_manager->need_update = true;
scene->geometry_manager->need_update = true;
scene->light_manager->need_update = true;
}
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index f5b68d5a4fe..9016a8d325f 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -108,7 +108,6 @@ Scene::Scene(const SceneParams &params_, Device *device)
integrator = new Integrator();
image_manager = new ImageManager(device->info);
particle_system_manager = new ParticleSystemManager();
- curve_system_manager = new CurveSystemManager();
bake_manager = new BakeManager();
/* OSL only works on the CPU */
@@ -156,7 +155,6 @@ void Scene::free_memory(bool final)
light_manager->device_free(device, &dscene);
particle_system_manager->device_free(device, &dscene);
- curve_system_manager->device_free(device, &dscene);
bake_manager->device_free(device, &dscene);
@@ -180,7 +178,6 @@ void Scene::free_memory(bool final)
delete shader_manager;
delete light_manager;
delete particle_system_manager;
- delete curve_system_manager;
delete image_manager;
delete bake_manager;
}
@@ -233,12 +230,6 @@ void Scene::device_update(Device *device_, Progress &progress)
if (progress.get_cancel() || device->have_error())
return;
- progress.set_status("Updating Hair Systems");
- curve_system_manager->device_update(device, &dscene, this, progress);
-
- if (progress.get_cancel() || device->have_error())
- return;
-
progress.set_status("Updating Particle Systems");
particle_system_manager->device_update(device, &dscene, this, progress);
@@ -369,8 +360,7 @@ bool Scene::need_data_update()
return (background->need_update || image_manager->need_update || object_manager->need_update ||
geometry_manager->need_update || light_manager->need_update ||
lookup_tables->need_update || integrator->need_update || shader_manager->need_update ||
- particle_system_manager->need_update || curve_system_manager->need_update ||
- bake_manager->need_update || film->need_update);
+ particle_system_manager->need_update || bake_manager->need_update || film->need_update);
}
bool Scene::need_reset()
@@ -393,7 +383,6 @@ void Scene::reset()
geometry_manager->tag_update(this);
light_manager->tag_update(this);
particle_system_manager->tag_update(this);
- curve_system_manager->tag_update(this);
}
void Scene::device_free()
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 6b10a901d7b..67616262c03 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -168,6 +168,8 @@ class SceneParams {
bool use_bvh_spatial_split;
bool use_bvh_unaligned_nodes;
int num_bvh_time_steps;
+ int hair_subdivisions;
+ CurveShapeType hair_shape;
bool persistent_data;
int texture_limit;
@@ -181,6 +183,8 @@ class SceneParams {
use_bvh_spatial_split = false;
use_bvh_unaligned_nodes = true;
num_bvh_time_steps = 0;
+ hair_subdivisions = 3;
+ hair_shape = CURVE_RIBBON;
persistent_data = false;
texture_limit = 0;
background = true;
@@ -193,8 +197,15 @@ class SceneParams {
use_bvh_spatial_split == params.use_bvh_spatial_split &&
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 &&
persistent_data == params.persistent_data && texture_limit == params.texture_limit);
}
+
+ int curve_subdivisions()
+ {
+ /* Matching the tesselation rate limit in Embree. */
+ return clamp(1 << hair_subdivisions, 1, 16);
+ }
};
/* Scene */
@@ -226,7 +237,6 @@ class Scene {
GeometryManager *geometry_manager;
ObjectManager *object_manager;
ParticleSystemManager *particle_system_manager;
- CurveSystemManager *curve_system_manager;
BakeManager *bake_manager;
/* default shaders */
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index f5bfebbaf78..1a94d3e9db7 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -61,8 +61,10 @@ Session::Session(const SessionParams &params_)
TaskScheduler::init(params.threads);
+ /* Create CPU/GPU devices. */
device = Device::create(params.device, stats, profiler, params.background);
+ /* Create buffers for interactive rendering. */
if (params.background && !params.write_render_cb) {
buffers = NULL;
display = NULL;
@@ -72,6 +74,9 @@ Session::Session(const SessionParams &params_)
display = new DisplayBuffer(device, params.display_buffer_linear);
}
+ /* Validate denoising parameters. */
+ set_denoising(params.denoising);
+
session_thread = NULL;
scene = NULL;
@@ -773,6 +778,7 @@ DeviceRequestedFeatures Session::get_requested_device_features()
*/
bool use_motion = scene->need_motion() == Scene::MotionType::MOTION_BLUR;
requested_features.use_hair = false;
+ requested_features.use_hair_thick = (scene->params.hair_shape == CURVE_THICK);
requested_features.use_object_motion = false;
requested_features.use_camera_motion = use_motion && scene->camera->use_motion();
foreach (Object *object, scene->objects) {
@@ -804,7 +810,7 @@ DeviceRequestedFeatures Session::get_requested_device_features()
requested_features.use_baking = bake_manager->get_baking();
requested_features.use_integrator_branched = (scene->integrator->method ==
Integrator::BRANCHED_PATH);
- if (params.run_denoising) {
+ if (params.denoising.use || params.denoising.store_passes) {
requested_features.use_denoising = true;
requested_features.use_shadow_tricks = true;
}
@@ -941,24 +947,35 @@ void Session::set_pause(bool pause_)
pause_cond.notify_all();
}
-void Session::set_denoising(bool denoising, bool optix_denoising)
+void Session::set_denoising(const DenoiseParams &denoising)
{
+ bool need_denoise = denoising.need_denoising_task();
+
/* Lock buffers so no denoising operation is triggered while the settings are changed here. */
thread_scoped_lock buffers_lock(buffers_mutex);
+ params.denoising = denoising;
+
+ if (!(params.device.denoisers & denoising.type)) {
+ if (need_denoise) {
+ progress.set_error("Denoiser type not supported by compute device");
+ }
- params.run_denoising = denoising;
- params.full_denoising = !optix_denoising;
- params.optix_denoising = optix_denoising;
+ params.denoising.use = false;
+ need_denoise = false;
+ }
// TODO(pmours): Query the required overlap value for denoising from the device?
- tile_manager.slice_overlap = denoising && !params.background ? 64 : 0;
- tile_manager.schedule_denoising = denoising && !buffers;
+ tile_manager.slice_overlap = need_denoise && !params.background ? 64 : 0;
+
+ /* Schedule per tile denoising for final renders if we are either denoising or
+ * need prefiltered passes for the native denoiser. */
+ tile_manager.schedule_denoising = need_denoise && !buffers;
}
void Session::set_denoising_start_sample(int sample)
{
- if (sample != params.denoising_start_sample) {
- params.denoising_start_sample = sample;
+ if (sample != params.denoising.start_sample) {
+ params.denoising.start_sample = sample;
pause_cond.notify_all();
}
@@ -1078,10 +1095,10 @@ void Session::update_status_time(bool show_pause, bool show_done)
*/
substatus += string_printf(", Sample %d/%d", progress.get_current_sample(), num_samples);
}
- if (params.full_denoising || params.optix_denoising) {
+ if (params.denoising.use && params.denoising.type != DENOISER_OPENIMAGEDENOISE) {
substatus += string_printf(", Denoised %d tiles", progress.get_denoised_tiles());
}
- else if (params.run_denoising) {
+ else if (params.denoising.store_passes && params.denoising.type == DENOISER_NLM) {
substatus += string_printf(", Prefiltered %d tiles", progress.get_denoised_tiles());
}
}
@@ -1110,7 +1127,7 @@ bool Session::render_need_denoise(bool &delayed)
delayed = false;
/* Denoising enabled? */
- if (!params.run_denoising) {
+ if (!params.denoising.need_denoising_task()) {
return false;
}
@@ -1127,7 +1144,7 @@ bool Session::render_need_denoise(bool &delayed)
}
/* Do not denoise until the sample at which denoising should start is reached. */
- if (tile_manager.state.sample < params.denoising_start_sample) {
+ if (tile_manager.state.sample < min(params.denoising.start_sample, params.samples - 1)) {
return false;
}
@@ -1178,9 +1195,6 @@ void Session::render(bool need_denoise)
task.pass_denoising_clean = scene->film->denoising_clean_offset;
task.denoising_from_render = true;
- task.denoising_do_filter = params.full_denoising;
- task.denoising_use_optix = params.optix_denoising;
- task.denoising_write_passes = params.write_denoising_passes;
if (tile_manager.schedule_denoising) {
/* Acquire denoising tiles during rendering. */
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 2707eed5531..0141629762c 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -62,10 +62,6 @@ class SessionParams {
bool display_buffer_linear;
- bool run_denoising;
- bool write_denoising_passes;
- bool full_denoising;
- bool optix_denoising;
DenoiseParams denoising;
double cancel_timeout;
@@ -94,11 +90,6 @@ class SessionParams {
use_profiling = false;
- run_denoising = false;
- write_denoising_passes = false;
- full_denoising = false;
- optix_denoising = false;
-
display_buffer_linear = false;
cancel_timeout = 0.1;
@@ -125,7 +116,8 @@ class SessionParams {
cancel_timeout == params.cancel_timeout && reset_timeout == params.reset_timeout &&
text_timeout == params.text_timeout &&
progressive_update_timeout == params.progressive_update_timeout &&
- tile_order == params.tile_order && shadingsystem == params.shadingsystem);
+ tile_order == params.tile_order && shadingsystem == params.shadingsystem &&
+ denoising.type == params.denoising.type);
}
};
@@ -161,7 +153,7 @@ class Session {
void reset(BufferParams &params, int samples);
void set_pause(bool pause);
void set_samples(int samples);
- void set_denoising(bool denoising, bool optix_denoising);
+ void set_denoising(const DenoiseParams &denoising);
void set_denoising_start_sample(int sample);
bool update_scene();
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 39ba45a751a..1120d909e98 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -33,6 +33,7 @@
#include "util/util_foreach.h"
#include "util/util_murmurhash.h"
+#include "util/util_task.h"
#ifdef WITH_OCIO
# include <OpenColorIO/OpenColorIO.h>
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index ea3dbaf8e03..88714e20a90 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -94,8 +94,7 @@ void SVMShaderManager::device_update(Device *device,
scene,
scene->shaders[i],
&progress,
- &shader_svm_nodes[i]),
- false);
+ &shader_svm_nodes[i]));
}
task_pool.wait_work();