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')
-rw-r--r--intern/cycles/app/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/addon/engine.py27
-rw-r--r--intern/cycles/blender/addon/properties.py37
-rw-r--r--intern/cycles/blender/addon/ui.py11
-rw-r--r--intern/cycles/blender/blender_camera.cpp17
-rw-r--r--intern/cycles/blender/blender_id_map.h2
-rw-r--r--intern/cycles/blender/blender_mesh.cpp77
-rw-r--r--intern/cycles/blender/blender_object.cpp4
-rw-r--r--intern/cycles/blender/blender_python.cpp1
-rw-r--r--intern/cycles/blender/blender_session.cpp29
-rw-r--r--intern/cycles/blender/blender_shader.cpp7
-rw-r--r--intern/cycles/blender/blender_sync.cpp71
-rw-r--r--intern/cycles/blender/blender_sync.h2
-rw-r--r--intern/cycles/blender/blender_util.h6
-rw-r--r--intern/cycles/blender/blender_volume.cpp75
-rw-r--r--intern/cycles/cmake/external_libs.cmake4
-rw-r--r--intern/cycles/device/cuda/device_cuda_impl.cpp25
-rw-r--r--intern/cycles/device/device.cpp4
-rw-r--r--intern/cycles/device/device.h4
-rw-r--r--intern/cycles/device/device_cpu.cpp235
-rw-r--r--intern/cycles/device/device_denoising.cpp52
-rw-r--r--intern/cycles/device/device_denoising.h8
-rw-r--r--intern/cycles/device/device_multi.cpp47
-rw-r--r--intern/cycles/device/device_optix.cpp395
-rw-r--r--intern/cycles/device/device_task.h21
-rw-r--r--intern/cycles/device/opencl/device_opencl_impl.cpp2
-rw-r--r--intern/cycles/kernel/CMakeLists.txt4
-rw-r--r--intern/cycles/kernel/bvh/bvh.h23
-rw-r--r--intern/cycles/kernel/geom/geom_curve_intersect.h9
-rw-r--r--intern/cycles/kernel/kernel_camera.h2
-rw-r--r--intern/cycles/kernel/kernel_light_background.h2
-rw-r--r--intern/cycles/kernel/kernel_path.h14
-rw-r--r--intern/cycles/kernel/kernel_shader.h31
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h2
-rw-r--r--intern/cycles/kernel/kernels/optix/kernel_optix.cu48
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl50
-rw-r--r--intern/cycles/kernel/svm/svm_sky.h21
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/buffers.h46
-rw-r--r--intern/cycles/render/camera.cpp40
-rw-r--r--intern/cycles/render/denoising.cpp64
-rw-r--r--intern/cycles/render/denoising.h4
-rw-r--r--intern/cycles/render/graph.cpp4
-rw-r--r--intern/cycles/render/image.cpp6
-rw-r--r--intern/cycles/render/image.h2
-rw-r--r--intern/cycles/render/image_sky.cpp33
-rw-r--r--intern/cycles/render/image_sky.h4
-rw-r--r--intern/cycles/render/light.cpp14
-rw-r--r--intern/cycles/render/nodes.cpp58
-rw-r--r--intern/cycles/render/nodes.h3
-rw-r--r--intern/cycles/render/object.cpp6
-rw-r--r--intern/cycles/render/session.cpp81
-rw-r--r--intern/cycles/render/session.h4
-rw-r--r--intern/cycles/test/CMakeLists.txt1
-rw-r--r--intern/cycles/test/util_transform_test.cpp53
-rw-r--r--intern/cycles/util/CMakeLists.txt5
-rw-r--r--intern/cycles/util/util_avxb.h2
-rw-r--r--intern/cycles/util/util_avxi.h2
-rw-r--r--intern/cycles/util/util_debug.cpp1
-rw-r--r--intern/cycles/util/util_debug.h3
-rw-r--r--intern/cycles/util/util_math.h10
-rw-r--r--intern/cycles/util/util_math_fast.h20
-rw-r--r--intern/cycles/util/util_math_float4.h18
-rw-r--r--intern/cycles/util/util_sky_model.cpp349
-rw-r--r--intern/cycles/util/util_sky_model.h453
-rw-r--r--intern/cycles/util/util_sky_model_data.h3847
-rw-r--r--intern/cycles/util/util_sky_nishita.cpp371
-rw-r--r--intern/cycles/util/util_sseb.h2
-rw-r--r--intern/cycles/util/util_ssei.h2
-rw-r--r--intern/cycles/util/util_tbb.h5
-rw-r--r--intern/cycles/util/util_transform.cpp28
-rw-r--r--intern/cycles/util/util_transform.h11
72 files changed, 1332 insertions, 5593 deletions
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index ef374f91a65..a2b0ed03925 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -35,7 +35,7 @@ if(WITH_CYCLES_OSL)
endif()
if(NOT CYCLES_STANDALONE_REPOSITORY)
- list(APPEND LIBRARIES bf_intern_glew_mx bf_intern_guardedalloc bf_intern_numaapi)
+ list(APPEND LIBRARIES bf_intern_glew_mx bf_intern_guardedalloc bf_intern_numaapi bf_intern_sky)
endif()
if(WITH_CYCLES_LOGGING)
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 7566ca28dd7..67e448db859 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -224,7 +224,7 @@ def system_info():
import _cycles
return _cycles.system_info()
-def list_render_passes(srl):
+def list_render_passes(scene, srl):
# Builtin Blender passes.
yield ("Combined", "RGBA", 'COLOR')
@@ -279,14 +279,17 @@ def list_render_passes(srl):
yield ("Denoising Normal", "XYZ", 'VECTOR')
yield ("Denoising Albedo", "RGB", 'COLOR')
yield ("Denoising Depth", "Z", 'VALUE')
- yield ("Denoising Shadowing", "X", 'VALUE')
- yield ("Denoising Variance", "RGB", 'COLOR')
- yield ("Denoising Intensity", "X", 'VALUE')
- clean_options = ("denoising_diffuse_direct", "denoising_diffuse_indirect",
- "denoising_glossy_direct", "denoising_glossy_indirect",
- "denoising_transmission_direct", "denoising_transmission_indirect")
- if any(getattr(crl, option) for option in clean_options):
- yield ("Denoising Clean", "RGB", 'COLOR')
+
+ if scene.cycles.denoiser == 'NLM':
+ yield ("Denoising Shadowing", "X", 'VALUE')
+ yield ("Denoising Variance", "RGB", 'COLOR')
+ yield ("Denoising Intensity", "X", 'VALUE')
+
+ clean_options = ("denoising_diffuse_direct", "denoising_diffuse_indirect",
+ "denoising_glossy_direct", "denoising_glossy_indirect",
+ "denoising_transmission_direct", "denoising_transmission_indirect")
+ if any(getattr(crl, option) for option in clean_options):
+ yield ("Denoising Clean", "RGB", 'COLOR')
# Custom AOV passes.
for aov in crl.aovs:
@@ -298,15 +301,15 @@ def list_render_passes(srl):
def register_passes(engine, scene, view_layer):
# Detect duplicate render pass names, first one wins.
listed = set()
- for name, channelids, channeltype in list_render_passes(view_layer):
+ for name, channelids, channeltype in list_render_passes(scene, view_layer):
if name not in listed:
engine.register_pass(scene, view_layer, name, len(channelids), channelids, channeltype)
listed.add(name)
-def detect_conflicting_passes(view_layer):
+def detect_conflicting_passes(scene, view_layer):
# Detect conflicting render pass names for UI.
counter = {}
- for name, _, _ in list_render_passes(view_layer):
+ for name, _, _ in list_render_passes(scene, view_layer):
counter[name] = counter.get(name, 0) + 1
for aov in view_layer.cycles.aovs:
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index da706451f88..45d25720aff 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -182,6 +182,7 @@ enum_aov_types = (
('COLOR', "Color", "Write a Color pass", 1),
)
+
def enum_openimagedenoise_denoiser(self, context):
if _cycles.with_openimagedenoise:
return [('OPENIMAGEDENOISE', "OpenImageDenoise", "Use Intel OpenImageDenoise AI denoiser running on the CPU", 4)]
@@ -208,14 +209,23 @@ def enum_preview_denoiser(self, context):
def enum_denoiser(self, context):
items = [('NLM', "NLM", "Cycles native non-local means denoiser, running on any compute device", 1)]
items += enum_optix_denoiser(self, context)
+ items += enum_openimagedenoise_denoiser(self, context)
return items
-enum_denoising_optix_input_passes = (
+enum_denoising_input_passes = (
('RGB', "Color", "Use only color as input", 1),
('RGB_ALBEDO', "Color + Albedo", "Use color and albedo data as input", 2),
('RGB_ALBEDO_NORMAL', "Color + Albedo + Normal", "Use color, albedo and normal data as input", 3),
)
+
+def update_render_passes(self, context):
+ scene = context.scene
+ view_layer = context.view_layer
+ view_layer.update_render_passes()
+ engine.detect_conflicting_passes(scene, view_layer)
+
+
class CyclesRenderSettings(bpy.types.PropertyGroup):
device: EnumProperty(
@@ -261,9 +271,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
denoiser: EnumProperty(
name="Denoiser",
- description="Denoise the image with the selected denoiser",
+ description="Denoise the image with the selected denoiser. "
+ "For denoising the image after rendering, denoising data render passes "
+ "also adapt to the selected denoiser",
items=enum_denoiser,
default=1,
+ update=update_render_passes,
)
preview_denoiser: EnumProperty(
name="Viewport Denoiser",
@@ -818,6 +831,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
debug_use_cuda_split_kernel: BoolProperty(name="Split Kernel", default=False)
debug_optix_cuda_streams: IntProperty(name="CUDA Streams", default=1, min=1)
+ debug_optix_curves_api: BoolProperty(name="Native OptiX Curve Primitive", default=False)
debug_opencl_kernel_type: EnumProperty(
name="OpenCL Kernel Type",
@@ -1291,12 +1305,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
del bpy.types.Scene.cycles_curves
-def update_render_passes(self, context):
- view_layer = context.view_layer
- view_layer.update_render_passes()
- engine.detect_conflicting_passes(view_layer)
-
-
class CyclesAOVPass(bpy.types.PropertyGroup):
name: StringProperty(
name="Name",
@@ -1430,7 +1438,7 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
)
denoising_store_passes: BoolProperty(
name="Store Denoising Passes",
- description="Store the denoising feature passes and the noisy image",
+ description="Store the denoising feature passes and the noisy image. The passes adapt to the denoiser selected for rendering",
default=False,
update=update_render_passes,
)
@@ -1443,11 +1451,18 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
denoising_optix_input_passes: EnumProperty(
name="Input Passes",
- description="Passes handed over to the OptiX denoiser (this can have different effects on the denoised image)",
- items=enum_denoising_optix_input_passes,
+ description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
+ items=enum_denoising_input_passes,
default='RGB_ALBEDO',
)
+ denoising_openimagedenoise_input_passes: EnumProperty(
+ name="Input Passes",
+ description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
+ items=enum_denoising_input_passes,
+ default='RGB_ALBEDO_NORMAL',
+ )
+
use_pass_crypto_object: BoolProperty(
name="Cryptomatte Object",
description="Render cryptomatte object pass, for isolating objects in compositing",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 129f16b0357..03b1675c309 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -265,7 +265,12 @@ class CYCLES_RENDER_PT_sampling_denoising(CyclesButtonsPanel, Panel):
row = heading.row(align=True)
row.prop(cscene, "use_denoising", text="")
sub = row.row()
+
sub.active = cscene.use_denoising
+ for view_layer in scene.view_layers:
+ if view_layer.cycles.denoising_store_passes:
+ sub.active = True
+
sub.prop(cscene, "denoiser", text="")
heading = layout.column(align=False, heading="Viewport")
@@ -777,10 +782,6 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_solid", text="Surfaces")
col.prop(view_layer, "use_strand", text="Hair")
col.prop(view_layer, "use_volumes", text="Volumes")
- if with_freestyle:
- sub = col.row(align=True)
- sub.prop(view_layer, "use_freestyle", text="Freestyle")
- sub.active = rd.use_freestyle
class CYCLES_RENDER_PT_override(CyclesButtonsPanel, Panel):
@@ -1007,6 +1008,7 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
col.prop(cycles_view_layer, "denoising_optix_input_passes")
return
elif denoiser == 'OPENIMAGEDENOISE':
+ col.prop(cycles_view_layer, "denoising_openimagedenoise_input_passes")
return
col.prop(cycles_view_layer, "denoising_radius", text="Radius")
@@ -2026,6 +2028,7 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
col = layout.column()
col.label(text="OptiX Flags:")
col.prop(cscene, "debug_optix_cuda_streams")
+ col.prop(cscene, "debug_optix_curves_api")
col.separator()
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 011678a7a65..e1ab3b3fbc1 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -76,6 +76,9 @@ struct BlenderCamera {
int full_width;
int full_height;
+ int render_width;
+ int render_height;
+
BoundBox2D border;
BoundBox2D pano_viewplane;
BoundBox2D viewport_camera_border;
@@ -126,8 +129,10 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende
bcam->matrix = transform_identity();
/* render resolution */
- bcam->full_width = render_resolution_x(b_render);
- bcam->full_height = render_resolution_y(b_render);
+ bcam->render_width = render_resolution_x(b_render);
+ bcam->render_height = render_resolution_y(b_render);
+ bcam->full_width = bcam->render_width;
+ bcam->full_height = bcam->render_height;
}
static float blender_camera_focal_distance(BL::RenderEngine &b_engine,
@@ -398,8 +403,8 @@ static void blender_camera_sync(Camera *cam,
/* panorama sensor */
if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
- float fit_xratio = (float)bcam->full_width * bcam->pixelaspect.x;
- float fit_yratio = (float)bcam->full_height * bcam->pixelaspect.y;
+ float fit_xratio = (float)bcam->render_width * bcam->pixelaspect.x;
+ float fit_yratio = (float)bcam->render_height * bcam->pixelaspect.y;
bool horizontal_fit;
float sensor_size;
@@ -709,6 +714,10 @@ static void blender_camera_from_view(BlenderCamera *bcam,
/* 3d view transform */
bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
+
+ /* dimensions */
+ bcam->full_width = width;
+ bcam->full_height = height;
}
static void blender_camera_view_subset(BL::RenderEngine &b_engine,
diff --git a/intern/cycles/blender/blender_id_map.h b/intern/cycles/blender/blender_id_map.h
index 3bc42e349ae..b5f6aaa67a8 100644
--- a/intern/cycles/blender/blender_id_map.h
+++ b/intern/cycles/blender/blender_id_map.h
@@ -200,7 +200,7 @@ template<typename K, typename T> class id_map {
* To uniquely identify instances, we use the parent, object and persistent instance ID.
* We also export separate object for a mesh and its particle hair. */
-enum { OBJECT_PERSISTENT_ID_SIZE = 16 };
+enum { OBJECT_PERSISTENT_ID_SIZE = 8 /* MAX_DUPLI_RECUR in Blender. */ };
struct ObjectKey {
void *parent;
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 49407799fcd..f4354d5166e 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -923,6 +923,74 @@ static void create_subd_mesh(Scene *scene,
/* Sync */
+static BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob,
+ BL::Scene /*b_scene*/)
+{
+ BL::Object::modifiers_iterator b_mod;
+
+ for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
+ if (!b_mod->is_a(&RNA_MeshSequenceCacheModifier)) {
+ continue;
+ }
+
+ BL::MeshSequenceCacheModifier mesh_cache = BL::MeshSequenceCacheModifier(*b_mod);
+
+ if (MeshSequenceCacheModifier_has_velocity_get(&mesh_cache.ptr)) {
+ return mesh_cache;
+ }
+ }
+
+ return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
+}
+
+static void sync_mesh_cached_velocities(BL::Object &b_ob,
+ BL::Scene b_scene,
+ Scene *scene,
+ Mesh *mesh)
+{
+ if (scene->need_motion() == Scene::MOTION_NONE)
+ return;
+
+ BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob, b_scene);
+
+ if (!b_mesh_cache) {
+ return;
+ }
+
+ /* Find or add attribute */
+ float3 *P = &mesh->verts[0];
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (!attr_mP) {
+ attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+
+ if (!MeshSequenceCacheModifier_read_velocity_get(&b_mesh_cache.ptr)) {
+ return;
+ }
+
+ const size_t numverts = mesh->verts.size();
+
+ if (b_mesh_cache.vertex_velocities.length() != numverts) {
+ return;
+ }
+
+ /* Only export previous and next frame, we don't have any in between data. */
+ float motion_times[2] = {-1.0f, 1.0f};
+ for (int step = 0; step < 2; step++) {
+ const float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
+ float3 *mP = attr_mP->data_float3() + step * numverts;
+
+ BL::MeshSequenceCacheModifier::vertex_velocities_iterator vvi;
+ int i = 0;
+
+ for (b_mesh_cache.vertex_velocities.begin(vvi); vvi != b_mesh_cache.vertex_velocities.end();
+ ++vvi, ++i) {
+ mP[i] = P[i] + get_float3(vvi->velocity()) * relative_time;
+ }
+ }
+}
+
static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
{
if (scene->need_motion() == Scene::MOTION_NONE)
@@ -1002,6 +1070,9 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph,
}
}
+ /* cached velocities (e.g. from alembic archive) */
+ sync_mesh_cached_velocities(b_ob, b_depsgraph.scene(), scene, mesh);
+
/* mesh fluid motion mantaflow */
sync_mesh_fluid_motion(b_ob, scene, mesh);
@@ -1023,6 +1094,12 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
return;
}
+ /* Cached motion blur already exported. */
+ BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(b_ob, b_scene);
+ if (mesh_cache) {
+ return;
+ }
+
/* Skip if no vertices were exported. */
size_t numverts = mesh->verts.size();
if (numverts == 0) {
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index d3a37563ef4..3ea6892a349 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -59,7 +59,7 @@ bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
return false;
}
-bool BlenderSync::object_is_mesh(BL::Object &b_ob)
+bool BlenderSync::object_is_geometry(BL::Object &b_ob)
{
BL::ID b_ob_data = b_ob.data();
@@ -143,7 +143,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
}
/* only interested in object that we can create meshes from */
- if (!object_is_mesh(b_ob)) {
+ if (!object_is_geometry(b_ob)) {
return NULL;
}
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 3e595c3ee52..25c77b74ce3 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -92,6 +92,7 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene)
flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
/* Synchronize OptiX flags. */
flags.optix.cuda_streams = get_int(cscene, "debug_optix_cuda_streams");
+ flags.optix.curves_api = get_boolean(cscene, "debug_optix_curves_api");
/* Synchronize OpenCL device type. */
switch (get_enum(cscene, "debug_opencl_device_type")) {
case 0:
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 391a1b8f473..a06030c8b7d 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -59,6 +59,7 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
BL::BlendData &b_data,
bool preview_osl)
: session(NULL),
+ scene(NULL),
sync(NULL),
b_engine(b_engine),
b_userpref(b_userpref),
@@ -88,6 +89,7 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
int width,
int height)
: session(NULL),
+ scene(NULL),
sync(NULL),
b_engine(b_engine),
b_userpref(b_userpref),
@@ -492,27 +494,15 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
/* Update denoising parameters. */
session->set_denoising(session_params.denoising);
- bool use_denoising = session_params.denoising.use;
- bool store_denoising_passes = session_params.denoising.store_passes;
-
- buffer_params.denoising_data_pass = use_denoising || store_denoising_passes;
- buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
- buffer_params.denoising_prefiltered_pass = store_denoising_passes &&
- session_params.denoising.type == DENOISER_NLM;
-
- scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
- scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
- scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass;
-
- /* Add passes */
+ /* Compute render passes and film settings. */
vector<Pass> passes = sync->sync_render_passes(
b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising);
- buffer_params.passes = passes;
- scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
- scene->film->tag_passes_update(scene, passes);
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
+ /* Set buffer params, using film settings from sync_render_passes. */
+ buffer_params.passes = passes;
+ buffer_params.denoising_data_pass = scene->film->denoising_data_pass;
+ buffer_params.denoising_clean_pass = scene->film->denoising_clean_pass;
+ buffer_params.denoising_prefiltered_pass = scene->film->denoising_prefiltered_pass;
BL::RenderResult::views_iterator b_view_iter;
@@ -982,7 +972,8 @@ void BlenderSession::update_status_progress()
remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
if (background) {
- scene_status += " | " + scene->name;
+ if (scene)
+ scene_status += " | " + scene->name;
if (b_rlay_name != "")
scene_status += ", " + b_rlay_name;
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 19d2730dc93..ae681432a43 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -678,7 +678,7 @@ static ShaderNode *add_node(Scene *scene,
* builtin names for packed images and movies
*/
int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
image->handle = scene->image_manager->add_image(
new BlenderImageLoader(b_image, image_frame), image->image_params());
}
@@ -713,7 +713,7 @@ static ShaderNode *add_node(Scene *scene,
if (is_builtin) {
int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
env->handle = scene->image_manager->add_image(new BlenderImageLoader(b_image, image_frame),
env->image_params());
}
@@ -815,9 +815,10 @@ static ShaderNode *add_node(Scene *scene,
sky->ground_albedo = b_sky_node.ground_albedo();
sky->sun_disc = b_sky_node.sun_disc();
sky->sun_size = b_sky_node.sun_size();
+ sky->sun_intensity = b_sky_node.sun_intensity();
sky->sun_elevation = b_sky_node.sun_elevation();
sky->sun_rotation = b_sky_node.sun_rotation();
- sky->altitude = b_sky_node.altitude();
+ sky->altitude = 1000.0f * b_sky_node.altitude();
sky->air_density = b_sky_node.air_density();
sky->dust_density = b_sky_node.dust_density();
sky->ozone_density = b_sky_node.ozone_density();
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index bf065cc5492..511061db08a 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -147,30 +147,43 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
/* Object */
else if (b_id.is_a(&RNA_Object)) {
BL::Object b_ob(b_id);
- const bool updated_geometry = b_update->is_updated_geometry();
+ const bool is_geometry = object_is_geometry(b_ob);
+ const bool is_light = !is_geometry && object_is_light(b_ob);
- if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
- object_map.set_recalc(b_ob);
- light_map.set_recalc(b_ob);
- }
+ if (is_geometry || is_light) {
+ const bool updated_geometry = b_update->is_updated_geometry();
- if (object_is_mesh(b_ob)) {
- if (updated_geometry ||
- (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) {
- BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
- geometry_map.set_recalc(key);
- }
- }
- else if (object_is_light(b_ob)) {
- if (updated_geometry) {
- light_map.set_recalc(b_ob);
+ /* Geometry (mesh, hair, volume). */
+ if (is_geometry) {
+ if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
+ object_map.set_recalc(b_ob);
+ }
+
+ if (updated_geometry ||
+ (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) {
+ BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
+ geometry_map.set_recalc(key);
+ }
+
+ if (updated_geometry) {
+ BL::Object::particle_systems_iterator b_psys;
+ for (b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end();
+ ++b_psys) {
+ particle_system_map.set_recalc(b_ob);
+ }
+ }
}
- }
+ /* Light */
+ else if (is_light) {
+ if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
+ object_map.set_recalc(b_ob);
+ light_map.set_recalc(b_ob);
+ }
- if (updated_geometry) {
- BL::Object::particle_systems_iterator b_psys;
- for (b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys)
- particle_system_map.set_recalc(b_ob);
+ if (updated_geometry) {
+ light_map.set_recalc(b_ob);
+ }
+ }
}
}
/* Mesh */
@@ -684,6 +697,16 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
}
RNA_END;
+ scene->film->denoising_data_pass = denoising.use || denoising.store_passes;
+ scene->film->denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
+ scene->film->denoising_prefiltered_pass = denoising.store_passes &&
+ denoising.type == DENOISER_NLM;
+
+ scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
+ scene->film->tag_passes_update(scene, passes);
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
return passes;
}
@@ -941,7 +964,13 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
denoising.strength = get_float(clayer, "denoising_strength");
denoising.feature_strength = get_float(clayer, "denoising_feature_strength");
denoising.relative_pca = get_boolean(clayer, "denoising_relative_pca");
- denoising.optix_input_passes = get_enum(clayer, "denoising_optix_input_passes");
+
+ denoising.input_passes = (DenoiserInput)get_enum(
+ clayer,
+ (denoising.type == DENOISER_OPTIX) ? "denoising_optix_input_passes" :
+ "denoising_openimagedenoise_input_passes",
+ DENOISER_INPUT_NUM,
+ DENOISER_INPUT_RGB_ALBEDO_NORMAL);
denoising.store_passes = get_boolean(clayer, "denoising_store_passes");
}
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 0214d9eb3b8..a551ec31e04 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -208,7 +208,7 @@ class BlenderSync {
/* util */
void find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader);
bool BKE_object_is_modified(BL::Object &b_ob);
- bool object_is_mesh(BL::Object &b_ob);
+ bool object_is_geometry(BL::Object &b_ob);
bool object_is_light(BL::Object &b_ob);
/* variables */
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index ad90a5f8d52..1ea34b41aa2 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -238,7 +238,7 @@ static inline string image_user_file_path(BL::ImageUser &iuser,
{
char filepath[1024];
iuser.tile(0);
- BKE_image_user_frame_calc(NULL, iuser.ptr.data, cfra);
+ BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
string filepath_str = string(filepath);
@@ -248,9 +248,9 @@ static inline string image_user_file_path(BL::ImageUser &iuser,
return filepath_str;
}
-static inline int image_user_frame_number(BL::ImageUser &iuser, int cfra)
+static inline int image_user_frame_number(BL::ImageUser &iuser, BL::Image &ima, int cfra)
{
- BKE_image_user_frame_calc(NULL, iuser.ptr.data, cfra);
+ BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
return iuser.frame_current();
}
diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 80591e0eec8..d0e1e4d6131 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -217,43 +217,29 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
class BlenderVolumeLoader : public VDBImageLoader {
public:
BlenderVolumeLoader(BL::BlendData &b_data, BL::Volume &b_volume, const string &grid_name)
- : VDBImageLoader(grid_name), b_data(b_data), b_volume(b_volume), unload(false)
- {
- }
-
- bool load_metadata(ImageMetaData &metadata) override
+ : VDBImageLoader(grid_name), b_volume(b_volume)
{
b_volume.grids.load(b_data.ptr.data);
- BL::VolumeGrid b_volume_grid = find_grid();
-
- if (!b_volume_grid) {
- return false;
- }
-
- unload = !b_volume_grid.is_loaded();
#ifdef WITH_OPENVDB
- Volume *volume = (Volume *)b_volume.ptr.data;
- VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
- grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
-#endif
+ BL::Volume::grids_iterator b_grid_iter;
+ for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
+ BL::VolumeGrid b_volume_grid(*b_grid_iter);
+ if (b_volume_grid.name() == grid_name) {
+ const bool unload = !b_volume_grid.is_loaded();
- return VDBImageLoader::load_metadata(metadata);
- }
+ Volume *volume = (Volume *)b_volume.ptr.data;
+ VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
+ grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
- bool load_pixels(const ImageMetaData &metadata,
- void *pixels,
- const size_t pixel_size,
- const bool associate_alpha) override
- {
- b_volume.grids.load(b_data.ptr.data);
- BL::VolumeGrid b_volume_grid = find_grid();
+ if (unload) {
+ b_volume_grid.unload();
+ }
- if (!b_volume_grid) {
- return false;
+ break;
+ }
}
-
- return VDBImageLoader::load_pixels(metadata, pixels, pixel_size, associate_alpha);
+#endif
}
bool equals(const ImageLoader &other) const override
@@ -263,36 +249,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
return b_volume == other_loader.b_volume && grid_name == other_loader.grid_name;
}
- void cleanup() override
- {
- VDBImageLoader::cleanup();
-
- BL::VolumeGrid b_volume_grid = find_grid();
- if (b_volume_grid && unload) {
- b_volume_grid.unload();
- }
- }
-
- /* Find grid with matching name. Grid point not stored in the class since
- * grids may be unloaded before we load the pixels, for example for motion
- * blur where we move between frames. */
- BL::VolumeGrid find_grid()
- {
-#ifdef WITH_OPENVDB
- BL::Volume::grids_iterator b_grid_iter;
- for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
- if (b_grid_iter->name() == grid_name) {
- return *b_grid_iter;
- }
- }
-#endif
-
- return BL::VolumeGrid(PointerRNA_NULL);
- }
-
- BL::BlendData b_data;
BL::Volume b_volume;
- bool unload;
};
static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *scene, Mesh *mesh)
@@ -342,7 +299,7 @@ static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *s
ImageParams params;
params.frame = b_volume.grids.frame();
- attr->data_voxel() = scene->image_manager->add_image(loader, params);
+ attr->data_voxel() = scene->image_manager->add_image(loader, params, false);
}
}
}
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index 0b082b11cf7..b09f442bd16 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -133,9 +133,9 @@ if(CYCLES_STANDALONE_REPOSITORY)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
####
- # embree
+ # Embree
if(WITH_CYCLES_EMBREE)
- find_package(embree 3.8.0 REQUIRED)
+ find_package(Embree 3.8.0 REQUIRED)
endif()
####
diff --git a/intern/cycles/device/cuda/device_cuda_impl.cpp b/intern/cycles/device/cuda/device_cuda_impl.cpp
index b9bbeb9a25b..3a2eb8df95b 100644
--- a/intern/cycles/device/cuda/device_cuda_impl.cpp
+++ b/intern/cycles/device/cuda/device_cuda_impl.cpp
@@ -383,11 +383,24 @@ string CUDADevice::compile_kernel(const DeviceRequestedFeatures &requested_featu
}
}
- const string ptx = path_get(string_printf("lib/%s_compute_%d%d.ptx", name, major, minor));
- VLOG(1) << "Testing for pre-compiled kernel " << ptx << ".";
- if (path_exists(ptx)) {
- VLOG(1) << "Using precompiled kernel.";
- return ptx;
+ /* The driver can JIT-compile PTX generated for older generations, so find the closest one. */
+ int ptx_major = major, ptx_minor = minor;
+ while (ptx_major >= 3) {
+ const string ptx = path_get(
+ string_printf("lib/%s_compute_%d%d.ptx", name, ptx_major, ptx_minor));
+ VLOG(1) << "Testing for pre-compiled kernel " << ptx << ".";
+ if (path_exists(ptx)) {
+ VLOG(1) << "Using precompiled kernel.";
+ return ptx;
+ }
+
+ if (ptx_minor > 0) {
+ ptx_minor--;
+ }
+ else {
+ ptx_major--;
+ ptx_minor = 9;
+ }
}
}
@@ -1760,7 +1773,7 @@ void CUDADevice::denoise(RenderTile &rtile, DenoisingTask &denoising)
denoising.render_buffer.samples = rtile.sample;
denoising.buffer.gpu_temporary_mem = true;
- denoising.run_denoising(&rtile);
+ denoising.run_denoising(rtile);
}
void CUDADevice::adaptive_sampling_filter(uint filter_sample,
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 9dbb33980b4..407f73e8451 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -209,13 +209,13 @@ bool Device::bind_fallback_display_space_shader(const float width, const float h
glUseProgram(fallback_shader_program);
image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture");
if (image_texture_location < 0) {
- LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform.";
+ LOG(ERROR) << "Shader doesn't contain the 'image_texture' uniform.";
return false;
}
fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen");
if (fullscreen_location < 0) {
- LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform.";
+ LOG(ERROR) << "Shader doesn't contain the 'fullscreen' uniform.";
return false;
}
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index a5833369a17..115b05e3911 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -439,10 +439,10 @@ class Device {
{
return 0;
}
- virtual void map_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/)
+ virtual void map_neighbor_tiles(Device * /*sub_device*/, RenderTileNeighbors & /*neighbors*/)
{
}
- virtual void unmap_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/)
+ virtual void unmap_neighbor_tiles(Device * /*sub_device*/, RenderTileNeighbors & /*neighbors*/)
{
}
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 8f68e66a1b4..ee3a3ddea64 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -182,6 +182,7 @@ class CPUDevice : public Device {
oidn::DeviceRef oidn_device;
oidn::FilterRef oidn_filter;
#endif
+ thread_spin_lock oidn_task_lock;
bool use_split_kernel;
@@ -948,12 +949,25 @@ class CPUDevice : public Device {
}
}
- void denoise_openimagedenoise(DeviceTask &task, RenderTile &rtile)
+ void denoise_openimagedenoise_buffer(DeviceTask &task,
+ float *buffer,
+ const size_t offset,
+ const size_t stride,
+ const size_t x,
+ const size_t y,
+ const size_t w,
+ const size_t h,
+ const float scale)
{
#ifdef WITH_OPENIMAGEDENOISE
assert(openimagedenoise_supported());
- /* Only one at a time, since OpenImageDenoise itself is multithreaded. */
+ /* Only one at a time, since OpenImageDenoise itself is multithreaded for full
+ * buffers, and for tiled rendering because creating multiple devices and filters
+ * is slow and memory hungry as well.
+ *
+ * TODO: optimize tiled rendering case, by batching together denoising of many
+ * tiles somehow? */
static thread_mutex mutex;
thread_scoped_lock lock(mutex);
@@ -964,54 +978,192 @@ class CPUDevice : public Device {
}
if (!oidn_filter) {
oidn_filter = oidn_device.newFilter("RT");
+ oidn_filter.set("hdr", true);
+ oidn_filter.set("srgb", false);
}
- /* Copy pixels from compute device to CPU (no-op for CPU device). */
- rtile.buffers->buffer.copy_from_device();
-
/* Set images with appropriate stride for our interleaved pass storage. */
- const struct {
+ struct {
const char *name;
- int offset;
- } passes[] = {{"color", task.pass_denoising_data + DENOISING_PASS_COLOR},
- {"normal", task.pass_denoising_data + DENOISING_PASS_NORMAL},
- {"albedo", task.pass_denoising_data + DENOISING_PASS_ALBEDO},
- {"output", 0},
+ const int offset;
+ const bool scale;
+ const bool use;
+ array<float> scaled_buffer;
+ } passes[] = {{"color", task.pass_denoising_data + DENOISING_PASS_COLOR, false, true},
+ {"albedo",
+ task.pass_denoising_data + DENOISING_PASS_ALBEDO,
+ true,
+ task.denoising.input_passes >= DENOISER_INPUT_RGB_ALBEDO},
+ {"normal",
+ task.pass_denoising_data + DENOISING_PASS_NORMAL,
+ true,
+ task.denoising.input_passes >= DENOISER_INPUT_RGB_ALBEDO_NORMAL},
+ {"output", 0, false, true},
{ NULL,
0 }};
for (int i = 0; passes[i].name; i++) {
- const int64_t offset = rtile.offset + rtile.x + rtile.y * rtile.stride;
- const int64_t buffer_offset = (offset * task.pass_stride + passes[i].offset) * sizeof(float);
- const int64_t pixel_stride = task.pass_stride * sizeof(float);
- const int64_t row_stride = rtile.stride * pixel_stride;
+ if (!passes[i].use) {
+ continue;
+ }
- oidn_filter.setImage(passes[i].name,
- (char *)rtile.buffer + buffer_offset,
- oidn::Format::Float3,
- rtile.w,
- rtile.h,
- 0,
- pixel_stride,
- row_stride);
+ const int64_t pixel_offset = offset + x + y * stride;
+ const int64_t buffer_offset = (pixel_offset * task.pass_stride + passes[i].offset);
+ const int64_t pixel_stride = task.pass_stride;
+ const int64_t row_stride = stride * pixel_stride;
+
+ if (passes[i].scale && scale != 1.0f) {
+ /* Normalize albedo and normal passes as they are scaled by the number of samples.
+ * For the color passes OIDN will perform auto-exposure making it unnecessary. */
+ array<float> &scaled_buffer = passes[i].scaled_buffer;
+ scaled_buffer.resize(w * h * 3);
+
+ for (int y = 0; y < h; y++) {
+ const float *pass_row = buffer + buffer_offset + y * row_stride;
+ float *scaled_row = scaled_buffer.data() + y * w * 3;
+
+ for (int x = 0; x < w; x++) {
+ scaled_row[x * 3 + 0] = pass_row[x * pixel_stride + 0] * scale;
+ scaled_row[x * 3 + 1] = pass_row[x * pixel_stride + 1] * scale;
+ scaled_row[x * 3 + 2] = pass_row[x * pixel_stride + 2] * scale;
+ }
+ }
+
+ oidn_filter.setImage(
+ passes[i].name, scaled_buffer.data(), oidn::Format::Float3, w, h, 0, 0, 0);
+ }
+ else {
+ oidn_filter.setImage(passes[i].name,
+ buffer + buffer_offset,
+ oidn::Format::Float3,
+ w,
+ h,
+ 0,
+ pixel_stride * sizeof(float),
+ row_stride * sizeof(float));
+ }
}
/* Execute filter. */
- oidn_filter.set("hdr", true);
- oidn_filter.set("srgb", false);
oidn_filter.commit();
oidn_filter.execute();
-
- /* todo: it may be possible to avoid this copy, but we have to ensure that
- * when other code copies data from the device it doesn't overwrite the
- * denoiser buffers. */
- rtile.buffers->buffer.copy_to_device();
#else
(void)task;
- (void)rtile;
+ (void)buffer;
+ (void)offset;
+ (void)stride;
+ (void)x;
+ (void)y;
+ (void)w;
+ (void)h;
+ (void)scale;
#endif
}
+ void denoise_openimagedenoise(DeviceTask &task, RenderTile &rtile)
+ {
+ if (task.type == DeviceTask::DENOISE_BUFFER) {
+ /* Copy pixels from compute device to CPU (no-op for CPU device). */
+ rtile.buffers->buffer.copy_from_device();
+
+ denoise_openimagedenoise_buffer(task,
+ (float *)rtile.buffer,
+ rtile.offset,
+ rtile.stride,
+ rtile.x,
+ rtile.y,
+ rtile.w,
+ rtile.h,
+ 1.0f / rtile.sample);
+
+ /* todo: it may be possible to avoid this copy, but we have to ensure that
+ * when other code copies data from the device it doesn't overwrite the
+ * denoiser buffers. */
+ rtile.buffers->buffer.copy_to_device();
+ }
+ else {
+ /* Per-tile denoising. */
+ rtile.sample = rtile.start_sample + rtile.num_samples;
+ const float scale = 1.0f / rtile.sample;
+ const float invscale = rtile.sample;
+ const size_t pass_stride = task.pass_stride;
+
+ /* Map neighboring tiles into one buffer for denoising. */
+ RenderTileNeighbors neighbors(rtile);
+ task.map_neighbor_tiles(neighbors, this);
+ RenderTile &center_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
+ rtile = center_tile;
+
+ /* Calculate size of the tile to denoise (including overlap). The overlap
+ * size was chosen empirically. OpenImageDenoise specifies an overlap size
+ * of 128 but this is significantly bigger than typical tile size. */
+ const int4 rect = rect_clip(rect_expand(center_tile.bounds(), 64), neighbors.bounds());
+ const int2 rect_size = make_int2(rect.z - rect.x, rect.w - rect.y);
+
+ /* Adjacent tiles are in separate memory regions, copy into single buffer. */
+ array<float> merged(rect_size.x * rect_size.y * task.pass_stride);
+
+ for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
+ RenderTile &ntile = neighbors.tiles[i];
+ if (!ntile.buffer) {
+ continue;
+ }
+
+ const int xmin = max(ntile.x, rect.x);
+ const int ymin = max(ntile.y, rect.y);
+ const int xmax = min(ntile.x + ntile.w, rect.z);
+ const int ymax = min(ntile.y + ntile.h, rect.w);
+
+ const size_t tile_offset = ntile.offset + xmin + ymin * ntile.stride;
+ const float *tile_buffer = (float *)ntile.buffer + tile_offset * pass_stride;
+
+ const size_t merged_stride = rect_size.x;
+ const size_t merged_offset = (xmin - rect.x) + (ymin - rect.y) * merged_stride;
+ float *merged_buffer = merged.data() + merged_offset * pass_stride;
+
+ for (int y = ymin; y < ymax; y++) {
+ for (int x = 0; x < pass_stride * (xmax - xmin); x++) {
+ merged_buffer[x] = tile_buffer[x] * scale;
+ }
+ tile_buffer += ntile.stride * pass_stride;
+ merged_buffer += merged_stride * pass_stride;
+ }
+ }
+
+ /* Denoise */
+ denoise_openimagedenoise_buffer(
+ task, merged.data(), 0, rect_size.x, 0, 0, rect_size.x, rect_size.y, 1.0f);
+
+ /* Copy back result from merged buffer. */
+ RenderTile &ntile = neighbors.target;
+ if (ntile.buffer) {
+ const int xmin = max(ntile.x, rect.x);
+ const int ymin = max(ntile.y, rect.y);
+ const int xmax = min(ntile.x + ntile.w, rect.z);
+ const int ymax = min(ntile.y + ntile.h, rect.w);
+
+ const size_t tile_offset = ntile.offset + xmin + ymin * ntile.stride;
+ float *tile_buffer = (float *)ntile.buffer + tile_offset * pass_stride;
+
+ const size_t merged_stride = rect_size.x;
+ const size_t merged_offset = (xmin - rect.x) + (ymin - rect.y) * merged_stride;
+ const float *merged_buffer = merged.data() + merged_offset * pass_stride;
+
+ for (int y = ymin; y < ymax; y++) {
+ for (int x = 0; x < pass_stride * (xmax - xmin); x += pass_stride) {
+ tile_buffer[x + 0] = merged_buffer[x + 0] * invscale;
+ tile_buffer[x + 1] = merged_buffer[x + 1] * invscale;
+ tile_buffer[x + 2] = merged_buffer[x + 2] * invscale;
+ }
+ tile_buffer += ntile.stride * pass_stride;
+ merged_buffer += merged_stride * pass_stride;
+ }
+ }
+
+ task.unmap_neighbor_tiles(neighbors, this);
+ }
+ }
+
void denoise_nlm(DenoisingTask &denoising, RenderTile &tile)
{
ProfilingHelper profiling(denoising.profiler, PROFILING_DENOISING);
@@ -1040,7 +1192,7 @@ class CPUDevice : public Device {
denoising.render_buffer.samples = tile.sample;
denoising.buffer.gpu_temporary_mem = false;
- denoising.run_denoising(&tile);
+ denoising.run_denoising(tile);
}
void thread_render(DeviceTask &task)
@@ -1070,10 +1222,23 @@ class CPUDevice : public Device {
}
}
+ /* NLM denoiser. */
DenoisingTask *denoising = NULL;
+ /* OpenImageDenoise: we can only denoise with one thread at a time, so to
+ * avoid waiting with mutex locks in the denoiser, we let only a single
+ * thread acquire denoising tiles. */
+ uint tile_types = task.tile_types;
+ bool hold_denoise_lock = false;
+ if ((tile_types & RenderTile::DENOISE) && task.denoising.type == DENOISER_OPENIMAGEDENOISE) {
+ if (!oidn_task_lock.try_lock()) {
+ tile_types &= ~RenderTile::DENOISE;
+ hold_denoise_lock = true;
+ }
+ }
+
RenderTile tile;
- while (task.acquire_tile(this, tile, task.tile_types)) {
+ while (task.acquire_tile(this, tile, tile_types)) {
if (tile.task == RenderTile::PATH_TRACE) {
if (use_split_kernel) {
device_only_memory<uchar> void_buffer(this, "void_buffer");
@@ -1108,6 +1273,10 @@ class CPUDevice : public Device {
}
}
+ if (hold_denoise_lock) {
+ oidn_task_lock.unlock();
+ }
+
profiler.remove_state(&kg->profiler);
thread_kernel_globals_free((KernelGlobals *)kgbuffer.device_pointer);
diff --git a/intern/cycles/device/device_denoising.cpp b/intern/cycles/device/device_denoising.cpp
index 89de80a5bcd..38c42d15cab 100644
--- a/intern/cycles/device/device_denoising.cpp
+++ b/intern/cycles/device/device_denoising.cpp
@@ -71,29 +71,30 @@ DenoisingTask::~DenoisingTask()
tile_info_mem.free();
}
-void DenoisingTask::set_render_buffer(RenderTile *rtiles)
+void DenoisingTask::set_render_buffer(RenderTileNeighbors &neighbors)
{
- for (int i = 0; i < 9; i++) {
- tile_info->offsets[i] = rtiles[i].offset;
- tile_info->strides[i] = rtiles[i].stride;
- tile_info->buffers[i] = rtiles[i].buffer;
+ for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
+ RenderTile &rtile = neighbors.tiles[i];
+ tile_info->offsets[i] = rtile.offset;
+ tile_info->strides[i] = rtile.stride;
+ tile_info->buffers[i] = rtile.buffer;
}
- tile_info->x[0] = rtiles[3].x;
- tile_info->x[1] = rtiles[4].x;
- tile_info->x[2] = rtiles[5].x;
- tile_info->x[3] = rtiles[5].x + rtiles[5].w;
- tile_info->y[0] = rtiles[1].y;
- tile_info->y[1] = rtiles[4].y;
- tile_info->y[2] = rtiles[7].y;
- tile_info->y[3] = rtiles[7].y + rtiles[7].h;
-
- target_buffer.offset = rtiles[9].offset;
- target_buffer.stride = rtiles[9].stride;
- target_buffer.ptr = rtiles[9].buffer;
-
- if (do_prefilter && rtiles[9].buffers) {
+ tile_info->x[0] = neighbors.tiles[3].x;
+ tile_info->x[1] = neighbors.tiles[4].x;
+ tile_info->x[2] = neighbors.tiles[5].x;
+ tile_info->x[3] = neighbors.tiles[5].x + neighbors.tiles[5].w;
+ tile_info->y[0] = neighbors.tiles[1].y;
+ tile_info->y[1] = neighbors.tiles[4].y;
+ tile_info->y[2] = neighbors.tiles[7].y;
+ tile_info->y[3] = neighbors.tiles[7].y + neighbors.tiles[7].h;
+
+ target_buffer.offset = neighbors.target.offset;
+ target_buffer.stride = neighbors.target.stride;
+ target_buffer.ptr = neighbors.target.buffer;
+
+ if (do_prefilter && neighbors.target.buffers) {
target_buffer.denoising_output_offset =
- rtiles[9].buffers->params.get_denoising_prefiltered_offset();
+ neighbors.target.buffers->params.get_denoising_prefiltered_offset();
}
else {
target_buffer.denoising_output_offset = 0;
@@ -320,12 +321,11 @@ void DenoisingTask::reconstruct()
functions.solve(target_buffer.ptr);
}
-void DenoisingTask::run_denoising(RenderTile *tile)
+void DenoisingTask::run_denoising(RenderTile &tile)
{
- RenderTile rtiles[10];
- rtiles[4] = *tile;
- functions.map_neighbor_tiles(rtiles);
- set_render_buffer(rtiles);
+ RenderTileNeighbors neighbors(tile);
+ functions.map_neighbor_tiles(neighbors);
+ set_render_buffer(neighbors);
setup_denoising_buffer();
@@ -347,7 +347,7 @@ void DenoisingTask::run_denoising(RenderTile *tile)
write_buffer();
}
- functions.unmap_neighbor_tiles(rtiles);
+ functions.unmap_neighbor_tiles(neighbors);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_denoising.h b/intern/cycles/device/device_denoising.h
index 4c122e981eb..2c0dc23b44a 100644
--- a/intern/cycles/device/device_denoising.h
+++ b/intern/cycles/device/device_denoising.h
@@ -102,8 +102,8 @@ class DenoisingTask {
device_ptr output_ptr)>
detect_outliers;
function<bool(int out_offset, device_ptr frop_ptr, device_ptr buffer_ptr)> write_feature;
- function<void(RenderTile *rtiles)> map_neighbor_tiles;
- function<void(RenderTile *rtiles)> unmap_neighbor_tiles;
+ function<void(RenderTileNeighbors &neighbors)> map_neighbor_tiles;
+ function<void(RenderTileNeighbors &neighbors)> unmap_neighbor_tiles;
} functions;
/* Stores state of the current Reconstruction operation,
@@ -154,7 +154,7 @@ class DenoisingTask {
DenoisingTask(Device *device, const DeviceTask &task);
~DenoisingTask();
- void run_denoising(RenderTile *tile);
+ void run_denoising(RenderTile &tile);
struct DenoiseBuffers {
int pass_stride;
@@ -179,7 +179,7 @@ class DenoisingTask {
protected:
Device *device;
- void set_render_buffer(RenderTile *rtiles);
+ void set_render_buffer(RenderTileNeighbors &neighbors);
void setup_denoising_buffer();
void prefilter_shadowing();
void prefilter_features();
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index fd14bbdccc5..9ea8782d0f0 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -177,8 +177,11 @@ class MultiDevice : public Device {
return false;
if (requested_features.use_denoising) {
+ /* Only need denoising feature, everything else is unused. */
+ DeviceRequestedFeatures denoising_features;
+ denoising_features.use_denoising = true;
foreach (SubDevice &sub, denoising_devices)
- if (!sub.device->load_kernels(requested_features))
+ if (!sub.device->load_kernels(denoising_features))
return false;
}
@@ -581,20 +584,22 @@ class MultiDevice : public Device {
return -1;
}
- void map_neighbor_tiles(Device *sub_device, RenderTile *tiles)
+ void map_neighbor_tiles(Device *sub_device, RenderTileNeighbors &neighbors)
{
- for (int i = 0; i < 9; i++) {
- if (!tiles[i].buffers) {
+ for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
+ RenderTile &tile = neighbors.tiles[i];
+
+ if (!tile.buffers) {
continue;
}
- device_vector<float> &mem = tiles[i].buffers->buffer;
- tiles[i].buffer = mem.device_pointer;
+ device_vector<float> &mem = tile.buffers->buffer;
+ tile.buffer = mem.device_pointer;
if (mem.device == this && matching_rendering_and_denoising_devices) {
/* Skip unnecessary copies in viewport mode (buffer covers the
* whole image), but still need to fix up the tile device pointer. */
- map_tile(sub_device, tiles[i]);
+ map_tile(sub_device, tile);
continue;
}
@@ -607,15 +612,15 @@ class MultiDevice : public Device {
* also required for the case where a CPU thread is denoising
* a tile rendered on the GPU. In that case we have to avoid
* overwriting the buffer being de-noised by the CPU thread. */
- if (!tiles[i].buffers->map_neighbor_copied) {
- tiles[i].buffers->map_neighbor_copied = true;
+ if (!tile.buffers->map_neighbor_copied) {
+ tile.buffers->map_neighbor_copied = true;
mem.copy_from_device();
}
if (mem.device == this) {
/* Can re-use memory if tile is already allocated on the sub device. */
- map_tile(sub_device, tiles[i]);
- mem.swap_device(sub_device, mem.device_size, tiles[i].buffer);
+ map_tile(sub_device, tile);
+ mem.swap_device(sub_device, mem.device_size, tile.buffer);
}
else {
mem.swap_device(sub_device, 0, 0);
@@ -623,40 +628,42 @@ class MultiDevice : public Device {
mem.copy_to_device();
- tiles[i].buffer = mem.device_pointer;
- tiles[i].device_size = mem.device_size;
+ tile.buffer = mem.device_pointer;
+ tile.device_size = mem.device_size;
mem.restore_device();
}
}
}
- void unmap_neighbor_tiles(Device *sub_device, RenderTile *tiles)
+ void unmap_neighbor_tiles(Device *sub_device, RenderTileNeighbors &neighbors)
{
- device_vector<float> &mem = tiles[9].buffers->buffer;
+ RenderTile &target_tile = neighbors.target;
+ device_vector<float> &mem = target_tile.buffers->buffer;
if (mem.device == this && matching_rendering_and_denoising_devices) {
return;
}
/* Copy denoised result back to the host. */
- mem.swap_device(sub_device, tiles[9].device_size, tiles[9].buffer);
+ mem.swap_device(sub_device, target_tile.device_size, target_tile.buffer);
mem.copy_from_device();
mem.restore_device();
/* Copy denoised result to the original device. */
mem.copy_to_device();
- for (int i = 0; i < 9; i++) {
- if (!tiles[i].buffers) {
+ for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
+ RenderTile &tile = neighbors.tiles[i];
+ if (!tile.buffers) {
continue;
}
- device_vector<float> &mem = tiles[i].buffers->buffer;
+ device_vector<float> &mem = tile.buffers->buffer;
if (mem.device != sub_device && mem.device != this) {
/* Free up memory again if it was allocated for the copy above. */
- mem.swap_device(sub_device, tiles[i].device_size, tiles[i].buffer);
+ mem.swap_device(sub_device, tile.device_size, tile.buffer);
sub_device->mem_free(mem);
mem.restore_device();
}
diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp
index ececca3df53..1cc45983565 100644
--- a/intern/cycles/device/device_optix.cpp
+++ b/intern/cycles/device/device_optix.cpp
@@ -131,8 +131,12 @@ class OptiXDevice : public CUDADevice {
PG_RGEN,
PG_MISS,
PG_HITD, // Default hit group
- PG_HITL, // __BVH_LOCAL__ hit group
PG_HITS, // __SHADOW_RECORD_ALL__ hit group
+ PG_HITL, // __BVH_LOCAL__ hit group (only used for triangles)
+# if OPTIX_ABI_VERSION >= 36
+ PG_HITD_MOTION,
+ PG_HITS_MOTION,
+# endif
# ifdef WITH_CYCLES_DEBUG
PG_EXCP,
# endif
@@ -177,6 +181,7 @@ class OptiXDevice : public CUDADevice {
OptixDeviceContext context = NULL;
OptixModule optix_module = NULL; // All necessary OptiX kernels are in one module
+ OptixModule builtin_modules[2] = {};
OptixPipeline pipelines[NUM_PIPELINES] = {};
bool motion_blur = false;
@@ -264,6 +269,9 @@ class OptiXDevice : public CUDADevice {
// Unload modules
if (optix_module != NULL)
optixModuleDestroy(optix_module);
+ for (unsigned int i = 0; i < 2; ++i)
+ if (builtin_modules[i] != NULL)
+ optixModuleDestroy(builtin_modules[i]);
for (unsigned int i = 0; i < NUM_PIPELINES; ++i)
if (pipelines[i] != NULL)
optixPipelineDestroy(pipelines[i]);
@@ -338,6 +346,12 @@ class OptiXDevice : public CUDADevice {
optixModuleDestroy(optix_module);
optix_module = NULL;
}
+ for (unsigned int i = 0; i < 2; ++i) {
+ if (builtin_modules[i] != NULL) {
+ optixModuleDestroy(builtin_modules[i]);
+ builtin_modules[i] = NULL;
+ }
+ }
for (unsigned int i = 0; i < NUM_PIPELINES; ++i) {
if (pipelines[i] != NULL) {
optixPipelineDestroy(pipelines[i]);
@@ -369,6 +383,18 @@ class OptiXDevice : public CUDADevice {
# endif
pipeline_options.pipelineLaunchParamsVariableName = "__params"; // See kernel_globals.h
+# if OPTIX_ABI_VERSION >= 36
+ pipeline_options.usesPrimitiveTypeFlags = OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE;
+ if (requested_features.use_hair) {
+ if (DebugFlags().optix.curves_api && requested_features.use_hair_thick) {
+ pipeline_options.usesPrimitiveTypeFlags |= OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_CUBIC_BSPLINE;
+ }
+ else {
+ pipeline_options.usesPrimitiveTypeFlags |= OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM;
+ }
+ }
+# endif
+
// Keep track of whether motion blur is enabled, so to enable/disable motion in BVH builds
// This is necessary since objects may be reported to have motion if the Vector pass is
// active, but may still need to be rendered without motion blur if that isn't active as well
@@ -442,6 +468,34 @@ class OptiXDevice : public CUDADevice {
group_descs[PG_HITD].hitgroup.entryFunctionNameIS = "__intersection__curve_ribbon";
group_descs[PG_HITS].hitgroup.entryFunctionNameIS = "__intersection__curve_ribbon";
}
+
+# if OPTIX_ABI_VERSION >= 36
+ if (DebugFlags().optix.curves_api && requested_features.use_hair_thick) {
+ OptixBuiltinISOptions builtin_options;
+ builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE;
+ builtin_options.usesMotionBlur = false;
+
+ check_result_optix_ret(optixBuiltinISModuleGet(
+ context, &module_options, &pipeline_options, &builtin_options, &builtin_modules[0]));
+
+ group_descs[PG_HITD].hitgroup.moduleIS = builtin_modules[0];
+ group_descs[PG_HITD].hitgroup.entryFunctionNameIS = nullptr;
+ group_descs[PG_HITS].hitgroup.moduleIS = builtin_modules[0];
+ group_descs[PG_HITS].hitgroup.entryFunctionNameIS = nullptr;
+
+ if (motion_blur) {
+ builtin_options.usesMotionBlur = true;
+
+ check_result_optix_ret(optixBuiltinISModuleGet(
+ context, &module_options, &pipeline_options, &builtin_options, &builtin_modules[1]));
+
+ group_descs[PG_HITD_MOTION] = group_descs[PG_HITD];
+ group_descs[PG_HITD_MOTION].hitgroup.moduleIS = builtin_modules[1];
+ group_descs[PG_HITS_MOTION] = group_descs[PG_HITS];
+ group_descs[PG_HITS_MOTION].hitgroup.moduleIS = builtin_modules[1];
+ }
+ }
+# endif
}
if (requested_features.use_subsurface || requested_features.use_shader_raytrace) {
@@ -493,8 +547,14 @@ class OptiXDevice : public CUDADevice {
unsigned int trace_css = stack_size[PG_HITD].cssCH;
// This is based on the maximum of closest-hit and any-hit/intersection programs
trace_css = std::max(trace_css, stack_size[PG_HITD].cssIS + stack_size[PG_HITD].cssAH);
- trace_css = std::max(trace_css, stack_size[PG_HITL].cssIS + stack_size[PG_HITL].cssAH);
trace_css = std::max(trace_css, stack_size[PG_HITS].cssIS + stack_size[PG_HITS].cssAH);
+ trace_css = std::max(trace_css, stack_size[PG_HITL].cssIS + stack_size[PG_HITL].cssAH);
+# if OPTIX_ABI_VERSION >= 36
+ trace_css = std::max(trace_css,
+ stack_size[PG_HITD_MOTION].cssIS + stack_size[PG_HITD_MOTION].cssAH);
+ trace_css = std::max(trace_css,
+ stack_size[PG_HITS_MOTION].cssIS + stack_size[PG_HITS_MOTION].cssAH);
+# endif
OptixPipelineLinkOptions link_options;
link_options.maxTraceDepth = 1;
@@ -503,17 +563,23 @@ class OptiXDevice : public CUDADevice {
# else
link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_LINEINFO;
# endif
- link_options.overrideUsesMotionBlur = pipeline_options.usesMotionBlur;
+# if OPTIX_ABI_VERSION < 24
+ link_options.overrideUsesMotionBlur = motion_blur;
+# endif
{ // Create path tracing pipeline
OptixProgramGroup pipeline_groups[] = {
- groups[PG_RGEN],
- groups[PG_MISS],
- groups[PG_HITD],
- groups[PG_HITS],
- groups[PG_HITL],
+ groups[PG_RGEN],
+ groups[PG_MISS],
+ groups[PG_HITD],
+ groups[PG_HITS],
+ groups[PG_HITL],
+# if OPTIX_ABI_VERSION >= 36
+ groups[PG_HITD_MOTION],
+ groups[PG_HITS_MOTION],
+# endif
# ifdef WITH_CYCLES_DEBUG
- groups[PG_EXCP],
+ groups[PG_EXCP],
# endif
};
check_result_optix_ret(
@@ -530,8 +596,8 @@ class OptiXDevice : public CUDADevice {
const unsigned int css = stack_size[PG_RGEN].cssRG + link_options.maxTraceDepth * trace_css;
// Set stack size depending on pipeline options
- check_result_optix_ret(optixPipelineSetStackSize(
- pipelines[PIP_PATH_TRACE], 0, 0, css, (pipeline_options.usesMotionBlur ? 3 : 2)));
+ check_result_optix_ret(
+ optixPipelineSetStackSize(pipelines[PIP_PATH_TRACE], 0, 0, css, (motion_blur ? 3 : 2)));
}
// Only need to create shader evaluation pipeline if one of these features is used:
@@ -541,15 +607,19 @@ class OptiXDevice : public CUDADevice {
if (use_shader_eval_pipeline) { // Create shader evaluation pipeline
OptixProgramGroup pipeline_groups[] = {
- groups[PG_BAKE],
- groups[PG_DISP],
- groups[PG_BACK],
- groups[PG_MISS],
- groups[PG_HITD],
- groups[PG_HITS],
- groups[PG_HITL],
+ groups[PG_BAKE],
+ groups[PG_DISP],
+ groups[PG_BACK],
+ groups[PG_MISS],
+ groups[PG_HITD],
+ groups[PG_HITS],
+ groups[PG_HITL],
+# if OPTIX_ABI_VERSION >= 36
+ groups[PG_HITD_MOTION],
+ groups[PG_HITS_MOTION],
+# endif
# ifdef WITH_CYCLES_DEBUG
- groups[PG_EXCP],
+ groups[PG_EXCP],
# endif
};
check_result_optix_ret(
@@ -672,7 +742,11 @@ class OptiXDevice : public CUDADevice {
sbt_params.missRecordCount = 1;
sbt_params.hitgroupRecordBase = sbt_data.device_pointer + PG_HITD * sizeof(SbtRecord);
sbt_params.hitgroupRecordStrideInBytes = sizeof(SbtRecord);
- sbt_params.hitgroupRecordCount = 3; // PG_HITD, PG_HITL, PG_HITS
+# if OPTIX_ABI_VERSION >= 36
+ sbt_params.hitgroupRecordCount = 5; // PG_HITD(_MOTION), PG_HITS(_MOTION), PG_HITL
+# else
+ sbt_params.hitgroupRecordCount = 3; // PG_HITD, PG_HITS, PG_HITL
+# endif
// Launch the ray generation program
check_result_optix(optixLaunch(pipelines[PIP_PATH_TRACE],
@@ -727,19 +801,18 @@ class OptiXDevice : public CUDADevice {
// 0 1 2
// 3 4 5
// 6 7 8 9
- RenderTile rtiles[10];
- rtiles[4] = rtile;
- task.map_neighbor_tiles(rtiles, this);
- rtile = rtiles[4]; // Tile may have been modified by mapping code
+ RenderTileNeighbors neighbors(rtile);
+ task.map_neighbor_tiles(neighbors, this);
+ RenderTile &center_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
+ RenderTile &target_tile = neighbors.target;
+ rtile = center_tile; // Tile may have been modified by mapping code
// Calculate size of the tile to denoise (including overlap)
- int4 rect = make_int4(
- rtiles[4].x, rtiles[4].y, rtiles[4].x + rtiles[4].w, rtiles[4].y + rtiles[4].h);
+ int4 rect = center_tile.bounds();
// Overlap between tiles has to be at least 64 pixels
// TODO(pmours): Query this value from OptiX
rect = rect_expand(rect, 64);
- int4 clip_rect = make_int4(
- rtiles[3].x, rtiles[1].y, rtiles[5].x + rtiles[5].w, rtiles[7].y + rtiles[7].h);
+ int4 clip_rect = neighbors.bounds();
rect = rect_clip(rect, clip_rect);
int2 rect_size = make_int2(rect.z - rect.x, rect.w - rect.y);
int2 overlap_offset = make_int2(rtile.x - rect.x, rtile.y - rect.y);
@@ -760,14 +833,14 @@ class OptiXDevice : public CUDADevice {
device_only_memory<float> input(this, "denoiser input");
device_vector<TileInfo> tile_info_mem(this, "denoiser tile info", MEM_READ_WRITE);
- if ((!rtiles[0].buffer || rtiles[0].buffer == rtile.buffer) &&
- (!rtiles[1].buffer || rtiles[1].buffer == rtile.buffer) &&
- (!rtiles[2].buffer || rtiles[2].buffer == rtile.buffer) &&
- (!rtiles[3].buffer || rtiles[3].buffer == rtile.buffer) &&
- (!rtiles[5].buffer || rtiles[5].buffer == rtile.buffer) &&
- (!rtiles[6].buffer || rtiles[6].buffer == rtile.buffer) &&
- (!rtiles[7].buffer || rtiles[7].buffer == rtile.buffer) &&
- (!rtiles[8].buffer || rtiles[8].buffer == rtile.buffer)) {
+ bool contiguous_memory = true;
+ for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
+ if (neighbors.tiles[i].buffer && neighbors.tiles[i].buffer != rtile.buffer) {
+ contiguous_memory = false;
+ }
+ }
+
+ if (contiguous_memory) {
// Tiles are in continous memory, so can just subtract overlap offset
input_ptr -= (overlap_offset.x + overlap_offset.y * rtile.stride) * pixel_stride;
// Stride covers the whole width of the image and not just a single tile
@@ -782,19 +855,19 @@ class OptiXDevice : public CUDADevice {
input_stride *= rect_size.x;
TileInfo *tile_info = tile_info_mem.alloc(1);
- for (int i = 0; i < 9; i++) {
- tile_info->offsets[i] = rtiles[i].offset;
- tile_info->strides[i] = rtiles[i].stride;
- tile_info->buffers[i] = rtiles[i].buffer;
+ for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
+ tile_info->offsets[i] = neighbors.tiles[i].offset;
+ tile_info->strides[i] = neighbors.tiles[i].stride;
+ tile_info->buffers[i] = neighbors.tiles[i].buffer;
}
- tile_info->x[0] = rtiles[3].x;
- tile_info->x[1] = rtiles[4].x;
- tile_info->x[2] = rtiles[5].x;
- tile_info->x[3] = rtiles[5].x + rtiles[5].w;
- tile_info->y[0] = rtiles[1].y;
- tile_info->y[1] = rtiles[4].y;
- tile_info->y[2] = rtiles[7].y;
- tile_info->y[3] = rtiles[7].y + rtiles[7].h;
+ tile_info->x[0] = neighbors.tiles[3].x;
+ tile_info->x[1] = neighbors.tiles[4].x;
+ tile_info->x[2] = neighbors.tiles[5].x;
+ tile_info->x[3] = neighbors.tiles[5].x + neighbors.tiles[5].w;
+ tile_info->y[0] = neighbors.tiles[1].y;
+ tile_info->y[1] = neighbors.tiles[4].y;
+ tile_info->y[2] = neighbors.tiles[7].y;
+ tile_info->y[3] = neighbors.tiles[7].y + neighbors.tiles[7].h;
tile_info_mem.copy_to_device();
void *args[] = {
@@ -804,7 +877,7 @@ class OptiXDevice : public CUDADevice {
# if OPTIX_DENOISER_NO_PIXEL_STRIDE
device_only_memory<float> input_rgb(this, "denoiser input rgb");
- input_rgb.alloc_to_device(rect_size.x * rect_size.y * 3 * task.denoising.optix_input_passes);
+ input_rgb.alloc_to_device(rect_size.x * rect_size.y * 3 * task.denoising.input_passes);
void *input_args[] = {&input_rgb.device_pointer,
&input_ptr,
@@ -813,7 +886,7 @@ class OptiXDevice : public CUDADevice {
&input_stride,
&task.pass_stride,
const_cast<int *>(pass_offset),
- &task.denoising.optix_input_passes,
+ &task.denoising.input_passes,
&rtile.sample};
launch_filter_kernel(
"kernel_cuda_filter_convert_to_rgb", rect_size.x, rect_size.y, input_args);
@@ -824,7 +897,7 @@ class OptiXDevice : public CUDADevice {
# endif
const bool recreate_denoiser = (denoiser == NULL) ||
- (task.denoising.optix_input_passes != denoiser_input_passes);
+ (task.denoising.input_passes != denoiser_input_passes);
if (recreate_denoiser) {
// Destroy existing handle before creating new one
if (denoiser != NULL) {
@@ -833,23 +906,29 @@ class OptiXDevice : public CUDADevice {
// Create OptiX denoiser handle on demand when it is first used
OptixDenoiserOptions denoiser_options;
- assert(task.denoising.optix_input_passes >= 1 && task.denoising.optix_input_passes <= 3);
+ assert(task.denoising.input_passes >= 1 && task.denoising.input_passes <= 3);
denoiser_options.inputKind = static_cast<OptixDenoiserInputKind>(
- OPTIX_DENOISER_INPUT_RGB + (task.denoising.optix_input_passes - 1));
+ OPTIX_DENOISER_INPUT_RGB + (task.denoising.input_passes - 1));
+# if OPTIX_ABI_VERSION < 28
denoiser_options.pixelFormat = OPTIX_PIXEL_FORMAT_FLOAT3;
+# endif
check_result_optix_ret(optixDenoiserCreate(context, &denoiser_options, &denoiser));
check_result_optix_ret(
optixDenoiserSetModel(denoiser, OPTIX_DENOISER_MODEL_KIND_HDR, NULL, 0));
// OptiX denoiser handle was created with the requested number of input passes
- denoiser_input_passes = task.denoising.optix_input_passes;
+ denoiser_input_passes = task.denoising.input_passes;
}
OptixDenoiserSizes sizes = {};
check_result_optix_ret(
optixDenoiserComputeMemoryResources(denoiser, rect_size.x, rect_size.y, &sizes));
+# if OPTIX_ABI_VERSION < 28
const size_t scratch_size = sizes.recommendedScratchSizeInBytes;
+# else
+ const size_t scratch_size = sizes.withOverlapScratchSizeInBytes;
+# endif
const size_t scratch_offset = sizes.stateSizeInBytes;
// Allocate denoiser state if tile size has changed since last setup
@@ -897,10 +976,10 @@ class OptiXDevice : public CUDADevice {
int2 output_offset = overlap_offset;
overlap_offset = make_int2(0, 0); // Not supported by denoiser API, so apply manually
# else
- output_layers[0].data = rtiles[9].buffer + pixel_offset;
- output_layers[0].width = rtiles[9].w;
- output_layers[0].height = rtiles[9].h;
- output_layers[0].rowStrideInBytes = rtiles[9].stride * pixel_stride;
+ output_layers[0].data = target_tile.buffer + pixel_offset;
+ output_layers[0].width = target_tile.w;
+ output_layers[0].height = target_tile.h;
+ output_layers[0].rowStrideInBytes = target_tile.stride * pixel_stride;
output_layers[0].pixelStrideInBytes = pixel_stride;
# endif
output_layers[0].format = OPTIX_PIXEL_FORMAT_FLOAT3;
@@ -913,7 +992,7 @@ class OptiXDevice : public CUDADevice {
denoiser_state.device_pointer,
scratch_offset,
input_layers,
- task.denoising.optix_input_passes,
+ task.denoising.input_passes,
overlap_offset.x,
overlap_offset.y,
output_layers,
@@ -922,26 +1001,26 @@ class OptiXDevice : public CUDADevice {
# if OPTIX_DENOISER_NO_PIXEL_STRIDE
void *output_args[] = {&input_ptr,
- &rtiles[9].buffer,
+ &target_tile.buffer,
&output_offset.x,
&output_offset.y,
&rect_size.x,
&rect_size.y,
- &rtiles[9].x,
- &rtiles[9].y,
- &rtiles[9].w,
- &rtiles[9].h,
- &rtiles[9].offset,
- &rtiles[9].stride,
+ &target_tile.x,
+ &target_tile.y,
+ &target_tile.w,
+ &target_tile.h,
+ &target_tile.offset,
+ &target_tile.stride,
&task.pass_stride,
&rtile.sample};
launch_filter_kernel(
- "kernel_cuda_filter_convert_from_rgb", rtiles[9].w, rtiles[9].h, output_args);
+ "kernel_cuda_filter_convert_from_rgb", target_tile.w, target_tile.h, output_args);
# endif
check_result_cuda_ret(cuStreamSynchronize(0));
- task.unmap_neighbor_tiles(rtiles, this);
+ task.unmap_neighbor_tiles(neighbors, this);
}
else {
// Run CUDA denoising kernels
@@ -993,7 +1072,11 @@ class OptiXDevice : public CUDADevice {
sbt_params.missRecordCount = 1;
sbt_params.hitgroupRecordBase = sbt_data.device_pointer + PG_HITD * sizeof(SbtRecord);
sbt_params.hitgroupRecordStrideInBytes = sizeof(SbtRecord);
- sbt_params.hitgroupRecordCount = 3; // PG_HITD, PG_HITL, PG_HITS
+# if OPTIX_ABI_VERSION >= 36
+ sbt_params.hitgroupRecordCount = 5; // PG_HITD(_MOTION), PG_HITS(_MOTION), PG_HITL
+# else
+ sbt_params.hitgroupRecordCount = 3; // PG_HITD, PG_HITS, PG_HITL
+# endif
check_result_optix(optixLaunch(pipelines[PIP_SHADER_EVAL],
cuda_stream[thread_index],
@@ -1070,7 +1153,7 @@ class OptiXDevice : public CUDADevice {
&build_input,
1,
temp_mem.device_pointer,
- temp_mem.device_size,
+ sizes.tempSizeInBytes,
out_data,
sizes.outputSizeInBytes,
&out_handle,
@@ -1142,7 +1225,6 @@ class OptiXDevice : public CUDADevice {
continue;
}
- const size_t num_curves = hair->num_curves();
const size_t num_segments = hair->num_segments();
size_t num_motion_steps = 1;
@@ -1152,7 +1234,18 @@ class OptiXDevice : public CUDADevice {
}
device_vector<OptixAabb> aabb_data(this, "temp_aabb_data", MEM_READ_ONLY);
- aabb_data.alloc(num_segments * num_motion_steps);
+# if OPTIX_ABI_VERSION >= 36
+ device_vector<int> index_data(this, "temp_index_data", MEM_READ_ONLY);
+ device_vector<float4> vertex_data(this, "temp_vertex_data", MEM_READ_ONLY);
+ // Four control points for each curve segment
+ const size_t num_vertices = num_segments * 4;
+ if (DebugFlags().optix.curves_api && hair->curve_shape == CURVE_THICK) {
+ index_data.alloc(num_segments);
+ vertex_data.alloc(num_vertices * num_motion_steps);
+ }
+ else
+# endif
+ aabb_data.alloc(num_segments * num_motion_steps);
// Get AABBs for each motion step
for (size_t step = 0; step < num_motion_steps; ++step) {
@@ -1165,44 +1258,127 @@ class OptiXDevice : public CUDADevice {
keys = motion_keys->data_float3() + attr_offset * hair->curve_keys.size();
}
- size_t i = step * num_segments;
- for (size_t j = 0; j < num_curves; ++j) {
- const Hair::Curve c = hair->get_curve(j);
-
- for (size_t k = 0; k < c.num_segments(); ++i, ++k) {
- BoundBox bounds = BoundBox::empty;
- c.bounds_grow(k, keys, hair->curve_radius.data(), bounds);
-
- aabb_data[i].minX = bounds.min.x;
- aabb_data[i].minY = bounds.min.y;
- aabb_data[i].minZ = bounds.min.z;
- aabb_data[i].maxX = bounds.max.x;
- aabb_data[i].maxY = bounds.max.y;
- aabb_data[i].maxZ = bounds.max.z;
+ for (size_t j = 0, i = 0; j < hair->num_curves(); ++j) {
+ const Hair::Curve curve = hair->get_curve(j);
+
+ for (int segment = 0; segment < curve.num_segments(); ++segment, ++i) {
+# if OPTIX_ABI_VERSION >= 36
+ if (DebugFlags().optix.curves_api && hair->curve_shape == CURVE_THICK) {
+ int k0 = curve.first_key + segment;
+ int k1 = k0 + 1;
+ int ka = max(k0 - 1, curve.first_key);
+ int kb = min(k1 + 1, curve.first_key + curve.num_keys - 1);
+
+ const float4 px = make_float4(keys[ka].x, keys[k0].x, keys[k1].x, keys[kb].x);
+ const float4 py = make_float4(keys[ka].y, keys[k0].y, keys[k1].y, keys[kb].y);
+ const float4 pz = make_float4(keys[ka].z, keys[k0].z, keys[k1].z, keys[kb].z);
+ const float4 pw = make_float4(hair->curve_radius[ka],
+ hair->curve_radius[k0],
+ hair->curve_radius[k1],
+ hair->curve_radius[kb]);
+
+ // Convert Catmull-Rom data to Bezier spline
+ static const float4 cr2bsp0 = make_float4(+7, -4, +5, -2) / 6.f;
+ static const float4 cr2bsp1 = make_float4(-2, 11, -4, +1) / 6.f;
+ static const float4 cr2bsp2 = make_float4(+1, -4, 11, -2) / 6.f;
+ static const float4 cr2bsp3 = make_float4(-2, +5, -4, +7) / 6.f;
+
+ index_data[i] = i * 4;
+ float4 *const v = vertex_data.data() + step * num_vertices + index_data[i];
+ v[0] = make_float4(
+ dot(cr2bsp0, px), dot(cr2bsp0, py), dot(cr2bsp0, pz), dot(cr2bsp0, pw));
+ v[1] = make_float4(
+ dot(cr2bsp1, px), dot(cr2bsp1, py), dot(cr2bsp1, pz), dot(cr2bsp1, pw));
+ v[2] = make_float4(
+ dot(cr2bsp2, px), dot(cr2bsp2, py), dot(cr2bsp2, pz), dot(cr2bsp2, pw));
+ v[3] = make_float4(
+ dot(cr2bsp3, px), dot(cr2bsp3, py), dot(cr2bsp3, pz), dot(cr2bsp3, pw));
+ }
+ else
+# endif
+ {
+ BoundBox bounds = BoundBox::empty;
+ curve.bounds_grow(segment, keys, hair->curve_radius.data(), bounds);
+
+ const size_t index = step * num_segments + i;
+ aabb_data[index].minX = bounds.min.x;
+ aabb_data[index].minY = bounds.min.y;
+ aabb_data[index].minZ = bounds.min.z;
+ aabb_data[index].maxX = bounds.max.x;
+ aabb_data[index].maxY = bounds.max.y;
+ aabb_data[index].maxZ = bounds.max.z;
+ }
}
}
}
// Upload AABB data to GPU
aabb_data.copy_to_device();
+# if OPTIX_ABI_VERSION >= 36
+ index_data.copy_to_device();
+ vertex_data.copy_to_device();
+# endif
vector<device_ptr> aabb_ptrs;
aabb_ptrs.reserve(num_motion_steps);
+# if OPTIX_ABI_VERSION >= 36
+ vector<device_ptr> width_ptrs;
+ vector<device_ptr> vertex_ptrs;
+ width_ptrs.reserve(num_motion_steps);
+ vertex_ptrs.reserve(num_motion_steps);
+# endif
for (size_t step = 0; step < num_motion_steps; ++step) {
aabb_ptrs.push_back(aabb_data.device_pointer + step * num_segments * sizeof(OptixAabb));
+# if OPTIX_ABI_VERSION >= 36
+ const device_ptr base_ptr = vertex_data.device_pointer +
+ step * num_vertices * sizeof(float4);
+ width_ptrs.push_back(base_ptr + 3 * sizeof(float)); // Offset by vertex size
+ vertex_ptrs.push_back(base_ptr);
+# endif
}
- // Disable visibility test anyhit program, since it is already checked during intersection
- // Those trace calls that require anyhit can force it with OPTIX_RAY_FLAG_ENFORCE_ANYHIT
- unsigned int build_flags = OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT;
+ // Force a single any-hit call, so shadow record-all behavior works correctly
+ unsigned int build_flags = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;
OptixBuildInput build_input = {};
- build_input.type = OPTIX_BUILD_INPUT_TYPE_CUSTOM_PRIMITIVES;
- build_input.aabbArray.aabbBuffers = (CUdeviceptr *)aabb_ptrs.data();
- build_input.aabbArray.numPrimitives = num_segments;
- build_input.aabbArray.strideInBytes = sizeof(OptixAabb);
- build_input.aabbArray.flags = &build_flags;
- build_input.aabbArray.numSbtRecords = 1;
- build_input.aabbArray.primitiveIndexOffset = hair->optix_prim_offset;
+# if OPTIX_ABI_VERSION >= 36
+ if (DebugFlags().optix.curves_api && hair->curve_shape == CURVE_THICK) {
+ build_input.type = OPTIX_BUILD_INPUT_TYPE_CURVES;
+ build_input.curveArray.curveType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE;
+ build_input.curveArray.numPrimitives = num_segments;
+ build_input.curveArray.vertexBuffers = (CUdeviceptr *)vertex_ptrs.data();
+ build_input.curveArray.numVertices = num_vertices;
+ build_input.curveArray.vertexStrideInBytes = sizeof(float4);
+ build_input.curveArray.widthBuffers = (CUdeviceptr *)width_ptrs.data();
+ build_input.curveArray.widthStrideInBytes = sizeof(float4);
+ build_input.curveArray.indexBuffer = (CUdeviceptr)index_data.device_pointer;
+ build_input.curveArray.indexStrideInBytes = sizeof(int);
+ build_input.curveArray.flag = build_flags;
+ build_input.curveArray.primitiveIndexOffset = hair->optix_prim_offset;
+ }
+ else
+# endif
+ {
+ // Disable visibility test any-hit program, since it is already checked during
+ // intersection. Those trace calls that require anyhit can force it with a ray flag.
+ build_flags |= OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT;
+
+ build_input.type = OPTIX_BUILD_INPUT_TYPE_CUSTOM_PRIMITIVES;
+# if OPTIX_ABI_VERSION < 23
+ build_input.aabbArray.aabbBuffers = (CUdeviceptr *)aabb_ptrs.data();
+ build_input.aabbArray.numPrimitives = num_segments;
+ build_input.aabbArray.strideInBytes = sizeof(OptixAabb);
+ build_input.aabbArray.flags = &build_flags;
+ build_input.aabbArray.numSbtRecords = 1;
+ build_input.aabbArray.primitiveIndexOffset = hair->optix_prim_offset;
+# else
+ build_input.customPrimitiveArray.aabbBuffers = (CUdeviceptr *)aabb_ptrs.data();
+ build_input.customPrimitiveArray.numPrimitives = num_segments;
+ build_input.customPrimitiveArray.strideInBytes = sizeof(OptixAabb);
+ build_input.customPrimitiveArray.flags = &build_flags;
+ build_input.customPrimitiveArray.numSbtRecords = 1;
+ build_input.customPrimitiveArray.primitiveIndexOffset = hair->optix_prim_offset;
+# endif
+ }
// Allocate memory for new BLAS and build it
OptixTraversableHandle handle;
@@ -1257,8 +1433,8 @@ class OptiXDevice : public CUDADevice {
vertex_ptrs.push_back(vertex_data.device_pointer + num_verts * step * sizeof(float3));
}
- // No special build flags for triangle primitives
- unsigned int build_flags = OPTIX_GEOMETRY_FLAG_NONE;
+ // Force a single any-hit call, so shadow record-all behavior works correctly
+ unsigned int build_flags = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;
OptixBuildInput build_input = {};
build_input.type = OPTIX_BUILD_INPUT_TYPE_TRIANGLES;
build_input.triangleArray.vertexBuffers = (CUdeviceptr *)vertex_ptrs.data();
@@ -1324,9 +1500,26 @@ class OptiXDevice : public CUDADevice {
// Set user instance ID to object index
instance.instanceId = ob->get_device_index();
- // Volumes have a special bit set in the visibility mask so a trace can mask only volumes
- // See 'scene_intersect_volume' in bvh.h
- instance.visibilityMask = (ob->geometry->has_volume ? 3 : 1);
+ // Have to have at least one bit in the mask, or else instance would always be culled
+ instance.visibilityMask = 1;
+
+ if (ob->geometry->has_volume) {
+ // Volumes have a special bit set in the visibility mask so a trace can mask only volumes
+ instance.visibilityMask |= 2;
+ }
+
+ if (ob->geometry->type == Geometry::HAIR) {
+ // Same applies to curves (so they can be skipped in local trace calls)
+ instance.visibilityMask |= 4;
+
+# if OPTIX_ABI_VERSION >= 36
+ if (motion_blur && ob->geometry->has_motion_blur() && DebugFlags().optix.curves_api &&
+ static_cast<const Hair *>(ob->geometry)->curve_shape == CURVE_THICK) {
+ // Select between motion blur and non-motion blur built-in intersection module
+ instance.sbtOffset = PG_HITD_MOTION - PG_HITD;
+ }
+# endif
+ }
// Insert motion traversable if object has motion
if (motion_blur && ob->use_motion()) {
diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h
index 600973b8100..fd380788282 100644
--- a/intern/cycles/device/device_task.h
+++ b/intern/cycles/device/device_task.h
@@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN
class Device;
class RenderBuffers;
class RenderTile;
+class RenderTileNeighbors;
class Tile;
enum DenoiserType {
@@ -41,6 +42,14 @@ enum DenoiserType {
DENOISER_ALL = ~0,
};
+enum DenoiserInput {
+ DENOISER_INPUT_RGB = 1,
+ DENOISER_INPUT_RGB_ALBEDO = 2,
+ DENOISER_INPUT_RGB_ALBEDO_NORMAL = 3,
+
+ DENOISER_INPUT_NUM,
+};
+
typedef int DenoiserTypeMask;
class DenoiseParams {
@@ -72,10 +81,10 @@ class DenoiseParams {
/* Clamp the input to the range of +-1e8. Should be enough for any legitimate data. */
bool clamp_input;
- /** Optix Denoiser **/
+ /** OIDN/Optix Denoiser **/
- /* Passes handed over to the OptiX denoiser (default to color + albedo). */
- int optix_input_passes;
+ /* Passes handed over to the OIDN/OptiX denoiser (default to color + albedo). */
+ DenoiserInput input_passes;
DenoiseParams()
{
@@ -91,7 +100,7 @@ class DenoiseParams {
neighbor_frames = 2;
clamp_input = true;
- optix_input_passes = 2;
+ input_passes = DENOISER_INPUT_RGB_ALBEDO_NORMAL;
start_sample = 0;
}
@@ -150,8 +159,8 @@ class DeviceTask {
function<void(RenderTile &)> update_tile_sample;
function<void(RenderTile &)> release_tile;
function<bool()> get_cancel;
- function<void(RenderTile *, Device *)> map_neighbor_tiles;
- function<void(RenderTile *, Device *)> unmap_neighbor_tiles;
+ function<void(RenderTileNeighbors &, Device *)> map_neighbor_tiles;
+ function<void(RenderTileNeighbors &, Device *)> unmap_neighbor_tiles;
uint tile_types;
DenoiseParams denoising;
diff --git a/intern/cycles/device/opencl/device_opencl_impl.cpp b/intern/cycles/device/opencl/device_opencl_impl.cpp
index 8c94815b193..e851749949d 100644
--- a/intern/cycles/device/opencl/device_opencl_impl.cpp
+++ b/intern/cycles/device/opencl/device_opencl_impl.cpp
@@ -1850,7 +1850,7 @@ void OpenCLDevice::denoise(RenderTile &rtile, DenoisingTask &denoising)
denoising.render_buffer.samples = rtile.sample;
denoising.buffer.gpu_temporary_mem = true;
- denoising.run_denoising(&rtile);
+ denoising.run_denoising(rtile);
}
void OpenCLDevice::shader(DeviceTask &task)
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 7cc0d32d521..db146226dc7 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -539,7 +539,7 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
${SRC_UTIL_HEADERS}
COMMAND ${CUBIN_CC_ENV}
"$<TARGET_FILE:cycles_cubin_cc>"
- -target 30
+ -target 50
-ptx
-i ${CMAKE_CURRENT_SOURCE_DIR}/${input}
${cuda_flags}
@@ -563,7 +563,7 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
COMMAND
${CUDA_NVCC_EXECUTABLE}
--ptx
- -arch=sm_30
+ -arch=sm_50
${cuda_flags}
${input}
WORKING_DIRECTORY
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index 80b58f46329..3049f243ae9 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -172,11 +172,11 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
0.0f,
ray->t,
ray->time,
- 0xFF,
+ 0xF,
OPTIX_RAY_FLAG_NONE,
+ 0, // SBT offset for PG_HITD
0,
0,
- 0, // SBT offset for PG_HITD
p0,
p1,
p2,
@@ -264,12 +264,13 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg,
0.0f,
ray->t,
ray->time,
+ // Skip curves
+ 0x3,
// Need to always call into __anyhit__kernel_optix_local_hit
- 0xFF,
OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
- 1,
+ 2, // SBT offset for PG_HITL
+ 0,
0,
- 0, // SBT offset for PG_HITL
p0,
p1,
p2,
@@ -374,12 +375,12 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
0.0f,
ray->t,
ray->time,
+ 0xF,
// Need to always call into __anyhit__kernel_optix_shadow_all_hit
- 0xFF,
OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
- 2,
+ 1, // SBT offset for PG_HITS
+ 0,
0,
- 0, // SBT offset for PG_HITS
p0,
p1,
*num_hits,
@@ -458,12 +459,12 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg,
0.0f,
ray->t,
ray->time,
- // Visibility mask set to only intersect objects with volumes
- 0x02,
+ // Skip everything but volumes
+ 0x2,
OPTIX_RAY_FLAG_NONE,
+ 0, // SBT offset for PG_HITD
0,
0,
- 0, // SBT offset for PG_HITD
p0,
p1,
p2,
diff --git a/intern/cycles/kernel/geom/geom_curve_intersect.h b/intern/cycles/kernel/geom/geom_curve_intersect.h
index c04dbee52cc..06d2c016f5b 100644
--- a/intern/cycles/kernel/geom/geom_curve_intersect.h
+++ b/intern/cycles/kernel/geom/geom_curve_intersect.h
@@ -734,7 +734,6 @@ ccl_device_inline void curve_shader_setup(KernelGlobals *kg,
}
sd->u = isect->u;
- sd->v = isect->v;
P = P + D * t;
@@ -750,6 +749,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals *kg,
sd->N = normalize(sine * bitangent - cosine * normalize(cross(tangent, bitangent)));
sd->Ng = -D;
+ sd->v = isect->v;
# if 0
/* This approximates the position and geometric normal of a thick curve too,
@@ -764,8 +764,11 @@ ccl_device_inline void curve_shader_setup(KernelGlobals *kg,
* This could be optimized by recording the normal in the intersection,
* however for Optix this would go beyond the size of the payload. */
const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, isect->u));
- sd->Ng = normalize(P - P_inside);
- sd->N = sd->Ng;
+ const float3 Ng = normalize(P - P_inside);
+
+ sd->N = Ng;
+ sd->Ng = Ng;
+ sd->v = 0.0f;
}
# ifdef __DPDU__
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 445cf9eb44b..efe46d5b0dd 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -379,7 +379,7 @@ ccl_device_inline void camera_sample(KernelGlobals *kg,
const int shutter_table_offset = kernel_data.cam.shutter_table_offset;
ray->time = lookup_table_read(kg, time, shutter_table_offset, SHUTTER_TABLE_SIZE);
/* TODO(sergey): Currently single rolling shutter effect type only
- * where scan-lines are acquired from top to bottom and whole scanline
+ * where scan-lines are acquired from top to bottom and whole scan-line
* is acquired at once (no delay in acquisition happens between pixels
* of single scan-line).
*
diff --git a/intern/cycles/kernel/kernel_light_background.h b/intern/cycles/kernel/kernel_light_background.h
index 30e336f0f80..5fa25069fcd 100644
--- a/intern/cycles/kernel/kernel_light_background.h
+++ b/intern/cycles/kernel/kernel_light_background.h
@@ -445,4 +445,4 @@ ccl_device float background_light_pdf(KernelGlobals *kg, float3 P, float3 direct
#endif
-CCL_NAMESPACE_END \ No newline at end of file
+CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index ba46d84d158..c332d5ad3ec 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -284,19 +284,11 @@ ccl_device_forceinline bool kernel_path_shader_apply(KernelGlobals *kg,
#ifdef __HOLDOUT__
if (((sd->flag & SD_HOLDOUT) || (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
(state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
+ const float3 holdout_weight = shader_holdout_apply(kg, sd);
if (kernel_data.background.transparent) {
- float3 holdout_weight;
- if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
- holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
- }
- else {
- holdout_weight = shader_holdout_eval(kg, sd);
- }
- /* any throughput is ok, should all be identical here */
L->transparent += average(holdout_weight * throughput);
}
-
- if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
+ if (isequal_float3(holdout_weight, make_float3(1.0f, 1.0f, 1.0f))) {
return false;
}
}
@@ -673,11 +665,9 @@ ccl_device void kernel_path_trace(
kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &ray);
-# ifndef __KERNEL_OPTIX__
if (ray.t == 0.0f) {
return;
}
-# endif
/* Initialize state. */
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 3d9f787f267..e461e1642b6 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -1017,15 +1017,36 @@ ccl_device float3 shader_emissive_eval(ShaderData *sd)
/* Holdout */
-ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
+ccl_device float3 shader_holdout_apply(KernelGlobals *kg, ShaderData *sd)
{
float3 weight = make_float3(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ /* For objects marked as holdout, preserve transparency and remove all other
+ * closures, replacing them with a holdout weight. */
+ if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
+ if ((sd->flag & SD_TRANSPARENT) && !(sd->flag & SD_HAS_ONLY_VOLUME)) {
+ weight = make_float3(1.0f, 1.0f, 1.0f) - sd->closure_transparent_extinction;
- if (CLOSURE_IS_HOLDOUT(sc->type))
- weight += sc->weight;
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (!CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
+ sc->type = NBUILTIN_CLOSURES;
+ }
+ }
+
+ sd->flag &= ~(SD_CLOSURE_FLAGS - (SD_TRANSPARENT | SD_BSDF));
+ }
+ else {
+ weight = make_float3(1.0f, 1.0f, 1.0f);
+ }
+ }
+ else {
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_HOLDOUT(sc->type)) {
+ weight += sc->weight;
+ }
+ }
}
return weight;
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
index 89fcb0ae60f..9ab374d1fba 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
@@ -77,7 +77,7 @@ ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg,
return make_float4(f, f, f, 1.0f);
}
/* Byte */
-#ifdef cl_khr_fp16
+#ifdef __KERNEL_CL_KHR_FP16__
/* half and half4 are optional in OpenCL */
else if (texture_type == IMAGE_DATA_TYPE_HALF) {
float f = tex_fetch(half, info, offset);
diff --git a/intern/cycles/kernel/kernels/optix/kernel_optix.cu b/intern/cycles/kernel/kernels/optix/kernel_optix.cu
index c730d952ed4..3b166e59dfd 100644
--- a/intern/cycles/kernel/kernels/optix/kernel_optix.cu
+++ b/intern/cycles/kernel/kernels/optix/kernel_optix.cu
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+// clang-format off
#include "kernel/kernel_compat_optix.h"
#include "util/util_atomic.h"
#include "kernel/kernel_types.h"
@@ -23,6 +24,7 @@
#include "kernel/kernel_path.h"
#include "kernel/kernel_bake.h"
+// clang-format on
template<typename T> ccl_device_forceinline T *get_payload_ptr_0()
{
@@ -139,8 +141,8 @@ extern "C" __global__ void __anyhit__kernel_optix_local_hit()
}
else {
if (local_isect->num_hits && optixGetRayTmax() > local_isect->hits[0].t) {
- // Record closest intersection only (do not terminate ray here, since there is no guarantee
- // about distance ordering in anyhit)
+ // Record closest intersection only
+ // Do not terminate ray here, since there is no guarantee about distance ordering in any-hit
return optixIgnoreIntersection();
}
@@ -153,15 +155,9 @@ extern "C" __global__ void __anyhit__kernel_optix_local_hit()
isect->object = get_object_id();
isect->type = kernel_tex_fetch(__prim_type, isect->prim);
- if (optixIsTriangleHit()) {
- const float2 barycentrics = optixGetTriangleBarycentrics();
- isect->u = 1.0f - barycentrics.y - barycentrics.x;
- isect->v = barycentrics.x;
- }
- else {
- isect->u = __uint_as_float(optixGetAttribute_0());
- isect->v = __uint_as_float(optixGetAttribute_1());
- }
+ const float2 barycentrics = optixGetTriangleBarycentrics();
+ isect->u = 1.0f - barycentrics.y - barycentrics.x;
+ isect->v = barycentrics.x;
// Record geometric normal
const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim);
@@ -198,10 +194,18 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
isect->u = 1.0f - barycentrics.y - barycentrics.x;
isect->v = barycentrics.x;
}
+# ifdef __HAIR__
else {
- isect->u = __uint_as_float(optixGetAttribute_0());
+ const float u = __uint_as_float(optixGetAttribute_0());
+ isect->u = u;
isect->v = __uint_as_float(optixGetAttribute_1());
+
+ // Filter out curve endcaps
+ if (u == 0.0f || u == 1.0f) {
+ return optixIgnoreIntersection();
+ }
}
+# endif
# ifdef __TRANSPARENT_SHADOWS__
// Detect if this surface has a shader with transparent shadows
@@ -213,7 +217,6 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
# ifdef __TRANSPARENT_SHADOWS__
}
- // TODO(pmours): Do we need REQUIRE_UNIQUE_ANYHIT for this to work?
optixSetPayload_2(optixGetPayload_2() + 1); // num_hits++
// Continue tracing
@@ -227,13 +230,25 @@ extern "C" __global__ void __anyhit__kernel_optix_visibility_test()
uint visibility = optixGetPayload_4();
#ifdef __VISIBILITY_FLAG__
const uint prim = optixGetPrimitiveIndex();
- if ((kernel_tex_fetch(__prim_visibility, prim) & visibility) == 0)
+ if ((kernel_tex_fetch(__prim_visibility, prim) & visibility) == 0) {
return optixIgnoreIntersection();
+ }
+#endif
+
+#ifdef __HAIR__
+ if (!optixIsTriangleHit()) {
+ // Filter out curve endcaps
+ const float u = __uint_as_float(optixGetAttribute_0());
+ if (u == 0.0f || u == 1.0f) {
+ return optixIgnoreIntersection();
+ }
+ }
#endif
// Shadow ray early termination
- if (visibility & PATH_RAY_SHADOW_OPAQUE)
+ if (visibility & PATH_RAY_SHADOW_OPAQUE) {
return optixTerminateRay();
+ }
}
extern "C" __global__ void __closesthit__kernel_optix_hit()
@@ -250,7 +265,7 @@ extern "C" __global__ void __closesthit__kernel_optix_hit()
optixSetPayload_2(__float_as_uint(barycentrics.x));
}
else {
- optixSetPayload_1(optixGetAttribute_0());
+ optixSetPayload_1(optixGetAttribute_0()); // Same as 'optixGetCurveParameter()'
optixSetPayload_2(optixGetAttribute_1());
}
}
@@ -286,7 +301,6 @@ ccl_device_inline void optix_intersection_curve(const uint prim, const uint type
__float_as_int(isect.u), // Attribute_0
__float_as_int(isect.v)); // Attribute_1
}
-
}
extern "C" __global__ void __intersection__curve_ribbon()
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index 08bc8f85120..a12e7a9dc17 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -122,12 +122,18 @@ vector geographical_to_direction(float lat, float lon)
return vector(cos(lat) * cos(lon), cos(lat) * sin(lon), sin(lat));
}
-color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
+float precise_angle(vector a, vector b)
+{
+ return 2.0 * atan2(length(a - b), length(a + b));
+}
+
+color sky_radiance_nishita(vector dir, float nishita_data[10], string filename)
{
/* definitions */
float sun_elevation = nishita_data[6];
float sun_rotation = nishita_data[7];
float angular_diameter = nishita_data[8];
+ float sun_intensity = nishita_data[9];
int sun_disc = angular_diameter > 0;
float alpha = 1.0;
color xyz;
@@ -138,13 +144,13 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
if (dir[2] >= 0.0) {
/* definitions */
vector sun_dir = geographical_to_direction(sun_elevation, sun_rotation + M_PI_2);
- float sun_dir_angle = acos(dot(dir, sun_dir));
+ float sun_dir_angle = precise_angle(dir, sun_dir);
float half_angular = angular_diameter / 2.0;
float dir_elevation = M_PI_2 - direction[0];
/* if ray inside sun disc render it, otherwise render sky */
if (sun_dir_angle < half_angular && sun_disc == 1) {
- /* get 3 pixels data */
+ /* get 2 pixels data */
color pixel_bottom = color(nishita_data[0], nishita_data[1], nishita_data[2]);
color pixel_top = color(nishita_data[3], nishita_data[4], nishita_data[5]);
float y;
@@ -153,13 +159,13 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
if (sun_elevation - half_angular > 0.0) {
if ((sun_elevation + half_angular) > 0.0) {
y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5;
- xyz = mix(pixel_bottom, pixel_top, y);
+ xyz = mix(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
else {
if (sun_elevation + half_angular > 0.0) {
y = dir_elevation / (sun_elevation + half_angular);
- xyz = mix(pixel_bottom, pixel_top, y);
+ xyz = mix(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
/* limb darkening, coefficient is 0.6f */
@@ -171,7 +177,8 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
else {
/* sky interpolation */
float x = (direction[1] + M_PI + sun_rotation) / M_2PI;
- float y = 1.0 - (dir_elevation / M_PI_2);
+ /* more pixels toward horizon compensation */
+ float y = 1.0 - sqrt(dir_elevation / M_PI_2);
if (x > 1.0) {
x = x - 1.0;
}
@@ -197,23 +204,24 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
mul;
}
}
- /* convert to RGB and adjust strength */
- return xyz_to_rgb(xyz[0], xyz[1], xyz[2]) * 120000.0;
+ /* convert to RGB */
+ return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
}
-shader node_sky_texture(int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- vector Vector = P,
- string type = "hosek_wilkie",
- float theta = 0.0,
- float phi = 0.0,
- string filename = "",
- color radiance = color(0.0, 0.0, 0.0),
- float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float nishita_data[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- output color Color = color(0.0, 0.0, 0.0))
+shader node_sky_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ vector Vector = P,
+ string type = "hosek_wilkie",
+ float theta = 0.0,
+ float phi = 0.0,
+ string filename = "",
+ color radiance = color(0.0, 0.0, 0.0),
+ float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float nishita_data[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ output color Color = color(0.0, 0.0, 0.0))
{
vector p = Vector;
diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h
index e877bd9a5c8..f824184c1d4 100644
--- a/intern/cycles/kernel/svm/svm_sky.h
+++ b/intern/cycles/kernel/svm/svm_sky.h
@@ -136,6 +136,7 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
float sun_elevation = nishita_data[6];
float sun_rotation = nishita_data[7];
float angular_diameter = nishita_data[8];
+ float sun_intensity = nishita_data[9];
bool sun_disc = (angular_diameter > 0.0f);
float3 xyz;
/* convert dir to spherical coordinates */
@@ -145,13 +146,13 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
if (dir.z >= 0.0f) {
/* definitions */
float3 sun_dir = geographical_to_direction(sun_elevation, sun_rotation + M_PI_2_F);
- float sun_dir_angle = acos(dot(dir, sun_dir));
+ float sun_dir_angle = precise_angle(dir, sun_dir);
float half_angular = angular_diameter / 2.0f;
float dir_elevation = M_PI_2_F - direction.x;
/* if ray inside sun disc render it, otherwise render sky */
if (sun_disc && sun_dir_angle < half_angular) {
- /* get 3 pixels data */
+ /* get 2 pixels data */
float3 pixel_bottom = make_float3(nishita_data[0], nishita_data[1], nishita_data[2]);
float3 pixel_top = make_float3(nishita_data[3], nishita_data[4], nishita_data[5]);
float y;
@@ -160,13 +161,13 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
if (sun_elevation - half_angular > 0.0f) {
if (sun_elevation + half_angular > 0.0f) {
y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5f;
- xyz = interp(pixel_bottom, pixel_top, y);
+ xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
else {
if (sun_elevation + half_angular > 0.0f) {
y = dir_elevation / (sun_elevation + half_angular);
- xyz = interp(pixel_bottom, pixel_top, y);
+ xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
/* limb darkening, coefficient is 0.6f */
@@ -178,7 +179,8 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
else {
/* sky interpolation */
float x = (direction.y + M_PI_F + sun_rotation) / M_2PI_F;
- float y = dir_elevation / M_PI_2_F;
+ /* more pixels toward horizon compensation */
+ float y = safe_sqrtf(dir_elevation / M_PI_2_F);
if (x > 1.0f) {
x -= 1.0f;
}
@@ -203,8 +205,8 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
}
}
- /* convert to rgb and adjust strength */
- return xyz_to_rgb(kg, xyz) * 120000.0f;
+ /* convert to RGB */
+ return xyz_to_rgb(kg, xyz);
}
ccl_device void svm_node_tex_sky(
@@ -301,7 +303,7 @@ ccl_device void svm_node_tex_sky(
/* Nishita */
else {
/* Define variables */
- float nishita_data[9];
+ float nishita_data[10];
float4 data = read_node_float(kg, offset);
nishita_data[0] = data.x;
@@ -317,7 +319,8 @@ ccl_device void svm_node_tex_sky(
data = read_node_float(kg, offset);
nishita_data[8] = data.x;
- uint texture_id = __float_as_uint(data.y);
+ nishita_data[9] = data.y;
+ uint texture_id = __float_as_uint(data.z);
/* Compute Sky */
f = sky_radiance_nishita(kg, dir, nishita_data, texture_id);
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index e37a0407976..6a1335dc5dd 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -2,6 +2,7 @@
set(INC
..
../../glew-mx
+ ../../sky/include
)
set(INC_SYS
@@ -92,6 +93,7 @@ set(LIB
cycles_device
cycles_subd
cycles_util
+ bf_intern_sky
)
if(WITH_CYCLES_OSL)
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 975bae2239c..06b6094e6c9 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -52,7 +52,7 @@ class BufferParams {
/* passes */
vector<Pass> passes;
bool denoising_data_pass;
- /* If only some light path types should be denoised, an additional pass is needed. */
+ /* If only some light path types should be target, an additional pass is needed. */
bool denoising_clean_pass;
/* When we're prefiltering the passes during rendering, we need to keep both the
* original and the prefiltered data around because neighboring tiles might still
@@ -149,6 +149,50 @@ class RenderTile {
RenderBuffers *buffers;
RenderTile();
+
+ int4 bounds() const
+ {
+ return make_int4(x, /* xmin */
+ y, /* ymin */
+ x + w, /* xmax */
+ y + h); /* ymax */
+ }
+};
+
+/* Render Tile Neighbors
+ * Set of neighboring tiles used for denoising. Tile order:
+ * 0 1 2
+ * 3 4 5
+ * 6 7 8 */
+
+class RenderTileNeighbors {
+ public:
+ static const int SIZE = 9;
+ static const int CENTER = 4;
+
+ RenderTile tiles[SIZE];
+ RenderTile target;
+
+ RenderTileNeighbors(const RenderTile &center)
+ {
+ tiles[CENTER] = center;
+ }
+
+ int4 bounds() const
+ {
+ return make_int4(tiles[3].x, /* xmin */
+ tiles[1].y, /* ymin */
+ tiles[5].x + tiles[5].w, /* xmax */
+ tiles[7].y + tiles[7].h); /* ymax */
+ }
+
+ void set_bounds_from_center()
+ {
+ tiles[3].x = tiles[CENTER].x;
+ tiles[1].y = tiles[CENTER].y;
+ tiles[5].x = tiles[CENTER].x + tiles[CENTER].w;
+ tiles[7].y = tiles[CENTER].y + tiles[CENTER].h;
+ }
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 74953afae9d..bbc111cb798 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -26,6 +26,7 @@
#include "util/util_function.h"
#include "util/util_logging.h"
#include "util/util_math_cdf.h"
+#include "util/util_task.h"
#include "util/util_vector.h"
/* needed for calculating differentials */
@@ -496,20 +497,35 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen
if (!need_device_update && !need_flags_update) {
return;
}
- KernelCamera *kcam = &dscene->data.cam;
- BoundBox viewplane_boundbox = viewplane_bounds_get();
- for (size_t i = 0; i < scene->objects.size(); ++i) {
- Object *object = scene->objects[i];
- if (object->geometry->has_volume && viewplane_boundbox.intersects(object->bounds)) {
- /* TODO(sergey): Consider adding more grained check. */
- VLOG(1) << "Detected camera inside volume.";
- kcam->is_inside_volume = 1;
- break;
+
+ KernelIntegrator *kintegrator = &dscene->data.integrator;
+ if (kintegrator->use_volumes) {
+ KernelCamera *kcam = &dscene->data.cam;
+ 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->geometry->has_volume &&
+ viewplane_boundbox.intersects(object->bounds)) {
+ /* TODO(sergey): Consider adding more grained check. */
+ VLOG(1) << "Detected camera inside volume.";
+ kcam->is_inside_volume = 1;
+ parallel_for_cancel();
+ break;
+ }
+ }
+ });
+
+ if (!kcam->is_inside_volume) {
+ VLOG(1) << "Camera is outside of the volume.";
}
}
- if (!kcam->is_inside_volume) {
- VLOG(1) << "Camera is outside of the volume.";
- }
+
need_device_update = false;
need_flags_update = false;
}
diff --git a/intern/cycles/render/denoising.cpp b/intern/cycles/render/denoising.cpp
index 4055bc4773b..76408ca4849 100644
--- a/intern/cycles/render/denoising.cpp
+++ b/intern/cycles/render/denoising.cpp
@@ -271,42 +271,45 @@ bool DenoiseTask::acquire_tile(Device *device, Device *tile_device, RenderTile &
*
* However, since there is only one large memory, the denoised result has to be written to
* a different buffer to avoid having to copy an entire horizontal slice of the image. */
-void DenoiseTask::map_neighboring_tiles(RenderTile *tiles, Device *tile_device)
+void DenoiseTask::map_neighboring_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
{
+ RenderTile &center_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
+ RenderTile &target_tile = neighbors.target;
+
/* Fill tile information. */
- for (int i = 0; i < 9; i++) {
- if (i == 4) {
+ for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
+ if (i == RenderTileNeighbors::CENTER) {
continue;
}
+ RenderTile &tile = neighbors.tiles[i];
int dx = (i % 3) - 1;
int dy = (i / 3) - 1;
- tiles[i].x = clamp(tiles[4].x + dx * denoiser->tile_size.x, 0, image.width);
- tiles[i].w = clamp(tiles[4].x + (dx + 1) * denoiser->tile_size.x, 0, image.width) - tiles[i].x;
- tiles[i].y = clamp(tiles[4].y + dy * denoiser->tile_size.y, 0, image.height);
- tiles[i].h = clamp(tiles[4].y + (dy + 1) * denoiser->tile_size.y, 0, image.height) -
- tiles[i].y;
+ tile.x = clamp(center_tile.x + dx * denoiser->tile_size.x, 0, image.width);
+ tile.w = clamp(center_tile.x + (dx + 1) * denoiser->tile_size.x, 0, image.width) - tile.x;
+ tile.y = clamp(center_tile.y + dy * denoiser->tile_size.y, 0, image.height);
+ tile.h = clamp(center_tile.y + (dy + 1) * denoiser->tile_size.y, 0, image.height) - tile.y;
- tiles[i].buffer = tiles[4].buffer;
- tiles[i].offset = tiles[4].offset;
- tiles[i].stride = image.width;
+ tile.buffer = center_tile.buffer;
+ tile.offset = center_tile.offset;
+ tile.stride = image.width;
}
/* Allocate output buffer. */
device_vector<float> *output_mem = new device_vector<float>(
tile_device, "denoising_output", MEM_READ_WRITE);
- output_mem->alloc(OUTPUT_NUM_CHANNELS * tiles[4].w * tiles[4].h);
+ output_mem->alloc(OUTPUT_NUM_CHANNELS * center_tile.w * center_tile.h);
/* Fill output buffer with noisy image, assumed by kernel_filter_finalize
* when skipping denoising of some pixels. */
float *result = output_mem->data();
- float *in = &image.pixels[image.num_channels * (tiles[4].y * image.width + tiles[4].x)];
+ float *in = &image.pixels[image.num_channels * (center_tile.y * image.width + center_tile.x)];
const DenoiseImageLayer &layer = image.layers[current_layer];
const int *input_to_image_channel = layer.input_to_image_channel.data();
- for (int y = 0; y < tiles[4].h; y++) {
- for (int x = 0; x < tiles[4].w; x++, result += OUTPUT_NUM_CHANNELS) {
+ for (int y = 0; y < center_tile.h; y++) {
+ for (int x = 0; x < center_tile.w; x++, result += OUTPUT_NUM_CHANNELS) {
for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
result[i] = in[image.num_channels * x + input_to_image_channel[INPUT_NOISY_IMAGE + i]];
}
@@ -317,35 +320,38 @@ void DenoiseTask::map_neighboring_tiles(RenderTile *tiles, Device *tile_device)
output_mem->copy_to_device();
/* Fill output tile info. */
- tiles[9] = tiles[4];
- tiles[9].buffer = output_mem->device_pointer;
- tiles[9].stride = tiles[9].w;
- tiles[9].offset -= tiles[9].x + tiles[9].y * tiles[9].stride;
+ target_tile = center_tile;
+ target_tile.buffer = output_mem->device_pointer;
+ target_tile.stride = target_tile.w;
+ target_tile.offset -= target_tile.x + target_tile.y * target_tile.stride;
thread_scoped_lock output_lock(output_mutex);
- assert(output_pixels.count(tiles[4].tile_index) == 0);
- output_pixels[tiles[9].tile_index] = output_mem;
+ assert(output_pixels.count(center_tile.tile_index) == 0);
+ output_pixels[target_tile.tile_index] = output_mem;
}
-void DenoiseTask::unmap_neighboring_tiles(RenderTile *tiles)
+void DenoiseTask::unmap_neighboring_tiles(RenderTileNeighbors &neighbors)
{
+ RenderTile &center_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
+ RenderTile &target_tile = neighbors.target;
+
thread_scoped_lock output_lock(output_mutex);
- assert(output_pixels.count(tiles[4].tile_index) == 1);
- device_vector<float> *output_mem = output_pixels[tiles[9].tile_index];
- output_pixels.erase(tiles[4].tile_index);
+ assert(output_pixels.count(center_tile.tile_index) == 1);
+ device_vector<float> *output_mem = output_pixels[target_tile.tile_index];
+ output_pixels.erase(center_tile.tile_index);
output_lock.unlock();
/* Copy denoised pixels from device. */
- output_mem->copy_from_device(0, OUTPUT_NUM_CHANNELS * tiles[9].w, tiles[9].h);
+ output_mem->copy_from_device(0, OUTPUT_NUM_CHANNELS * target_tile.w, target_tile.h);
float *result = output_mem->data();
- float *out = &image.pixels[image.num_channels * (tiles[9].y * image.width + tiles[9].x)];
+ float *out = &image.pixels[image.num_channels * (target_tile.y * image.width + target_tile.x)];
const DenoiseImageLayer &layer = image.layers[current_layer];
const int *output_to_image_channel = layer.output_to_image_channel.data();
- for (int y = 0; y < tiles[9].h; y++) {
- for (int x = 0; x < tiles[9].w; x++, result += OUTPUT_NUM_CHANNELS) {
+ for (int y = 0; y < target_tile.h; y++) {
+ for (int x = 0; x < target_tile.w; x++, result += OUTPUT_NUM_CHANNELS) {
for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
out[image.num_channels * x + output_to_image_channel[i]] = result[i];
}
diff --git a/intern/cycles/render/denoising.h b/intern/cycles/render/denoising.h
index 5c6f913cb38..c1b4d0a5596 100644
--- a/intern/cycles/render/denoising.h
+++ b/intern/cycles/render/denoising.h
@@ -196,8 +196,8 @@ class DenoiseTask {
/* Device task callbacks */
bool acquire_tile(Device *device, Device *tile_device, RenderTile &tile);
- void map_neighboring_tiles(RenderTile *tiles, Device *tile_device);
- void unmap_neighboring_tiles(RenderTile *tiles);
+ void map_neighboring_tiles(RenderTileNeighbors &neighbors, Device *tile_device);
+ void unmap_neighboring_tiles(RenderTileNeighbors &neighbors);
void release_tile();
bool get_cancel();
};
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 436324b00ba..1b138455515 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -484,8 +484,8 @@ void ShaderGraph::remove_proxy_nodes()
vector<ShaderInput *> links(output->links);
foreach (ShaderInput *to, links) {
- /* remove any autoconvert nodes too if they lead to
- * sockets with an automatically set default value */
+ /* Remove any auto-convert nodes too if they lead to
+ * sockets with an automatically set default value. */
ShaderNode *tonode = to->parent;
if (tonode->special_type == SHADER_SPECIAL_TYPE_AUTOCONVERT) {
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 8d187814d64..691eb162dd0 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -362,9 +362,11 @@ ImageHandle ImageManager::add_image(const string &filename,
return handle;
}
-ImageHandle ImageManager::add_image(ImageLoader *loader, const ImageParams &params)
+ImageHandle ImageManager::add_image(ImageLoader *loader,
+ const ImageParams &params,
+ const bool builtin)
{
- const int slot = add_image_slot(loader, params, true);
+ const int slot = add_image_slot(loader, params, builtin);
ImageHandle handle;
handle.tile_slots.push_back(slot);
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index fffe7c5152a..47be0ee559a 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -169,7 +169,7 @@ class ImageManager {
ImageHandle add_image(const string &filename,
const ImageParams &params,
const vector<int> &tiles);
- ImageHandle add_image(ImageLoader *loader, const ImageParams &params);
+ ImageHandle add_image(ImageLoader *loader, const ImageParams &params, const bool builtin = true);
void device_update(Device *device, Scene *scene, Progress &progress);
void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress);
diff --git a/intern/cycles/render/image_sky.cpp b/intern/cycles/render/image_sky.cpp
index 442e1d7941f..0560907c63e 100644
--- a/intern/cycles/render/image_sky.cpp
+++ b/intern/cycles/render/image_sky.cpp
@@ -16,16 +16,20 @@
#include "render/image_sky.h"
+#include "sky_model.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)
+SkyLoader::SkyLoader(float sun_elevation,
+ float altitude,
+ float air_density,
+ float dust_density,
+ float ozone_density)
: sun_elevation(sun_elevation),
altitude(altitude),
air_density(air_density),
@@ -56,23 +60,22 @@ bool SkyLoader::load_pixels(const ImageMetaData &metadata,
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);
+ SKY_nishita_skymodel_precompute_texture(pixel_data,
+ metadata.channels,
+ r.begin(),
+ r.end(),
+ width,
+ height,
+ sun_elevation,
+ altitude,
+ air_density,
+ dust_density,
+ ozone_density);
});
return true;
diff --git a/intern/cycles/render/image_sky.h b/intern/cycles/render/image_sky.h
index cf4a3e8942c..686f4e5b885 100644
--- a/intern/cycles/render/image_sky.h
+++ b/intern/cycles/render/image_sky.h
@@ -21,14 +21,14 @@ CCL_NAMESPACE_BEGIN
class SkyLoader : public ImageLoader {
private:
float sun_elevation;
- int altitude;
+ float altitude;
float air_density;
float dust_density;
float ozone_density;
public:
SkyLoader(float sun_elevation,
- int altitude,
+ float altitude,
float air_density,
float dust_density,
float ozone_density);
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index c0615c6217b..183c02cb6b9 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -625,13 +625,19 @@ void LightManager::device_update_background(Device *device,
}
}
+ /* Determine sun direction from lat/long and texture mapping. */
float latitude = sky->sun_elevation;
float longitude = M_2PI_F - sky->sun_rotation + M_PI_2_F;
+ float3 sun_direction = make_float3(
+ cosf(latitude) * cosf(longitude), cosf(latitude) * sinf(longitude), sinf(latitude));
+ Transform sky_transform = transform_inverse(sky->tex_mapping.compute_transform());
+ sun_direction = transform_direction(&sky_transform, sun_direction);
+
+ /* Pack sun direction and size. */
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 = make_float4(
+ sun_direction.x, sun_direction.y, sun_direction.z, half_angle);
+
kbackground->sun_weight = 4.0f;
environment_res.x = max(environment_res.x, 512);
environment_res.y = max(environment_res.y, 256);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index ab392839e52..d5f65fb54db 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -27,9 +27,10 @@
#include "render/scene.h"
#include "render/svm.h"
+#include "sky_model.h"
+
#include "util/util_foreach.h"
#include "util/util_logging.h"
-#include "util/util_sky_model.h"
#include "util/util_transform.h"
#include "kernel/svm/svm_color_util.h"
@@ -631,7 +632,7 @@ typedef struct SunSky {
/* Parameter */
float radiance_x, radiance_y, radiance_z;
- float config_x[9], config_y[9], config_z[9], nishita_data[9];
+ float config_x[9], config_y[9], config_z[9], nishita_data[10];
} SunSky;
/* Preetham model */
@@ -726,8 +727,8 @@ static void sky_texture_precompute_hosek(SunSky *sunsky,
float solarElevation = M_PI_2_F - theta;
/* Initialize Sky Model */
- ArHosekSkyModelState *sky_state;
- sky_state = arhosek_xyz_skymodelstate_alloc_init(
+ SKY_ArHosekSkyModelState *sky_state;
+ sky_state = SKY_arhosek_xyz_skymodelstate_alloc_init(
(double)turbidity, (double)ground_albedo, (double)solarElevation);
/* Copy values from sky_state to SunSky */
@@ -741,25 +742,31 @@ static void sky_texture_precompute_hosek(SunSky *sunsky,
sunsky->radiance_z = (float)sky_state->radiances[2];
/* Free sky_state */
- arhosekskymodelstate_free(sky_state);
+ SKY_arhosekskymodelstate_free(sky_state);
}
/* Nishita improved */
static void sky_texture_precompute_nishita(SunSky *sunsky,
bool sun_disc,
float sun_size,
+ float sun_intensity,
float sun_elevation,
float sun_rotation,
- int altitude,
+ float 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);
+ SKY_nishita_skymodel_precompute_sun(
+ sun_elevation, sun_size, altitude, air_density, dust_density, pixel_bottom, pixel_top);
+ /* limit sun rotation between 0 and 360 degrees */
+ sun_rotation = fmodf(sun_rotation, M_2PI_F);
+ if (sun_rotation < 0.0f) {
+ sun_rotation += M_2PI_F;
+ }
+ sun_rotation = M_2PI_F - sun_rotation;
/* send data to svm_sky */
sunsky->nishita_data[0] = pixel_bottom[0];
sunsky->nishita_data[1] = pixel_bottom[1];
@@ -768,8 +775,9 @@ static void sky_texture_precompute_nishita(SunSky *sunsky,
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[7] = sun_rotation;
sunsky->nishita_data[8] = sun_disc ? sun_size : 0.0f;
+ sunsky->nishita_data[9] = sun_intensity;
}
NODE_DEFINE(SkyTextureNode)
@@ -789,9 +797,10 @@ NODE_DEFINE(SkyTextureNode)
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_intensity, "Sun Intensity", 1.0f);
+ SOCKET_FLOAT(sun_elevation, "Sun Elevation", 15.0f * M_PI_F / 180.0f);
SOCKET_FLOAT(sun_rotation, "Sun Rotation", 0.0f);
- SOCKET_INT(altitude, "Altitude", 0);
+ SOCKET_FLOAT(altitude, "Altitude", 1.0f);
SOCKET_FLOAT(air_density, "Air", 1.0f);
SOCKET_FLOAT(dust_density, "Dust", 1.0f);
SOCKET_FLOAT(ozone_density, "Ozone", 1.0f);
@@ -819,12 +828,17 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
else if (type == NODE_SKY_HOSEK)
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
else if (type == NODE_SKY_NISHITA) {
+ /* Clamp altitude to reasonable values.
+ * Below 1m causes numerical issues and above 60km is space. */
+ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
+
sky_texture_precompute_nishita(&sunsky,
sun_disc,
sun_size,
+ sun_intensity,
sun_elevation,
sun_rotation,
- altitude,
+ clamped_altitude,
air_density,
dust_density);
/* precomputed texture image parameters */
@@ -836,7 +850,7 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
/* precompute sky texture */
if (handle.empty()) {
SkyLoader *loader = new SkyLoader(
- sun_elevation, altitude, air_density, dust_density, ozone_density);
+ sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
handle = image_manager->add_image(loader, impar);
}
}
@@ -891,7 +905,10 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
__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);
+ compiler.add_node(__float_as_uint(sunsky.nishita_data[8]),
+ __float_as_uint(sunsky.nishita_data[9]),
+ handle.svm_slot(),
+ 0);
}
tex_mapping.compile_end(compiler, vector_in, vector_offset);
@@ -907,12 +924,17 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
else if (type == NODE_SKY_HOSEK)
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
else if (type == NODE_SKY_NISHITA) {
+ /* Clamp altitude to reasonable values.
+ * Below 1m causes numerical issues and above 60km is space. */
+ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
+
sky_texture_precompute_nishita(&sunsky,
sun_disc,
sun_size,
+ sun_intensity,
sun_elevation,
sun_rotation,
- altitude,
+ clamped_altitude,
air_density,
dust_density);
/* precomputed texture image parameters */
@@ -924,7 +946,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
/* precompute sky texture */
if (handle.empty()) {
SkyLoader *loader = new SkyLoader(
- sun_elevation, altitude, air_density, dust_density, ozone_density);
+ sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
handle = image_manager->add_image(loader, impar);
}
}
@@ -939,7 +961,7 @@ 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);
+ compiler.parameter_array("nishita_data", sunsky.nishita_data, 10);
/* nishita texture */
if (type == NODE_SKY_NISHITA) {
compiler.parameter_texture("filename", handle.svm_slot());
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 846ba7423e5..326f1d14168 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -170,9 +170,10 @@ class SkyTextureNode : public TextureNode {
float ground_albedo;
bool sun_disc;
float sun_size;
+ float sun_intensity;
float sun_elevation;
float sun_rotation;
- int altitude;
+ float altitude;
float air_density;
float dust_density;
float ozone_density;
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index c45ae5553a8..f200e409b9e 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -823,6 +823,12 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
Mesh *mesh = static_cast<Mesh *>(geom);
apply = apply && mesh->subdivision_type == Mesh::SUBDIVISION_NONE;
}
+ else if (geom->type == Geometry::HAIR) {
+ /* Can't apply non-uniform scale to curves, this can't be represented by
+ * control points and radius alone. */
+ float scale;
+ apply = apply && transform_uniform_scale(object->tfm, scale);
+ }
if (apply) {
if (!(motion_blur && object->use_motion())) {
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 1a94d3e9db7..08a8cb08254 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -536,7 +536,7 @@ void Session::release_tile(RenderTile &rtile, const bool need_denoise)
denoising_cond.notify_all();
}
-void Session::map_neighbor_tiles(RenderTile *tiles, Device *tile_device)
+void Session::map_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
{
thread_scoped_lock tile_lock(tile_mutex);
@@ -546,75 +546,77 @@ void Session::map_neighbor_tiles(RenderTile *tiles, Device *tile_device)
tile_manager.state.buffer.full_x + tile_manager.state.buffer.width,
tile_manager.state.buffer.full_y + tile_manager.state.buffer.height);
+ RenderTile &center_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
+
if (!tile_manager.schedule_denoising) {
/* Fix up tile slices with overlap. */
if (tile_manager.slice_overlap != 0) {
- int y = max(tiles[4].y - tile_manager.slice_overlap, image_region.y);
- tiles[4].h = min(tiles[4].y + tiles[4].h + tile_manager.slice_overlap, image_region.w) - y;
- tiles[4].y = y;
+ int y = max(center_tile.y - tile_manager.slice_overlap, image_region.y);
+ center_tile.h = min(center_tile.y + center_tile.h + tile_manager.slice_overlap,
+ image_region.w) -
+ y;
+ center_tile.y = y;
}
/* Tiles are not being denoised individually, which means the entire image is processed. */
- tiles[3].x = tiles[4].x;
- tiles[1].y = tiles[4].y;
- tiles[5].x = tiles[4].x + tiles[4].w;
- tiles[7].y = tiles[4].y + tiles[4].h;
+ neighbors.set_bounds_from_center();
}
else {
- int center_idx = tiles[4].tile_index;
+ int center_idx = center_tile.tile_index;
assert(tile_manager.state.tiles[center_idx].state == Tile::DENOISE);
for (int dy = -1, i = 0; dy <= 1; dy++) {
for (int dx = -1; dx <= 1; dx++, i++) {
+ RenderTile &rtile = neighbors.tiles[i];
int nindex = tile_manager.get_neighbor_index(center_idx, i);
if (nindex >= 0) {
Tile *tile = &tile_manager.state.tiles[nindex];
- tiles[i].x = image_region.x + tile->x;
- tiles[i].y = image_region.y + tile->y;
- tiles[i].w = tile->w;
- tiles[i].h = tile->h;
+ rtile.x = image_region.x + tile->x;
+ rtile.y = image_region.y + tile->y;
+ rtile.w = tile->w;
+ rtile.h = tile->h;
if (buffers) {
- tile_manager.state.buffer.get_offset_stride(tiles[i].offset, tiles[i].stride);
+ tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
- tiles[i].buffer = buffers->buffer.device_pointer;
- tiles[i].buffers = buffers;
+ rtile.buffer = buffers->buffer.device_pointer;
+ rtile.buffers = buffers;
}
else {
assert(tile->buffers);
- tile->buffers->params.get_offset_stride(tiles[i].offset, tiles[i].stride);
+ tile->buffers->params.get_offset_stride(rtile.offset, rtile.stride);
- tiles[i].buffer = tile->buffers->buffer.device_pointer;
- tiles[i].buffers = tile->buffers;
+ rtile.buffer = tile->buffers->buffer.device_pointer;
+ rtile.buffers = tile->buffers;
}
}
else {
- int px = tiles[4].x + dx * params.tile_size.x;
- int py = tiles[4].y + dy * params.tile_size.y;
+ int px = center_tile.x + dx * params.tile_size.x;
+ int py = center_tile.y + dy * params.tile_size.y;
- tiles[i].x = clamp(px, image_region.x, image_region.z);
- tiles[i].y = clamp(py, image_region.y, image_region.w);
- tiles[i].w = tiles[i].h = 0;
+ rtile.x = clamp(px, image_region.x, image_region.z);
+ rtile.y = clamp(py, image_region.y, image_region.w);
+ rtile.w = rtile.h = 0;
- tiles[i].buffer = (device_ptr)NULL;
- tiles[i].buffers = NULL;
+ rtile.buffer = (device_ptr)NULL;
+ rtile.buffers = NULL;
}
}
}
}
- assert(tiles[4].buffers);
- device->map_neighbor_tiles(tile_device, tiles);
+ assert(center_tile.buffers);
+ device->map_neighbor_tiles(tile_device, neighbors);
/* The denoised result is written back to the original tile. */
- tiles[9] = tiles[4];
+ neighbors.target = center_tile;
}
-void Session::unmap_neighbor_tiles(RenderTile *tiles, Device *tile_device)
+void Session::unmap_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
{
thread_scoped_lock tile_lock(tile_mutex);
- device->unmap_neighbor_tiles(tile_device, tiles);
+ device->unmap_neighbor_tiles(tile_device, neighbors);
}
void Session::run_cpu()
@@ -943,8 +945,14 @@ void Session::set_pause(bool pause_)
}
}
- if (notify)
- pause_cond.notify_all();
+ if (session_thread) {
+ if (notify) {
+ pause_cond.notify_all();
+ }
+ }
+ else if (pause_) {
+ update_status_time(pause_);
+ }
}
void Session::set_denoising(const DenoiseParams &denoising)
@@ -1003,7 +1011,7 @@ bool Session::update_scene()
int height = tile_manager.state.buffer.full_height;
int resolution = tile_manager.state.resolution_divider;
- if (width != cam->width || height != cam->height) {
+ if (width != cam->width || height != cam->height || resolution != cam->resolution) {
cam->width = width;
cam->height = height;
cam->resolution = resolution;
@@ -1126,6 +1134,11 @@ bool Session::render_need_denoise(bool &delayed)
{
delayed = false;
+ /* Not supported yet for baking. */
+ if (read_bake_tile_cb) {
+ return false;
+ }
+
/* Denoising enabled? */
if (!params.denoising.need_denoising_task()) {
return false;
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 0141629762c..e3ac054ead3 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -198,8 +198,8 @@ class Session {
void update_tile_sample(RenderTile &tile);
void release_tile(RenderTile &tile, const bool need_denoise);
- void map_neighbor_tiles(RenderTile *tiles, Device *tile_device);
- void unmap_neighbor_tiles(RenderTile *tiles, Device *tile_device);
+ void map_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device);
+ void unmap_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device);
bool device_use_gl;
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index 6dcc7f7b3dd..07b345baff8 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -112,3 +112,4 @@ set_source_files_properties(util_avxf_avx_test.cpp PROPERTIES COMPILE_FLAGS "${C
CYCLES_TEST(util_avxf_avx "cycles_util;bf_intern_numaapi;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}")
set_source_files_properties(util_avxf_avx2_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
CYCLES_TEST(util_avxf_avx2 "cycles_util;bf_intern_numaapi;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}")
+CYCLES_TEST(util_transform "cycles_util;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}")
diff --git a/intern/cycles/test/util_transform_test.cpp b/intern/cycles/test/util_transform_test.cpp
new file mode 100644
index 00000000000..58ce0fdfee4
--- /dev/null
+++ b/intern/cycles/test/util_transform_test.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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 "testing/testing.h"
+
+#include "util/util_transform.h"
+#include "util/util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+TEST(transform_motion_decompose, Degenerated)
+{
+ // Simple case: single degenerated matrix.
+ {
+ vector<Transform> motion = {transform_scale(0.0f, 0.0f, 0.0f)};
+ vector<DecomposedTransform> decomp(motion.size());
+ transform_motion_decompose(decomp.data(), motion.data(), motion.size());
+ EXPECT_TRUE(transform_decomposed_isfinite_safe(&decomp[0]));
+ }
+
+ // Copy from previous to current.
+ {
+ vector<Transform> motion = {transform_rotate(M_PI_4_F, make_float3(1.0f, 1.0f, 1.0f)),
+ transform_scale(0.0f, 0.0f, 0.0f)};
+ vector<DecomposedTransform> decomp(motion.size());
+ transform_motion_decompose(decomp.data(), motion.data(), motion.size());
+ EXPECT_NEAR(len(decomp[1].x - decomp[0].x), 0.0f, 1e-6f);
+ }
+
+ // Copy from next to current.
+ {
+ vector<Transform> motion = {transform_scale(0.0f, 0.0f, 0.0f),
+ transform_rotate(M_PI_4_F, make_float3(1.0f, 1.0f, 1.0f))};
+ vector<DecomposedTransform> decomp(motion.size());
+ transform_motion_decompose(decomp.data(), motion.data(), motion.size());
+ EXPECT_NEAR(len(decomp[0].x - decomp[1].x), 0.0f, 1e-6f);
+ }
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index ad4ea9c86e0..f5e488d1bd2 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -98,12 +98,9 @@ set(SRC_HEADERS
util_rect.h
util_set.h
util_simd.h
- util_sky_model.cpp
- util_sky_model.h
- util_sky_model_data.h
- util_sky_nishita.cpp
util_avxf.h
util_avxb.h
+ util_avxi.h
util_semaphore.h
util_sseb.h
util_ssef.h
diff --git a/intern/cycles/util/util_avxb.h b/intern/cycles/util/util_avxb.h
index 34fafd188de..5c03b1d88d7 100644
--- a/intern/cycles/util/util_avxb.h
+++ b/intern/cycles/util/util_avxb.h
@@ -57,7 +57,7 @@ struct avxb {
: m256(_mm256_insertf128_ps(_mm256_castps128_ps256(a), b, 1))
{
}
- __forceinline operator const __m256 &(void)const
+ __forceinline operator const __m256 &(void) const
{
return m256;
}
diff --git a/intern/cycles/util/util_avxi.h b/intern/cycles/util/util_avxi.h
index e658a4f848f..1b3810764b7 100644
--- a/intern/cycles/util/util_avxi.h
+++ b/intern/cycles/util/util_avxi.h
@@ -54,7 +54,7 @@ struct avxi {
__forceinline avxi(const __m256i a) : m256(a)
{
}
- __forceinline operator const __m256i &(void)const
+ __forceinline operator const __m256i &(void) const
{
return m256;
}
diff --git a/intern/cycles/util/util_debug.cpp b/intern/cycles/util/util_debug.cpp
index 6ad4f709ab5..74ecefa1917 100644
--- a/intern/cycles/util/util_debug.cpp
+++ b/intern/cycles/util/util_debug.cpp
@@ -83,6 +83,7 @@ DebugFlags::OptiX::OptiX()
void DebugFlags::OptiX::reset()
{
cuda_streams = 1;
+ curves_api = false;
}
DebugFlags::OpenCL::OpenCL() : device_type(DebugFlags::OpenCL::DEVICE_ALL), debug(false)
diff --git a/intern/cycles/util/util_debug.h b/intern/cycles/util/util_debug.h
index da9f5408b59..6ac4beb55b8 100644
--- a/intern/cycles/util/util_debug.h
+++ b/intern/cycles/util/util_debug.h
@@ -108,6 +108,9 @@ class DebugFlags {
/* Number of CUDA streams to launch kernels concurrently from. */
int cuda_streams;
+
+ /* Use OptiX curves API for hair instead of custom implementation. */
+ bool curves_api;
};
/* Descriptor of OpenCL feature-set to be used. */
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 737c834e073..8caabf6eac3 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -787,6 +787,16 @@ ccl_device_inline float compare_floats(float a, float b, float abs_diff, int ulp
return (abs(__float_as_int(a) - __float_as_int(b)) < ulp_diff);
}
+/* Calculate the angle between the two vectors a and b.
+ * The usual approach acos(dot(a, b)) has severe precision issues for small angles,
+ * which are avoided by this method.
+ * Based on "Mangled Angles" from https://people.eecs.berkeley.edu/~wkahan/Mindless.pdf
+ */
+ccl_device_inline float precise_angle(float3 a, float3 b)
+{
+ return 2.0f * atan2f(len(a - b), len(a + b));
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H__ */
diff --git a/intern/cycles/util/util_math_fast.h b/intern/cycles/util/util_math_fast.h
index e979bd9e0c0..07b0878e3d5 100644
--- a/intern/cycles/util/util_math_fast.h
+++ b/intern/cycles/util/util_math_fast.h
@@ -87,7 +87,7 @@ ccl_device_inline int fast_rint(float x)
/* Single roundps instruction on SSE4.1+ (for gcc/clang at least). */
return float_to_int(rintf(x));
#else
- /* emulate rounding by adding/substracting 0.5. */
+ /* emulate rounding by adding/subtracting 0.5. */
return float_to_int(x + copysignf(0.5f, x));
#endif
}
@@ -445,12 +445,10 @@ ccl_device_inline float fast_expf(float x)
return fast_exp2f(x / M_LN2_F);
}
-#ifndef __KERNEL_GPU__
-/* MSVC seems to have a code-gen bug here in at least SSE41/AVX
- * see T78047 for details. */
-# ifdef _MSC_VER
-# pragma optimize("", off)
-# endif
+#if defined(__KERNEL_CPU__) && !defined(_MSC_VER)
+/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
+ * T78047 and T78869 for details. Just disable for now, it only makes
+ * a small difference in denoising performance. */
ccl_device float4 fast_exp2f4(float4 x)
{
const float4 one = make_float4(1.0f);
@@ -466,14 +464,16 @@ ccl_device float4 fast_exp2f4(float4 x)
r = madd4(x, r, make_float4(1.0f));
return __int4_as_float4(__float4_as_int4(r) + (m << 23));
}
-# ifdef _MSC_VER
-# pragma optimize("", on)
-# endif
ccl_device_inline float4 fast_expf4(float4 x)
{
return fast_exp2f4(x / M_LN2_F);
}
+#else
+ccl_device_inline float4 fast_expf4(float4 x)
+{
+ return make_float4(fast_expf(x.x), fast_expf(x.y), fast_expf(x.z), fast_expf(x.w));
+}
#endif
ccl_device_inline float fast_exp10(float x)
diff --git a/intern/cycles/util/util_math_float4.h b/intern/cycles/util/util_math_float4.h
index cd4b3e3b74c..ec5328adb31 100644
--- a/intern/cycles/util/util_math_float4.h
+++ b/intern/cycles/util/util_math_float4.h
@@ -477,6 +477,24 @@ ccl_device_inline float4 safe_divide_float4_float(const float4 a, const float b)
return (b != 0.0f) ? a / b : make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
+ccl_device_inline bool isfinite4_safe(float4 v)
+{
+ return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z) && isfinite_safe(v.w);
+}
+
+ccl_device_inline float4 ensure_finite4(float4 v)
+{
+ if (!isfinite_safe(v.x))
+ v.x = 0.0f;
+ if (!isfinite_safe(v.y))
+ v.y = 0.0f;
+ if (!isfinite_safe(v.z))
+ v.z = 0.0f;
+ if (!isfinite_safe(v.w))
+ v.w = 0.0f;
+ return v;
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_FLOAT4_H__ */
diff --git a/intern/cycles/util/util_sky_model.cpp b/intern/cycles/util/util_sky_model.cpp
deleted file mode 100644
index 8cdad8a90a4..00000000000
--- a/intern/cycles/util/util_sky_model.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
-This source is published under the following 3-clause BSD license.
-
-Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * None of the names of the contributors may be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* ============================================================================
-
-This file is part of a sample implementation of the analytical skylight and
-solar radiance models presented in the SIGGRAPH 2012 paper
-
-
- "An Analytic Model for Full Spectral Sky-Dome Radiance"
-
-and the 2013 IEEE CG&A paper
-
- "Adding a Solar Radiance Function to the Hosek Skylight Model"
-
- both by
-
- Lukas Hosek and Alexander Wilkie
- Charles University in Prague, Czech Republic
-
-
- Version: 1.4a, February 22nd, 2013
-
-Version history:
-
-1.4a February 22nd, 2013
- Removed unnecessary and counter-intuitive solar radius parameters
- from the interface of the colourspace sky dome initialisation functions.
-
-1.4 February 11th, 2013
- Fixed a bug which caused the relative brightness of the solar disc
- and the sky dome to be off by a factor of about 6. The sun was too
- bright: this affected both normal and alien sun scenarios. The
- coefficients of the solar radiance function were changed to fix this.
-
-1.3 January 21st, 2013 (not released to the public)
- Added support for solar discs that are not exactly the same size as
- the terrestrial sun. Also added support for suns with a different
- emission spectrum ("Alien World" functionality).
-
-1.2a December 18th, 2012
- Fixed a mistake and some inaccuracies in the solar radiance function
- explanations found in ArHosekSkyModel.h. The actual source code is
- unchanged compared to version 1.2.
-
-1.2 December 17th, 2012
- Native RGB data and a solar radiance function that matches the turbidity
- conditions were added.
-
-1.1 September 2012
- The coefficients of the spectral model are now scaled so that the output
- is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
- XYZ model is now no longer scaled to the range [0...1]. Instead, it is
- the result of a simple conversion from spectral data via the CIE 2 degree
- standard observer matching functions. Therefore, after multiplication
- with 683 lm / W, the Y channel now corresponds to luminance in lm.
-
-1.0 May 11th, 2012
- Initial release.
-
-
-Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
-an updated version of this code has been published!
-
-============================================================================ */
-
-/*
-
-All instructions on how to use this code are in the accompanying header file.
-
-*/
-
-#include "util/util_sky_model.h"
-#include "util/util_sky_model_data.h"
-
-#include <assert.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-CCL_NAMESPACE_BEGIN
-
-// Some macro definitions that occur elsewhere in ART, and that have to be
-// replicated to make this a stand-alone module.
-
-#ifndef MATH_PI
-# define MATH_PI 3.141592653589793
-#endif
-
-#ifndef MATH_DEG_TO_RAD
-# define MATH_DEG_TO_RAD (MATH_PI / 180.0)
-#endif
-
-#ifndef DEGREES
-# define DEGREES *MATH_DEG_TO_RAD
-#endif
-
-#ifndef TERRESTRIAL_SOLAR_RADIUS
-# define TERRESTRIAL_SOLAR_RADIUS ((0.51 DEGREES) / 2.0)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(_struct) ((_struct *)malloc(sizeof(_struct)))
-#endif
-
-// internal definitions
-
-typedef const double *ArHosekSkyModel_Dataset;
-typedef const double *ArHosekSkyModel_Radiance_Dataset;
-
-// internal functions
-
-static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
- ArHosekSkyModelConfiguration config,
- double turbidity,
- double albedo,
- double solar_elevation)
-{
- const double *elev_matrix;
-
- int int_turbidity = (int)turbidity;
- double turbidity_rem = turbidity - (double)int_turbidity;
-
- solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
-
- // alb 0 low turb
-
- elev_matrix = dataset + (9 * 6 * (int_turbidity - 1));
-
- for (unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] =
- (1.0 - albedo) * (1.0 - turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
- pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
- }
-
- // alb 1 low turb
- elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity - 1));
- for (unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] +=
- (albedo) * (1.0 - turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
- pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
- }
-
- if (int_turbidity == 10)
- return;
-
- // alb 0 high turb
- elev_matrix = dataset + (9 * 6 * (int_turbidity));
- for (unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] +=
- (1.0 - albedo) * (turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
- pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
- }
-
- // alb 1 high turb
- elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity));
- for (unsigned int i = 0; i < 9; ++i) {
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- config[i] +=
- (albedo) * (turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[i] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[i + 9] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[i + 18] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[i + 27] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[i + 36] +
- pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
- }
-}
-
-static double ArHosekSkyModel_CookRadianceConfiguration(ArHosekSkyModel_Radiance_Dataset dataset,
- double turbidity,
- double albedo,
- double solar_elevation)
-{
- const double *elev_matrix;
-
- int int_turbidity = (int)turbidity;
- double turbidity_rem = turbidity - (double)int_turbidity;
- double res;
- solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
-
- // alb 0 low turb
- elev_matrix = dataset + (6 * (int_turbidity - 1));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res = (1.0 - albedo) * (1.0 - turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
-
- // alb 1 low turb
- elev_matrix = dataset + (6 * 10 + 6 * (int_turbidity - 1));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res += (albedo) * (1.0 - turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
- if (int_turbidity == 10)
- return res;
-
- // alb 0 high turb
- elev_matrix = dataset + (6 * (int_turbidity));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res += (1.0 - albedo) * (turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
-
- // alb 1 high turb
- elev_matrix = dataset + (6 * 10 + 6 * (int_turbidity));
- //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
- res += (albedo) * (turbidity_rem) *
- (pow(1.0 - solar_elevation, 5.0) * elev_matrix[0] +
- 5.0 * pow(1.0 - solar_elevation, 4.0) * solar_elevation * elev_matrix[1] +
- 10.0 * pow(1.0 - solar_elevation, 3.0) * pow(solar_elevation, 2.0) * elev_matrix[2] +
- 10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
- 5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
- pow(solar_elevation, 5.0) * elev_matrix[5]);
- return res;
-}
-
-static double ArHosekSkyModel_GetRadianceInternal(ArHosekSkyModelConfiguration configuration,
- double theta,
- double gamma)
-{
- const double expM = exp(configuration[4] * gamma);
- const double rayM = cos(gamma) * cos(gamma);
- const double mieM =
- (1.0 + cos(gamma) * cos(gamma)) /
- pow((1.0 + configuration[8] * configuration[8] - 2.0 * configuration[8] * cos(gamma)), 1.5);
- const double zenith = sqrt(cos(theta));
-
- return (1.0 + configuration[0] * exp(configuration[1] / (cos(theta) + 0.01))) *
- (configuration[2] + configuration[3] * expM + configuration[5] * rayM +
- configuration[6] * mieM + configuration[7] * zenith);
-}
-
-void arhosekskymodelstate_free(ArHosekSkyModelState *state)
-{
- free(state);
-}
-
-double arhosekskymodel_radiance(ArHosekSkyModelState *state,
- double theta,
- double gamma,
- double wavelength)
-{
- int low_wl = (int)((wavelength - 320.0) / 40.0);
-
- if (low_wl < 0 || low_wl >= 11)
- return 0.0;
-
- double interp = fmod((wavelength - 320.0) / 40.0, 1.0);
-
- double val_low = ArHosekSkyModel_GetRadianceInternal(state->configs[low_wl], theta, gamma) *
- state->radiances[low_wl] * state->emission_correction_factor_sky[low_wl];
-
- if (interp < 1e-6)
- return val_low;
-
- double result = (1.0 - interp) * val_low;
-
- if (low_wl + 1 < 11) {
- result += interp *
- ArHosekSkyModel_GetRadianceInternal(state->configs[low_wl + 1], theta, gamma) *
- state->radiances[low_wl + 1] * state->emission_correction_factor_sky[low_wl + 1];
- }
-
- return result;
-}
-
-// xyz and rgb versions
-
-ArHosekSkyModelState *arhosek_xyz_skymodelstate_alloc_init(const double turbidity,
- const double albedo,
- const double elevation)
-{
- ArHosekSkyModelState *state = ALLOC(ArHosekSkyModelState);
-
- state->solar_radius = TERRESTRIAL_SOLAR_RADIUS;
- state->turbidity = turbidity;
- state->albedo = albedo;
- state->elevation = elevation;
-
- for (unsigned int channel = 0; channel < 3; ++channel) {
- ArHosekSkyModel_CookConfiguration(
- datasetsXYZ[channel], state->configs[channel], turbidity, albedo, elevation);
-
- state->radiances[channel] = ArHosekSkyModel_CookRadianceConfiguration(
- datasetsXYZRad[channel], turbidity, albedo, elevation);
- }
-
- return state;
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_sky_model.h b/intern/cycles/util/util_sky_model.h
deleted file mode 100644
index 36f1079a16d..00000000000
--- a/intern/cycles/util/util_sky_model.h
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
-This source is published under the following 3-clause BSD license.
-
-Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * None of the names of the contributors may be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* ============================================================================
-
-This file is part of a sample implementation of the analytical skylight and
-solar radiance models presented in the SIGGRAPH 2012 paper
-
-
- "An Analytic Model for Full Spectral Sky-Dome Radiance"
-
-and the 2013 IEEE CG&A paper
-
- "Adding a Solar Radiance Function to the Hosek Skylight Model"
-
- both by
-
- Lukas Hosek and Alexander Wilkie
- Charles University in Prague, Czech Republic
-
-
- Version: 1.4a, February 22nd, 2013
-
-Version history:
-
-1.4a February 22nd, 2013
- Removed unnecessary and counter-intuitive solar radius parameters
- from the interface of the colourspace sky dome initialisation functions.
-
-1.4 February 11th, 2013
- Fixed a bug which caused the relative brightness of the solar disc
- and the sky dome to be off by a factor of about 6. The sun was too
- bright: this affected both normal and alien sun scenarios. The
- coefficients of the solar radiance function were changed to fix this.
-
-1.3 January 21st, 2013 (not released to the public)
- Added support for solar discs that are not exactly the same size as
- the terrestrial sun. Also added support for suns with a different
- emission spectrum ("Alien World" functionality).
-
-1.2a December 18th, 2012
- Fixed a mistake and some inaccuracies in the solar radiance function
- explanations found in ArHosekSkyModel.h. The actual source code is
- unchanged compared to version 1.2.
-
-1.2 December 17th, 2012
- Native RGB data and a solar radiance function that matches the turbidity
- conditions were added.
-
-1.1 September 2012
- The coefficients of the spectral model are now scaled so that the output
- is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
- XYZ model is now no longer scaled to the range [0...1]. Instead, it is
- the result of a simple conversion from spectral data via the CIE 2 degree
- standard observer matching functions. Therefore, after multiplication
- with 683 lm / W, the Y channel now corresponds to luminance in lm.
-
-1.0 May 11th, 2012
- Initial release.
-
-
-Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
-an updated version of this code has been published!
-
-============================================================================ */
-
-/*
-
-This code is taken from ART, a rendering research system written in a
-mix of C99 / Objective C. Since ART is not a small system and is intended to
-be inter-operable with other libraries, and since C does not have namespaces,
-the structures and functions in ART all have to have somewhat wordy
-canonical names that begin with Ar.../ar..., like those seen in this example.
-
-Usage information:
-==================
-
-
-Model initialisation
---------------------
-
-A separate ArHosekSkyModelState has to be maintained for each spectral
-band you want to use the model for. So in a renderer with 'num_channels'
-bands, you would need something like
-
- ArHosekSkyModelState * skymodel_state[num_channels];
-
-You then have to allocate and initialise these states. In the following code
-snippet, we assume that 'albedo' is defined as
-
- double albedo[num_channels];
-
-with a ground albedo value between [0,1] for each channel. The solar elevation
-is given in radians.
-
- for ( unsigned int i = 0; i < num_channels; i++ )
- skymodel_state[i] =
- arhosekskymodelstate_alloc_init(
- turbidity,
- albedo[i],
- solarElevation
- );
-
-Note that starting with version 1.3, there is also a second initialisation
-function which generates skydome states for different solar emission spectra
-and solar radii: 'arhosekskymodelstate_alienworld_alloc_init()'.
-
-See the notes about the "Alien World" functionality provided further down for a
-discussion of the usefulness and limits of that second initalisation function.
-Sky model states that have been initialized with either function behave in a
-completely identical fashion during use and cleanup.
-
-Using the model to generate skydome samples
--------------------------------------------
-
-Generating a skydome radiance spectrum "skydome_result" for a given location
-on the skydome determined via the angles theta and gamma works as follows:
-
- double skydome_result[num_channels];
-
- for ( unsigned int i = 0; i < num_channels; i++ )
- skydome_result[i] =
- arhosekskymodel_radiance(
- skymodel_state[i],
- theta,
- gamma,
- channel_center[i]
- );
-
-The variable "channel_center" is assumed to hold the channel center wavelengths
-for each of the num_channels samples of the spectrum we are building.
-
-
-Cleanup after use
------------------
-
-After rendering is complete, the content of the sky model states should be
-disposed of via
-
- for ( unsigned int i = 0; i < num_channels; i++ )
- arhosekskymodelstate_free( skymodel_state[i] );
-
-
-CIE XYZ Version of the Model
-----------------------------
-
-Usage of the CIE XYZ version of the model is exactly the same, except that
-num_channels is of course always 3, and that ArHosekTristimSkyModelState and
-arhosek_tristim_skymodel_radiance() have to be used instead of their spectral
-counterparts.
-
-RGB Version of the Model
-------------------------
-
-The RGB version uses sRGB primaries with a linear gamma ramp. The same set of
-functions as with the XYZ data is used, except the model is initialized
-by calling arhosek_rgb_skymodelstate_alloc_init.
-
-Solar Radiance Function
------------------------
-
-For each position on the solar disc, this function returns the entire radiance
-one sees - direct emission, as well as in-scattered light in the area of the
-solar disc. The latter is important for low solar elevations - nice images of
-the setting sun would not be possible without this. This is also the reason why
-this function, just like the regular sky dome model evaluation function, needs
-access to the sky dome data structures, as these provide information on
-in-scattered radiance.
-
-CAVEAT #1: in this release, this function is only provided in spectral form!
- RGB/XYZ versions to follow at a later date.
-
-CAVEAT #2: (fixed from release 1.3 onwards)
-
-CAVEAT #3: limb darkening renders the brightness of the solar disc
- inhomogeneous even for high solar elevations - only taking a single
- sample at the centre of the sun will yield an incorrect power
- estimate for the solar disc! Always take multiple random samples
- across the entire solar disc to estimate its power!
-
-CAVEAT #4: in this version, the limb darkening calculations still use a fairly
- computationally expensive 5th order polynomial that was directly
- taken from astronomical literature. For the purposes of Computer
- Graphics, this is needlessly accurate, though, and will be replaced
- by a cheaper approximation in a future release.
-
-"Alien World" functionality
----------------------------
-
-The Hosek sky model can be used to roughly (!) predict the appearance of
-outdoor scenes on earth-like planets, i.e. planets of a similar size and
-atmospheric make-up. Since the spectral version of our model predicts sky dome
-luminance patterns and solar radiance independently for each waveband, and
-since the intensity of each waveband is solely dependent on the input radiance
-from the star that the world in question is orbiting, it is trivial to re-scale
-the wavebands to match a different star radiance.
-
-At least in theory, the spectral version of the model has always been capable
-of this sort of thing, and the actual sky dome and solar radiance models were
-actually not altered at all in this release. All we did was to add some support
-functionality for doing this more easily with the existing data and functions,
-and to add some explanations.
-
-Just use 'arhosekskymodelstate_alienworld_alloc_init()' to initialise the sky
-model states (you will have to provide values for star temperature and solar
-intensity compared to the terrestrial sun), and do everything else as you
-did before.
-
-CAVEAT #1: we assume the emission of the star that illuminates the alien world
- to be a perfect blackbody emission spectrum. This is never entirely
- realistic - real star emission spectra are considerably more complex
- than this, mainly due to absorption effects in the outer layers of
- stars. However, blackbody spectra are a reasonable first assumption
- in a usage scenario like this, where 100% accuracy is simply not
- necessary: for rendering purposes, there are likely no visible
- differences between a highly accurate solution based on a more
- involved simulation, and this approximation.
-
-CAVEAT #2: we always use limb darkening data from our own sun to provide this
- "appearance feature", even for suns of strongly different
- temperature. Which is presumably not very realistic, but (as with
- the unaltered blackbody spectrum from caveat #1) probably not a bad
- first guess, either. If you need more accuracy than we provide here,
- please make inquiries with a friendly astro-physicst of your choice.
-
-CAVEAT #3: you have to provide a value for the solar intensity of the star
- which illuminates the alien world. For this, please bear in mind
- that there is very likely a comparatively tight range of absolute
- solar irradiance values for which an earth-like planet with an
- atmosphere like the one we assume in our model can exist in the
- first place!
-
- Too much irradiance, and the atmosphere probably boils off into
- space, too little, it freezes. Which means that stars of
- considerably different emission colour than our sun will have to be
- fairly different in size from it, to still provide a reasonable and
- inhabitable amount of irradiance. Red stars will need to be much
- larger than our sun, while white or blue stars will have to be
- comparatively tiny. The initialisation function handles this and
- computes a plausible solar radius for a given emission spectrum. In
- terms of absolute radiometric values, you should probably not stray
- all too far from a solar intensity value of 1.0.
-
-CAVEAT #4: although we now support different solar radii for the actual solar
- disc, the sky dome luminance patterns are *not* parameterised by
- this value - i.e. the patterns stay exactly the same for different
- solar radii! Which is of course not correct. But in our experience,
- solar discs up to several degrees in diameter (! - our own sun is
- half a degree across) do not cause the luminance patterns on the sky
- to change perceptibly. The reason we know this is that we initially
- used unrealistically large suns in our brute force path tracer, in
- order to improve convergence speeds (which in the beginning were
- abysmal). Later, we managed to do the reference renderings much
- faster even with realistically small suns, and found that there was
- no real difference in skydome appearance anyway.
- Conclusion: changing the solar radius should not be over-done, so
- close orbits around red supergiants are a no-no. But for the
- purposes of getting a fairly credible first impression of what an
- alien world with a reasonably sized sun would look like, what we are
- doing here is probably still o.k.
-
-HINT #1: if you want to model the sky of an earth-like planet that orbits
- a binary star, just super-impose two of these models with solar
- intensity of ~0.5 each, and closely spaced solar positions. Light is
- additive, after all. Tattooine, here we come... :-)
-
- P.S. according to Star Wars canon, Tattooine orbits a binary
- that is made up of a G and K class star, respectively.
- So ~5500K and ~4200K should be good first guesses for their
- temperature. Just in case you were wondering, after reading the
- previous paragraph.
-*/
-
-#include "util/util_types.h"
-
-CCL_NAMESPACE_BEGIN
-
-#ifndef _SKY_MODEL_H_
-# define _SKY_MODEL_H_
-
-typedef double ArHosekSkyModelConfiguration[9];
-
-// Spectral version of the model
-
-/* ----------------------------------------------------------------------------
-
- ArHosekSkyModelState struct
- ---------------------------
-
- This struct holds the pre-computation data for one particular albedo value.
- Most fields are self-explanatory, but users should never directly
- manipulate any of them anyway. The only consistent way to manipulate such
- structs is via the functions 'arhosekskymodelstate_alloc_init' and
- 'arhosekskymodelstate_free'.
-
- 'emission_correction_factor_sky'
- 'emission_correction_factor_sun'
-
- The original model coefficients were fitted against the emission of
- our local sun. If a different solar emission is desired (i.e. if the
- model is being used to predict skydome appearance for an earth-like
- planet that orbits a different star), these correction factors, which
- are determined during the alloc_init step, are applied to each waveband
- separately (they default to 1.0 in normal usage). This is the simplest
- way to retrofit this sort of capability to the existing model. The
- different factors for sky and sun are needed since the solar disc may
- be of a different size compared to the terrestrial sun.
-
----------------------------------------------------------------------------- */
-
-typedef struct ArHosekSkyModelState {
- ArHosekSkyModelConfiguration configs[11];
- double radiances[11];
- double turbidity;
- double solar_radius;
- double emission_correction_factor_sky[11];
- double emission_correction_factor_sun[11];
- double albedo;
- double elevation;
-} ArHosekSkyModelState;
-
-/* ----------------------------------------------------------------------------
-
- arhosekskymodelstate_alloc_init() function
- ------------------------------------------
-
- Initialises an ArHosekSkyModelState struct for a terrestrial setting.
-
----------------------------------------------------------------------------- */
-
-ArHosekSkyModelState *arhosekskymodelstate_alloc_init(const double solar_elevation,
- const double atmospheric_turbidity,
- const double ground_albedo);
-
-/* ----------------------------------------------------------------------------
-
- arhosekskymodelstate_alienworld_alloc_init() function
- -----------------------------------------------------
-
- Initialises an ArHosekSkyModelState struct for an "alien world" setting
- with a sun of a surface temperature given in 'kelvin'. The parameter
- 'solar_intensity' controls the overall brightness of the sky, relative
- to the solar irradiance on Earth. A value of 1.0 yields a sky dome that
- is, on average over the wavelenghts covered in the model (!), as bright
- as the terrestrial sky in radiometric terms.
-
- Which means that the solar radius has to be adjusted, since the
- emissivity of a solar surface with a given temperature is more or less
- fixed. So hotter suns have to be smaller to be equally bright as the
- terrestrial sun, while cooler suns have to be larger. Note that there are
- limits to the validity of the luminance patterns of the underlying model:
- see the discussion above for more on this. In particular, an alien sun with
- a surface temperature of only 2000 Kelvin has to be very large if it is
- to be as bright as the terrestrial sun - so large that the luminance
- patterns are no longer a really good fit in that case.
-
- If you need information about the solar radius that the model computes
- for a given temperature (say, for light source sampling purposes), you
- have to query the 'solar_radius' variable of the sky model state returned
- *after* running this function.
-
----------------------------------------------------------------------------- */
-
-ArHosekSkyModelState *arhosekskymodelstate_alienworld_alloc_init(
- const double solar_elevation,
- const double solar_intensity,
- const double solar_surface_temperature_kelvin,
- const double atmospheric_turbidity,
- const double ground_albedo);
-
-void arhosekskymodelstate_free(ArHosekSkyModelState *state);
-
-double arhosekskymodel_radiance(ArHosekSkyModelState *state,
- double theta,
- double gamma,
- double wavelength);
-
-// CIE XYZ and RGB versions
-
-ArHosekSkyModelState *arhosek_xyz_skymodelstate_alloc_init(const double turbidity,
- const double albedo,
- const double elevation);
-
-ArHosekSkyModelState *arhosek_rgb_skymodelstate_alloc_init(const double turbidity,
- const double albedo,
- const double elevation);
-
-double arhosek_tristim_skymodel_radiance(ArHosekSkyModelState *state,
- double theta,
- double gamma,
- int channel);
-
-// Delivers the complete function: sky + sun, including limb darkening.
-// Please read the above description before using this - there are several
-// caveats!
-
-double arhosekskymodel_solar_radiance(ArHosekSkyModelState *state,
- double theta,
- double gamma,
- double wavelength);
-
-#endif // _SKY_MODEL_H_
-
-/* Nishita improved sky model */
-
-void nishita_skymodel_precompute_texture(float *pixels,
- int stride,
- int start_y,
- int end_y,
- int width,
- int height,
- float sun_elevation,
- float altitude,
- float air_density,
- float dust_density,
- float ozone_density);
-
-void nishita_skymodel_precompute_sun(float sun_elevation,
- float angular_diameter,
- float altitude,
- float air_density,
- float dust_density,
- float *pixel_bottom,
- float *pixel_top);
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_sky_model_data.h b/intern/cycles/util/util_sky_model_data.h
deleted file mode 100644
index a2a3935eb84..00000000000
--- a/intern/cycles/util/util_sky_model_data.h
+++ /dev/null
@@ -1,3847 +0,0 @@
-/*
-This source is published under the following 3-clause BSD license.
-
-Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * None of the names of the contributors may be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* ============================================================================
-
-This file is part of a sample implementation of the analytical skylight and
-solar radiance models presented in the SIGGRAPH 2012 paper
-
-
- "An Analytic Model for Full Spectral Sky-Dome Radiance"
-
-and the 2013 IEEE CG&A paper
-
- "Adding a Solar Radiance Function to the Hosek Skylight Model"
-
- both by
-
- Lukas Hosek and Alexander Wilkie
- Charles University in Prague, Czech Republic
-
-
- Version: 1.4a, February 22nd, 2013
-
-Version history:
-
-1.4a February 22nd, 2013
- Removed unnecessary and counter-intuitive solar radius parameters
- from the interface of the colourspace sky dome initialisation functions.
-
-1.4 February 11th, 2013
- Fixed a bug which caused the relative brightness of the solar disc
- and the sky dome to be off by a factor of about 6. The sun was too
- bright: this affected both normal and alien sun scenarios. The
- coefficients of the solar radiance function were changed to fix this.
-
-1.3 January 21st, 2013 (not released to the public)
- Added support for solar discs that are not exactly the same size as
- the terrestrial sun. Also added support for suns with a different
- emission spectrum ("Alien World" functionality).
-
-1.2a December 18th, 2012
- Fixed a mistake and some inaccuracies in the solar radiance function
- explanations found in ArHosekSkyModel.h. The actual source code is
- unchanged compared to version 1.2.
-
-1.2 December 17th, 2012
- Native RGB data and a solar radiance function that matches the turbidity
- conditions were added.
-
-1.1 September 2012
- The coefficients of the spectral model are now scaled so that the output
- is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
- XYZ model is now no longer scaled to the range [0...1]. Instead, it is
- the result of a simple conversion from spectral data via the CIE 2 degree
- standard observer matching functions. Therefore, after multiplication
- with 683 lm / W, the Y channel now corresponds to luminance in lm.
-
-1.0 May 11th, 2012
- Initial release.
-
-
-Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
-an updated version of this code has been published!
-
-============================================================================ */
-
-CCL_NAMESPACE_BEGIN
-
-/*
-
-This file contains the coefficient data for the XYZ colour space version of
-the model.
-
-*/
-
-// Uses Sep 9 pattern / Aug 23 mean dataset
-
-static const double datasetXYZ1[] = {
- // albedo 0, turbidity 1
- -1.117001e+000,
- -1.867262e-001,
- -1.113505e+001,
- 1.259865e+001,
- -3.937339e-002,
- 1.167571e+000,
- 7.100686e-003,
- 3.592678e+000,
- 6.083296e-001,
- -1.152006e+000,
- -1.926669e-001,
- 6.152049e+000,
- -4.770802e+000,
- -8.704701e-002,
- 7.483626e-001,
- 3.372718e-002,
- 4.464592e+000,
- 4.036546e-001,
- -1.072371e+000,
- -2.696632e-001,
- 2.816168e-001,
- 1.820571e+000,
- -3.742666e-001,
- 2.080607e+000,
- -7.675295e-002,
- -2.835366e+000,
- 1.129329e+000,
- -1.109935e+000,
- -1.532764e-001,
- 1.198787e+000,
- -9.015183e-001,
- 5.173015e-003,
- 5.749178e-001,
- 1.075633e-001,
- 4.387949e+000,
- 2.650413e-001,
- -1.052297e+000,
- -2.229452e-001,
- 1.952347e+000,
- 5.727205e-001,
- -4.885070e+000,
- 1.984016e+000,
- -1.106197e-001,
- -4.898361e-001,
- 8.907873e-001,
- -1.070108e+000,
- -1.600465e-001,
- 1.593886e+000,
- -4.479251e-005,
- -3.306541e+000,
- 9.390193e-001,
- 9.513168e-002,
- 2.343583e+000,
- 5.335404e-001,
- // albedo 0, turbidity 2
- -1.113253e+000,
- -1.699600e-001,
- -1.038822e+001,
- 1.137513e+001,
- -4.040911e-002,
- 1.037455e+000,
- 4.991792e-002,
- 4.801919e+000,
- 6.302710e-001,
- -1.135747e+000,
- -1.678594e-001,
- 4.970755e+000,
- -4.430230e+000,
- -6.657408e-002,
- 3.636161e-001,
- 1.558009e-001,
- 6.013370e+000,
- 3.959601e-001,
- -1.095892e+000,
- -2.732595e-001,
- 7.666496e-001,
- 1.350731e+000,
- -4.401401e-001,
- 2.470135e+000,
- -1.707929e-001,
- -3.260793e+000,
- 1.170337e+000,
- -1.073668e+000,
- -2.603929e-002,
- -1.944589e-001,
- 4.575207e-001,
- 6.878164e-001,
- -1.390770e-001,
- 3.690299e-001,
- 7.885781e+000,
- 1.877694e-001,
- -1.070091e+000,
- -2.798957e-001,
- 2.338478e+000,
- -2.647221e+000,
- -7.387808e+000,
- 2.329210e+000,
- -1.644639e-001,
- -2.003710e+000,
- 9.874527e-001,
- -1.067120e+000,
- -1.418866e-001,
- 1.254090e+000,
- 6.053048e+000,
- -2.918892e+000,
- 5.322812e-001,
- 1.613053e-001,
- 3.018161e+000,
- 5.274090e-001,
- // albedo 0, turbidity 3
- -1.129483e+000,
- -1.890619e-001,
- -9.065101e+000,
- 9.659923e+000,
- -3.607819e-002,
- 8.314359e-001,
- 8.181661e-002,
- 4.768868e+000,
- 6.339777e-001,
- -1.146420e+000,
- -1.883579e-001,
- 3.309173e+000,
- -3.127882e+000,
- -6.938176e-002,
- 3.987113e-001,
- 1.400581e-001,
- 6.283042e+000,
- 5.267076e-001,
- -1.128348e+000,
- -2.641305e-001,
- 1.223176e+000,
- 5.514952e-002,
- -3.490649e-001,
- 1.997784e+000,
- -4.123709e-002,
- -2.251251e+000,
- 9.483466e-001,
- -1.025820e+000,
- 1.404690e-002,
- -1.187406e+000,
- 2.729900e+000,
- 5.877588e-001,
- -2.761140e-001,
- 4.602633e-001,
- 8.305125e+000,
- 3.945001e-001,
- -1.083957e+000,
- -2.606679e-001,
- 2.207108e+000,
- -7.202803e+000,
- -5.968103e+000,
- 2.129455e+000,
- -7.789512e-002,
- -1.137688e+000,
- 8.871769e-001,
- -1.062465e+000,
- -1.512189e-001,
- 1.042881e+000,
- 1.427839e+001,
- -4.242214e+000,
- 4.038100e-001,
- 1.997780e-001,
- 2.814449e+000,
- 5.803196e-001,
- // albedo 0, turbidity 4
- -1.175099e+000,
- -2.410789e-001,
- -1.108587e+001,
- 1.133404e+001,
- -1.819300e-002,
- 6.772942e-001,
- 9.605043e-002,
- 4.231166e+000,
- 6.239972e-001,
- -1.224207e+000,
- -2.883527e-001,
- 3.002206e+000,
- -2.649612e+000,
- -4.795418e-002,
- 4.984398e-001,
- 3.251434e-002,
- 4.851611e+000,
- 6.551019e-001,
- -1.136955e+000,
- -2.423048e-001,
- 1.058823e+000,
- -2.489236e-001,
- -2.462179e-001,
- 1.933140e+000,
- 9.106828e-002,
- -1.905869e-001,
- 8.171065e-001,
- -1.014535e+000,
- -8.262500e-003,
- -1.448017e+000,
- 2.295788e+000,
- 3.510334e-001,
- -1.477418e+000,
- 5.432449e-001,
- 5.762796e+000,
- 4.908751e-001,
- -1.070666e+000,
- -2.379780e-001,
- 1.844589e+000,
- -5.442448e+000,
- -4.012768e+000,
- 2.945275e+000,
- 9.854725e-003,
- 8.455959e-002,
- 8.145030e-001,
- -1.071525e+000,
- -1.777132e-001,
- 8.076590e-001,
- 9.925865e+000,
- -3.324623e+000,
- -6.367437e-001,
- 2.844581e-001,
- 2.248384e+000,
- 6.544022e-001,
- // albedo 0, turbidity 5
- -1.218818e+000,
- -2.952382e-001,
- -1.345975e+001,
- 1.347153e+001,
- -6.814585e-003,
- 5.079068e-001,
- 1.197230e-001,
- 3.776949e+000,
- 5.836961e-001,
- -1.409868e+000,
- -5.114330e-001,
- 2.776539e+000,
- -2.039001e+000,
- -2.673769e-002,
- 4.145288e-001,
- 7.829342e-004,
- 2.275883e+000,
- 6.629691e-001,
- -1.069151e+000,
- -9.434247e-002,
- 7.293972e-001,
- -1.222473e+000,
- -1.533461e-001,
- 2.160357e+000,
- 4.626837e-002,
- 3.852415e+000,
- 8.593570e-001,
- -1.021306e+000,
- -1.149551e-001,
- -1.108414e+000,
- 4.178343e+000,
- 4.013665e-001,
- -2.222814e+000,
- 6.929462e-001,
- 1.392652e+000,
- 4.401662e-001,
- -1.074251e+000,
- -2.224002e-001,
- 1.372356e+000,
- -8.858704e+000,
- -3.922660e+000,
- 3.020018e+000,
- -1.458724e-002,
- 1.511186e+000,
- 8.288064e-001,
- -1.062048e+000,
- -1.526582e-001,
- 4.921067e-001,
- 1.485522e+001,
- -3.229936e+000,
- -8.426604e-001,
- 3.916243e-001,
- 2.678994e+000,
- 6.689264e-001,
- // albedo 0, turbidity 6
- -1.257023e+000,
- -3.364700e-001,
- -1.527795e+001,
- 1.504223e+001,
- 2.717715e-003,
- 3.029910e-001,
- 1.636851e-001,
- 3.561663e+000,
- 5.283161e-001,
- -1.635124e+000,
- -7.329993e-001,
- 3.523939e+000,
- -2.566337e+000,
- -1.902543e-002,
- 5.505483e-001,
- -6.242176e-002,
- 1.065992e+000,
- 6.654236e-001,
- -9.295823e-001,
- 4.845834e-002,
- -2.992990e-001,
- -2.001327e-001,
- -8.019339e-002,
- 1.807806e+000,
- 9.020277e-002,
- 5.095372e+000,
- 8.639936e-001,
- -1.093740e+000,
- -2.148608e-001,
- -5.216240e-001,
- 2.119777e+000,
- 9.506454e-002,
- -1.831439e+000,
- 6.961204e-001,
- 1.102084e-001,
- 4.384319e-001,
- -1.044181e+000,
- -1.849257e-001,
- 9.071246e-001,
- -4.648901e+000,
- -2.279385e+000,
- 2.356502e+000,
- -4.169147e-002,
- 1.932557e+000,
- 8.296550e-001,
- -1.061451e+000,
- -1.458745e-001,
- 2.952267e-001,
- 8.967214e+000,
- -3.726228e+000,
- -5.022316e-001,
- 5.684877e-001,
- 3.102347e+000,
- 6.658443e-001,
- // albedo 0, turbidity 7
- -1.332391e+000,
- -4.127769e-001,
- -9.328643e+000,
- 9.046194e+000,
- 3.457775e-003,
- 3.377425e-001,
- 1.530909e-001,
- 3.301209e+000,
- 4.997917e-001,
- -1.932002e+000,
- -9.947777e-001,
- -2.042329e+000,
- 3.586940e+000,
- -5.642182e-002,
- 8.130478e-001,
- -8.195988e-002,
- 1.118294e-001,
- 5.617231e-001,
- -8.707374e-001,
- 1.286999e-001,
- 1.820054e+000,
- -4.674706e+000,
- 3.317471e-003,
- 5.919018e-001,
- 1.975278e-001,
- 6.686519e+000,
- 9.631727e-001,
- -1.070378e+000,
- -3.030579e-001,
- -9.041938e-001,
- 6.200201e+000,
- 1.232207e-001,
- -3.650628e-001,
- 5.029403e-001,
- -2.903162e+000,
- 3.811408e-001,
- -1.063035e+000,
- -1.637545e-001,
- 5.853072e-001,
- -7.889906e+000,
- -1.200641e+000,
- 1.035018e+000,
- 1.192093e-001,
- 3.267054e+000,
- 8.416151e-001,
- -1.053655e+000,
- -1.562286e-001,
- 2.423683e-001,
- 1.128575e+001,
- -4.363262e+000,
- -7.314160e-002,
- 5.642088e-001,
- 2.514023e+000,
- 6.670457e-001,
- // albedo 0, turbidity 8
- -1.366112e+000,
- -4.718287e-001,
- -7.876222e+000,
- 7.746900e+000,
- -9.182309e-003,
- 4.716076e-001,
- 8.320252e-002,
- 3.165603e+000,
- 5.392334e-001,
- -2.468204e+000,
- -1.336340e+000,
- -5.386723e+000,
- 7.072672e+000,
- -8.329266e-002,
- 8.636876e-001,
- -1.978177e-002,
- -1.326218e-001,
- 2.979222e-001,
- -9.653522e-001,
- -2.373416e-002,
- 1.810250e+000,
- -6.467262e+000,
- 1.410706e-001,
- -4.753717e-001,
- 3.003095e-001,
- 6.551163e+000,
- 1.151083e+000,
- -8.943186e-001,
- -2.487152e-001,
- -2.308960e-001,
- 8.512648e+000,
- 1.298402e-001,
- 1.034705e+000,
- 2.303509e-001,
- -3.924095e+000,
- 2.982717e-001,
- -1.146999e+000,
- -2.318784e-001,
- 8.992419e-002,
- -9.933614e+000,
- -8.860920e-001,
- -3.071656e-002,
- 2.852012e-001,
- 3.046199e+000,
- 8.599001e-001,
- -1.032399e+000,
- -1.645145e-001,
- 2.683599e-001,
- 1.327701e+001,
- -4.407670e+000,
- 7.709869e-002,
- 4.951727e-001,
- 1.957277e+000,
- 6.630943e-001,
- // albedo 0, turbidity 9
- -1.469070e+000,
- -6.135092e-001,
- -6.506263e+000,
- 6.661315e+000,
- -3.835383e-002,
- 7.150413e-001,
- 7.784318e-003,
- 2.820577e+000,
- 6.756784e-001,
- -2.501583e+000,
- -1.247404e+000,
- -1.523462e+001,
- 1.633191e+001,
- -1.204803e-002,
- 5.896471e-001,
- -2.002023e-002,
- 1.144647e+000,
- 6.177874e-002,
- -2.438672e+000,
- -1.127291e+000,
- 5.731172e+000,
- -1.021350e+001,
- 6.165610e-002,
- -7.752641e-001,
- 4.708254e-001,
- 4.176847e+000,
- 1.200881e+000,
- -1.513427e-001,
- 9.792731e-002,
- -1.612349e+000,
- 9.814289e+000,
- 5.188921e-002,
- 1.716403e+000,
- -7.039255e-002,
- -2.815115e+000,
- 3.291874e-001,
- -1.318511e+000,
- -3.650554e-001,
- 4.221268e-001,
- -9.294529e+000,
- -4.397520e-002,
- -8.100625e-001,
- 3.742719e-001,
- 1.834166e+000,
- 8.223450e-001,
- -1.016009e+000,
- -1.820264e-001,
- 1.278426e-001,
- 1.182696e+001,
- -4.801528e+000,
- 4.947899e-001,
- 4.660378e-001,
- 1.601254e+000,
- 6.702359e-001,
- // albedo 0, turbidity 10
- -1.841310e+000,
- -9.781779e-001,
- -4.610903e+000,
- 4.824662e+000,
- -5.100806e-002,
- 6.463776e-001,
- -6.377724e-006,
- 2.216875e+000,
- 8.618530e-001,
- -2.376373e+000,
- -1.108657e+000,
- -1.489799e+001,
- 1.546458e+001,
- 4.091025e-002,
- 9.761780e-002,
- -1.048958e-002,
- 2.165834e+000,
- -1.609171e-001,
- -4.710318e+000,
- -2.261963e+000,
- 6.947327e+000,
- -1.034828e+001,
- -1.325542e-001,
- 7.508674e-001,
- 2.247553e-001,
- 2.873142e+000,
- 1.297100e+000,
- 2.163750e-001,
- -1.944345e-001,
- -2.437860e+000,
- 1.011314e+001,
- 4.450500e-001,
- 3.111492e-001,
- 2.751323e-001,
- -1.627906e+000,
- 2.531213e-001,
- -1.258794e+000,
- -3.524641e-001,
- 8.425444e-001,
- -1.085313e+001,
- -1.154381e+000,
- -4.638014e-001,
- -2.781115e-003,
- 4.344498e-001,
- 8.507091e-001,
- -1.018938e+000,
- -1.804153e-001,
- -6.354054e-002,
- 1.573150e+001,
- -4.386999e+000,
- 6.211115e-001,
- 5.294648e-001,
- 1.580749e+000,
- 6.586655e-001,
- // albedo 1, turbidity 1
- -1.116416e+000,
- -1.917524e-001,
- -1.068233e+001,
- 1.222221e+001,
- -3.668978e-002,
- 1.054022e+000,
- 1.592132e-002,
- 3.180583e+000,
- 5.627370e-001,
- -1.132341e+000,
- -1.671286e-001,
- 5.976499e+000,
- -4.227366e+000,
- -9.542489e-002,
- 8.664938e-001,
- 8.351793e-003,
- 4.876068e+000,
- 4.492779e-001,
- -1.087635e+000,
- -3.173679e-001,
- 4.314407e-001,
- 1.100555e+000,
- -4.410057e-001,
- 1.677253e+000,
- -3.005925e-002,
- -4.201249e+000,
- 1.070902e+000,
- -1.083031e+000,
- -8.847705e-002,
- 1.291773e+000,
- 4.546776e-001,
- 3.091894e-001,
- 7.261760e-001,
- 4.203659e-002,
- 5.990615e+000,
- 3.704756e-001,
- -1.057899e+000,
- -2.246706e-001,
- 2.329563e+000,
- -1.219656e+000,
- -5.335260e+000,
- 8.545378e-001,
- -3.906209e-002,
- -9.025499e-001,
- 7.797348e-001,
- -1.073305e+000,
- -1.522553e-001,
- 1.767063e+000,
- 1.904280e+000,
- -3.101673e+000,
- 3.995856e-001,
- 2.905192e-002,
- 2.563977e+000,
- 5.753067e-001,
- // albedo 1, turbidity 2
- -1.113674e+000,
- -1.759694e-001,
- -9.754125e+000,
- 1.087391e+001,
- -3.841093e-002,
- 9.524272e-001,
- 5.680219e-002,
- 4.227034e+000,
- 6.029571e-001,
- -1.126496e+000,
- -1.680281e-001,
- 5.332352e+000,
- -4.575579e+000,
- -6.761755e-002,
- 3.295335e-001,
- 1.194896e-001,
- 5.570901e+000,
- 4.536185e-001,
- -1.103074e+000,
- -2.681801e-001,
- 6.571479e-002,
- 2.396522e+000,
- -4.551280e-001,
- 2.466331e+000,
- -1.232022e-001,
- -3.023201e+000,
- 1.086379e+000,
- -1.053299e+000,
- -2.697173e-002,
- 8.379121e-001,
- -9.681458e-001,
- 5.890692e-001,
- -4.872027e-001,
- 2.936929e-001,
- 7.510139e+000,
- 3.079122e-001,
- -1.079553e+000,
- -2.710448e-001,
- 2.462379e+000,
- -3.713554e-001,
- -8.534512e+000,
- 1.828242e+000,
- -1.686398e-001,
- -1.961340e+000,
- 8.941077e-001,
- -1.069741e+000,
- -1.396394e-001,
- 1.657868e+000,
- 3.236313e+000,
- -2.706344e+000,
- -2.948122e-001,
- 1.314816e-001,
- 2.868457e+000,
- 5.413403e-001,
- // albedo 1, turbidity 3
- -1.131649e+000,
- -1.954455e-001,
- -7.751595e+000,
- 8.685861e+000,
- -4.910871e-002,
- 8.992952e-001,
- 4.710143e-002,
- 4.254818e+000,
- 6.821116e-001,
- -1.156689e+000,
- -1.884324e-001,
- 3.163519e+000,
- -3.091522e+000,
- -6.613927e-002,
- -2.575883e-002,
- 1.640065e-001,
- 6.073643e+000,
- 4.453468e-001,
- -1.079224e+000,
- -2.621389e-001,
- 9.446437e-001,
- 1.448479e+000,
- -3.969384e-001,
- 2.626638e+000,
- -8.101186e-002,
- -3.016355e+000,
- 1.076295e+000,
- -1.080832e+000,
- 1.033057e-002,
- -3.500156e-001,
- -3.281419e-002,
- 5.655512e-001,
- -1.156742e+000,
- 4.534710e-001,
- 8.774122e+000,
- 2.772869e-001,
- -1.051202e+000,
- -2.679975e-001,
- 2.719109e+000,
- -2.190316e+000,
- -6.878798e+000,
- 2.250481e+000,
- -2.030252e-001,
- -2.026527e+000,
- 9.701096e-001,
- -1.089849e+000,
- -1.598589e-001,
- 1.564748e+000,
- 6.869187e+000,
- -3.053670e+000,
- -6.110435e-001,
- 1.644472e-001,
- 2.370452e+000,
- 5.511770e-001,
- // albedo 1, turbidity 4
- -1.171419e+000,
- -2.429746e-001,
- -8.991334e+000,
- 9.571216e+000,
- -2.772861e-002,
- 6.688262e-001,
- 7.683478e-002,
- 3.785611e+000,
- 6.347635e-001,
- -1.228554e+000,
- -2.917562e-001,
- 2.753986e+000,
- -2.491780e+000,
- -4.663434e-002,
- 3.118303e-001,
- 7.546506e-002,
- 4.463096e+000,
- 5.955071e-001,
- -1.093124e+000,
- -2.447767e-001,
- 9.097406e-001,
- 5.448296e-001,
- -2.957824e-001,
- 2.024167e+000,
- -5.152333e-004,
- -1.069081e+000,
- 9.369565e-001,
- -1.056994e+000,
- 1.569507e-002,
- -8.217491e-001,
- 1.870818e+000,
- 7.061930e-001,
- -1.483928e+000,
- 5.978206e-001,
- 6.864902e+000,
- 3.673332e-001,
- -1.054871e+000,
- -2.758129e-001,
- 2.712807e+000,
- -5.950110e+000,
- -6.554039e+000,
- 2.447523e+000,
- -1.895171e-001,
- -1.454292e+000,
- 9.131738e-001,
- -1.100218e+000,
- -1.746241e-001,
- 1.438505e+000,
- 1.115481e+001,
- -3.266076e+000,
- -8.837357e-001,
- 1.970100e-001,
- 1.991595e+000,
- 5.907821e-001,
- // albedo 1, turbidity 5
- -1.207267e+000,
- -2.913610e-001,
- -1.103767e+001,
- 1.140724e+001,
- -1.416800e-002,
- 5.564047e-001,
- 8.476262e-002,
- 3.371255e+000,
- 6.221335e-001,
- -1.429698e+000,
- -5.374218e-001,
- 2.837524e+000,
- -2.221936e+000,
- -2.422337e-002,
- 9.313758e-002,
- 7.190250e-002,
- 1.869022e+000,
- 5.609035e-001,
- -1.002274e+000,
- -6.972810e-002,
- 4.031308e-001,
- -3.932997e-001,
- -1.521923e-001,
- 2.390646e+000,
- -6.893990e-002,
- 2.999661e+000,
- 1.017843e+000,
- -1.081168e+000,
- -1.178666e-001,
- -4.968080e-001,
- 3.919299e+000,
- 6.046866e-001,
- -2.440615e+000,
- 7.891538e-001,
- 2.140835e+000,
- 2.740470e-001,
- -1.050727e+000,
- -2.307688e-001,
- 2.276396e+000,
- -9.454407e+000,
- -5.505176e+000,
- 2.992620e+000,
- -2.450942e-001,
- 6.078372e-001,
- 9.606765e-001,
- -1.103752e+000,
- -1.810202e-001,
- 1.375044e+000,
- 1.589095e+001,
- -3.438954e+000,
- -1.265669e+000,
- 2.475172e-001,
- 1.680768e+000,
- 5.978056e-001,
- // albedo 1, turbidity 6
- -1.244324e+000,
- -3.378542e-001,
- -1.111001e+001,
- 1.137784e+001,
- -7.896794e-003,
- 4.808023e-001,
- 9.249904e-002,
- 3.025816e+000,
- 5.880239e-001,
- -1.593165e+000,
- -7.027621e-001,
- 2.220896e+000,
- -1.437709e+000,
- -1.534738e-002,
- 6.286958e-002,
- 6.644555e-002,
- 1.091727e+000,
- 5.470080e-001,
- -9.136506e-001,
- 1.344874e-002,
- 7.772636e-001,
- -1.209396e+000,
- -1.408978e-001,
- 2.433718e+000,
- -1.041938e-001,
- 3.791244e+000,
- 1.037916e+000,
- -1.134968e+000,
- -1.803315e-001,
- -9.267335e-001,
- 4.576670e+000,
- 6.851928e-001,
- -2.805000e+000,
- 8.687208e-001,
- 1.161483e+000,
- 2.571688e-001,
- -1.017037e+000,
- -2.053943e-001,
- 2.361640e+000,
- -9.887818e+000,
- -5.122889e+000,
- 3.287088e+000,
- -2.594102e-001,
- 8.578927e-001,
- 9.592340e-001,
- -1.118723e+000,
- -1.934942e-001,
- 1.226023e+000,
- 1.674140e+001,
- -3.277335e+000,
- -1.629809e+000,
- 2.765232e-001,
- 1.637713e+000,
- 6.113963e-001,
- // albedo 1, turbidity 7
- -1.314779e+000,
- -4.119915e-001,
- -1.241150e+001,
- 1.241578e+001,
- 2.344284e-003,
- 2.980837e-001,
- 1.414613e-001,
- 2.781731e+000,
- 4.998556e-001,
- -1.926199e+000,
- -1.020038e+000,
- 2.569200e+000,
- -1.081159e+000,
- -2.266833e-002,
- 3.588668e-001,
- 8.750078e-003,
- -2.452171e-001,
- 4.796758e-001,
- -7.780002e-001,
- 1.850647e-001,
- 4.445456e-002,
- -2.409297e+000,
- -7.816346e-002,
- 1.546790e+000,
- -2.807227e-002,
- 5.998176e+000,
- 1.132396e+000,
- -1.179326e+000,
- -3.578330e-001,
- -2.392933e-001,
- 6.467883e+000,
- 5.904596e-001,
- -1.869975e+000,
- 8.045839e-001,
- -2.498121e+000,
- 1.610633e-001,
- -1.009956e+000,
- -1.311896e-001,
- 1.726577e+000,
- -1.219356e+001,
- -3.466239e+000,
- 2.343602e+000,
- -2.252205e-001,
- 2.573681e+000,
- 1.027109e+000,
- -1.112460e+000,
- -2.063093e-001,
- 1.233051e+000,
- 2.058946e+001,
- -4.578074e+000,
- -1.145643e+000,
- 3.160192e-001,
- 1.420159e+000,
- 5.860212e-001,
- // albedo 1, turbidity 8
- -1.371689e+000,
- -4.914196e-001,
- -1.076610e+001,
- 1.107405e+001,
- -1.485077e-002,
- 5.936218e-001,
- 3.685482e-002,
- 2.599968e+000,
- 6.002204e-001,
- -2.436997e+000,
- -1.377939e+000,
- 2.130141e-002,
- 1.079593e+000,
- -1.796232e-002,
- -3.933248e-002,
- 1.610711e-001,
- -6.901181e-001,
- 1.206416e-001,
- -8.743368e-001,
- 7.331370e-002,
- 8.734259e-001,
- -3.743126e+000,
- -3.151167e-002,
- 1.297596e+000,
- -7.634926e-002,
- 6.532873e+000,
- 1.435737e+000,
- -9.810197e-001,
- -3.521634e-001,
- -2.855205e-001,
- 7.134674e+000,
- 6.839748e-001,
- -1.394841e+000,
- 6.952036e-001,
- -4.633104e+000,
- -2.173401e-002,
- -1.122958e+000,
- -1.691536e-001,
- 1.382360e+000,
- -1.102913e+001,
- -2.608171e+000,
- 1.865111e+000,
- -1.345154e-001,
- 3.112342e+000,
- 1.094134e+000,
- -1.075586e+000,
- -2.077415e-001,
- 1.171477e+000,
- 1.793270e+001,
- -4.656858e+000,
- -1.036839e+000,
- 3.338295e-001,
- 1.042793e+000,
- 5.739374e-001,
- // albedo 1, turbidity 9
- -1.465871e+000,
- -6.364486e-001,
- -8.833718e+000,
- 9.343650e+000,
- -3.223600e-002,
- 7.552848e-001,
- -3.121341e-006,
- 2.249164e+000,
- 8.094662e-001,
- -2.448924e+000,
- -1.270878e+000,
- -4.823703e+000,
- 5.853058e+000,
- -2.149127e-002,
- 3.581132e-002,
- -1.230276e-003,
- 4.892553e-001,
- -1.597657e-001,
- -2.419809e+000,
- -1.071337e+000,
- 1.575648e+000,
- -4.983580e+000,
- 9.545185e-003,
- 5.032615e-001,
- 4.186266e-001,
- 4.634147e+000,
- 1.433517e+000,
- -1.383278e-001,
- -2.797095e-002,
- -1.943067e-001,
- 6.679623e+000,
- 4.118280e-001,
- -2.744289e-001,
- -2.118722e-002,
- -4.337025e+000,
- 1.505072e-001,
- -1.341872e+000,
- -2.518572e-001,
- 1.027009e+000,
- -6.527103e+000,
- -1.081271e+000,
- 1.015465e+000,
- 2.845789e-001,
- 2.470371e+000,
- 9.278120e-001,
- -1.040640e+000,
- -2.367454e-001,
- 1.100744e+000,
- 8.827253e+000,
- -4.560794e+000,
- -7.287017e-001,
- 2.842503e-001,
- 6.336593e-001,
- 6.327335e-001,
- // albedo 1, turbidity 10
- -1.877993e+000,
- -1.025135e+000,
- -4.311037e+000,
- 4.715016e+000,
- -4.711631e-002,
- 6.335844e-001,
- -7.665398e-006,
- 1.788017e+000,
- 9.001409e-001,
- -2.281540e+000,
- -1.137668e+000,
- -1.036869e+001,
- 1.136254e+001,
- 1.961739e-002,
- -9.836174e-002,
- -6.734567e-003,
- 1.320918e+000,
- -2.400807e-001,
- -4.904054e+000,
- -2.315781e+000,
- 5.735999e+000,
- -8.626257e+000,
- -1.255643e-001,
- 1.545446e+000,
- 1.396860e-001,
- 2.972897e+000,
- 1.429934e+000,
- 4.077067e-001,
- -1.833688e-001,
- -2.450939e+000,
- 9.119433e+000,
- 4.505361e-001,
- -1.340828e+000,
- 3.973690e-001,
- -1.785370e+000,
- 9.628711e-002,
- -1.296052e+000,
- -3.250526e-001,
- 1.813294e+000,
- -1.031485e+001,
- -1.388690e+000,
- 1.239733e+000,
- -8.989196e-002,
- -3.389637e-001,
- 9.639560e-001,
- -1.062181e+000,
- -2.423444e-001,
- 7.577592e-001,
- 1.566938e+001,
- -4.462264e+000,
- -5.742810e-001,
- 3.262259e-001,
- 9.461672e-001,
- 6.232887e-001,
-};
-
-static const double datasetXYZRad1[] = {
- // albedo 0, turbidity 1
- 1.560219e+000,
- 1.417388e+000,
- 1.206927e+000,
- 1.091949e+001,
- 5.931416e+000,
- 7.304788e+000,
- // albedo 0, turbidity 2
- 1.533049e+000,
- 1.560532e+000,
- 3.685059e-001,
- 1.355040e+001,
- 5.543711e+000,
- 7.792189e+000,
- // albedo 0, turbidity 3
- 1.471043e+000,
- 1.746088e+000,
- -9.299697e-001,
- 1.720362e+001,
- 5.473384e+000,
- 8.336416e+000,
- // albedo 0, turbidity 4
- 1.355991e+000,
- 2.109348e+000,
- -3.295855e+000,
- 2.264843e+001,
- 5.454607e+000,
- 9.304656e+000,
- // albedo 0, turbidity 5
- 1.244963e+000,
- 2.547533e+000,
- -5.841485e+000,
- 2.756879e+001,
- 5.576104e+000,
- 1.043287e+001,
- // albedo 0, turbidity 6
- 1.175532e+000,
- 2.784634e+000,
- -7.212225e+000,
- 2.975347e+001,
- 6.472980e+000,
- 1.092331e+001,
- // albedo 0, turbidity 7
- 1.082973e+000,
- 3.118094e+000,
- -8.934293e+000,
- 3.186879e+001,
- 8.473885e+000,
- 1.174019e+001,
- // albedo 0, turbidity 8
- 9.692500e-001,
- 3.349574e+000,
- -1.003810e+001,
- 3.147654e+001,
- 1.338931e+001,
- 1.272547e+001,
- // albedo 0, turbidity 9
- 8.547044e-001,
- 3.151538e+000,
- -9.095567e+000,
- 2.554995e+001,
- 2.273219e+001,
- 1.410398e+001,
- // albedo 0, turbidity 10
- 7.580340e-001,
- 2.311153e+000,
- -5.170814e+000,
- 1.229669e+001,
- 3.686529e+001,
- 1.598882e+001,
- // albedo 1, turbidity 1
- 1.664273e+000,
- 1.574468e+000,
- 1.422078e+000,
- 9.768247e+000,
- 1.447338e+001,
- 1.644988e+001,
- // albedo 1, turbidity 2
- 1.638295e+000,
- 1.719586e+000,
- 5.786675e-001,
- 1.239846e+001,
- 1.415419e+001,
- 1.728605e+001,
- // albedo 1, turbidity 3
- 1.572623e+000,
- 1.921559e+000,
- -7.714802e-001,
- 1.609246e+001,
- 1.420954e+001,
- 1.825908e+001,
- // albedo 1, turbidity 4
- 1.468395e+000,
- 2.211970e+000,
- -2.845869e+000,
- 2.075027e+001,
- 1.524822e+001,
- 1.937622e+001,
- // albedo 1, turbidity 5
- 1.355047e+000,
- 2.556469e+000,
- -4.960920e+000,
- 2.460237e+001,
- 1.648360e+001,
- 2.065648e+001,
- // albedo 1, turbidity 6
- 1.291642e+000,
- 2.742036e+000,
- -6.061967e+000,
- 2.602002e+001,
- 1.819144e+001,
- 2.116712e+001,
- // albedo 1, turbidity 7
- 1.194565e+000,
- 2.972120e+000,
- -7.295779e+000,
- 2.691805e+001,
- 2.124880e+001,
- 2.201819e+001,
- // albedo 1, turbidity 8
- 1.083631e+000,
- 3.047021e+000,
- -7.766096e+000,
- 2.496261e+001,
- 2.744264e+001,
- 2.291875e+001,
- // albedo 1, turbidity 9
- 9.707994e-001,
- 2.736459e+000,
- -6.308284e+000,
- 1.760860e+001,
- 3.776291e+001,
- 2.392150e+001,
- // albedo 1, turbidity 10
- 8.574294e-001,
- 1.865155e+000,
- -2.364707e+000,
- 4.337793e+000,
- 5.092831e+001,
- 2.523432e+001,
-};
-
-static const double datasetXYZ2[] = {
- // albedo 0, turbidity 1
- -1.127942e+000,
- -1.905548e-001,
- -1.252356e+001,
- 1.375799e+001,
- -3.624732e-002,
- 1.055453e+000,
- 1.385036e-002,
- 4.176970e+000,
- 5.928345e-001,
- -1.155260e+000,
- -1.778135e-001,
- 6.216056e+000,
- -5.254116e+000,
- -8.787445e-002,
- 8.434621e-001,
- 4.025734e-002,
- 6.195322e+000,
- 3.111856e-001,
- -1.125624e+000,
- -3.217593e-001,
- 5.043919e-001,
- 1.686284e+000,
- -3.536071e-001,
- 1.476321e+000,
- -7.899019e-002,
- -4.522531e+000,
- 1.271691e+000,
- -1.081801e+000,
- -1.033234e-001,
- 9.995550e-001,
- 7.482946e-003,
- -6.776018e-002,
- 1.463141e+000,
- 9.492021e-002,
- 5.612723e+000,
- 1.298846e-001,
- -1.075320e+000,
- -2.402711e-001,
- 2.141284e+000,
- -1.203359e+000,
- -4.945188e+000,
- 1.437221e+000,
- -8.096750e-002,
- -1.028378e+000,
- 1.004164e+000,
- -1.073337e+000,
- -1.516517e-001,
- 1.639379e+000,
- 2.304669e+000,
- -3.214244e+000,
- 1.286245e+000,
- 5.613957e-002,
- 2.480902e+000,
- 4.999363e-001,
- // albedo 0, turbidity 2
- -1.128399e+000,
- -1.857793e-001,
- -1.089863e+001,
- 1.172984e+001,
- -3.768099e-002,
- 9.439285e-001,
- 4.869335e-002,
- 4.845114e+000,
- 6.119211e-001,
- -1.114002e+000,
- -1.399280e-001,
- 4.963800e+000,
- -4.685500e+000,
- -7.780879e-002,
- 4.049736e-001,
- 1.586297e-001,
- 7.770264e+000,
- 3.449006e-001,
- -1.185472e+000,
- -3.403543e-001,
- 6.588322e-001,
- 1.133713e+000,
- -4.118674e-001,
- 2.061191e+000,
- -1.882768e-001,
- -4.372586e+000,
- 1.223530e+000,
- -1.002272e+000,
- 2.000703e-002,
- 7.073269e-002,
- 1.485075e+000,
- 5.005589e-001,
- 4.301494e-001,
- 3.626541e-001,
- 7.921098e+000,
- 1.574766e-001,
- -1.121006e+000,
- -3.007777e-001,
- 2.242051e+000,
- -4.571561e+000,
- -7.761071e+000,
- 2.053404e+000,
- -1.524018e-001,
- -1.886162e+000,
- 1.018208e+000,
- -1.058864e+000,
- -1.358673e-001,
- 1.389667e+000,
- 8.633409e+000,
- -3.437249e+000,
- 7.295429e-001,
- 1.514700e-001,
- 2.842513e+000,
- 5.014325e-001,
- // albedo 0, turbidity 3
- -1.144464e+000,
- -2.043799e-001,
- -1.020188e+001,
- 1.071247e+001,
- -3.256693e-002,
- 7.860205e-001,
- 6.872719e-002,
- 4.824771e+000,
- 6.259836e-001,
- -1.170104e+000,
- -2.118626e-001,
- 4.391405e+000,
- -4.198900e+000,
- -7.111559e-002,
- 3.890442e-001,
- 1.024831e-001,
- 6.282535e+000,
- 5.365688e-001,
- -1.129171e+000,
- -2.552880e-001,
- 2.238298e-001,
- 7.314295e-001,
- -3.562730e-001,
- 1.881931e+000,
- -3.078716e-002,
- -1.039120e+000,
- 9.096301e-001,
- -1.042294e+000,
- 4.450203e-003,
- -5.116033e-001,
- 2.627589e+000,
- 6.098996e-001,
- -1.264638e-001,
- 4.325281e-001,
- 7.080503e+000,
- 4.583646e-001,
- -1.082293e+000,
- -2.723056e-001,
- 2.065076e+000,
- -8.143133e+000,
- -7.892212e+000,
- 2.142231e+000,
- -7.106240e-002,
- -1.122398e+000,
- 8.338505e-001,
- -1.071715e+000,
- -1.426568e-001,
- 1.095351e+000,
- 1.729783e+001,
- -3.851931e+000,
- 4.360514e-001,
- 2.114440e-001,
- 2.970832e+000,
- 5.944389e-001,
- // albedo 0, turbidity 4
- -1.195909e+000,
- -2.590449e-001,
- -1.191037e+001,
- 1.207947e+001,
- -1.589842e-002,
- 6.297846e-001,
- 9.054772e-002,
- 4.285959e+000,
- 5.933752e-001,
- -1.245763e+000,
- -3.316637e-001,
- 4.293660e+000,
- -3.694011e+000,
- -4.699947e-002,
- 4.843684e-001,
- 2.130425e-002,
- 4.097549e+000,
- 6.530809e-001,
- -1.148742e+000,
- -1.902509e-001,
- -2.393233e-001,
- -2.441254e-001,
- -2.610918e-001,
- 1.846988e+000,
- 3.532866e-002,
- 2.660106e+000,
- 8.358294e-001,
- -1.016080e+000,
- -7.444960e-002,
- -5.053436e-001,
- 4.388855e+000,
- 6.054987e-001,
- -1.208300e+000,
- 5.817215e-001,
- 2.543570e+000,
- 4.726568e-001,
- -1.072027e+000,
- -2.101440e-001,
- 1.518378e+000,
- -1.060119e+001,
- -6.016546e+000,
- 2.649475e+000,
- -5.166992e-002,
- 1.571269e+000,
- 8.344622e-001,
- -1.072365e+000,
- -1.511201e-001,
- 7.478010e-001,
- 1.900732e+001,
- -3.950387e+000,
- -3.473907e-001,
- 3.797211e-001,
- 2.782949e+000,
- 6.296808e-001,
- // albedo 0, turbidity 5
- -1.239423e+000,
- -3.136289e-001,
- -1.351100e+001,
- 1.349468e+001,
- -7.070423e-003,
- 5.012315e-001,
- 1.106008e-001,
- 3.803619e+000,
- 5.577948e-001,
- -1.452524e+000,
- -5.676944e-001,
- 2.993153e+000,
- -2.277288e+000,
- -2.168954e-002,
- 3.056720e-001,
- 1.152338e-002,
- 1.852697e+000,
- 6.427228e-001,
- -1.061421e+000,
- -4.590521e-002,
- 6.057022e-001,
- -1.096835e+000,
- -1.504952e-001,
- 2.344921e+000,
- -5.491832e-002,
- 5.268322e+000,
- 9.082253e-001,
- -1.042373e+000,
- -1.769498e-001,
- -1.075388e+000,
- 3.831712e+000,
- 3.154140e-001,
- -2.416458e+000,
- 7.909032e-001,
- -1.492892e-002,
- 3.854049e-001,
- -1.064159e+000,
- -1.892684e-001,
- 1.438685e+000,
- -8.166362e+000,
- -3.616364e+000,
- 3.275206e+000,
- -1.203825e-001,
- 2.039491e+000,
- 8.688057e-001,
- -1.070120e+000,
- -1.569508e-001,
- 4.124760e-001,
- 1.399683e+001,
- -3.547085e+000,
- -1.046326e+000,
- 4.973825e-001,
- 2.791231e+000,
- 6.503286e-001,
- // albedo 0, turbidity 6
- -1.283579e+000,
- -3.609518e-001,
- -1.335397e+001,
- 1.315248e+001,
- -4.431938e-004,
- 3.769526e-001,
- 1.429824e-001,
- 3.573613e+000,
- 4.998696e-001,
- -1.657952e+000,
- -7.627948e-001,
- 1.958222e+000,
- -7.949816e-001,
- -2.882837e-002,
- 5.356149e-001,
- -5.191946e-002,
- 8.869955e-001,
- 6.263320e-001,
- -9.527600e-001,
- 6.494189e-002,
- 5.361303e-001,
- -2.129590e+000,
- -9.258630e-002,
- 1.604776e+000,
- 5.067770e-002,
- 6.376055e+000,
- 9.138052e-001,
- -1.080827e+000,
- -2.523120e-001,
- -7.154262e-001,
- 4.120085e+000,
- 1.878228e-001,
- -1.492158e+000,
- 6.881655e-001,
- -1.446611e+000,
- 4.040631e-001,
- -1.054075e+000,
- -1.665498e-001,
- 9.191052e-001,
- -6.636943e+000,
- -1.894826e+000,
- 2.107810e+000,
- -3.680499e-002,
- 2.655452e+000,
- 8.413840e-001,
- -1.061127e+000,
- -1.448849e-001,
- 2.667493e-001,
- 1.034103e+001,
- -4.285769e+000,
- -3.874504e-001,
- 5.998752e-001,
- 3.132426e+000,
- 6.652753e-001,
- // albedo 0, turbidity 7
- -1.347345e+000,
- -4.287832e-001,
- -9.305553e+000,
- 9.133813e+000,
- -3.173527e-003,
- 3.977564e-001,
- 1.151420e-001,
- 3.320564e+000,
- 4.998134e-001,
- -1.927296e+000,
- -9.901372e-001,
- -2.593499e+000,
- 4.087421e+000,
- -5.833993e-002,
- 8.158929e-001,
- -4.681279e-002,
- 2.423716e-001,
- 4.938052e-001,
- -9.470092e-001,
- 7.325237e-002,
- 2.064735e+000,
- -5.167540e+000,
- -1.313751e-002,
- 4.832169e-001,
- 1.126295e-001,
- 6.970522e+000,
- 1.035022e+000,
- -1.022557e+000,
- -2.762616e-001,
- -9.375748e-001,
- 6.696739e+000,
- 2.200765e-001,
- -1.133253e-001,
- 5.492505e-001,
- -3.109391e+000,
- 3.321914e-001,
- -1.087444e+000,
- -1.836263e-001,
- 6.225024e-001,
- -8.576765e+000,
- -1.107637e+000,
- 7.859427e-001,
- 9.910909e-002,
- 3.112938e+000,
- 8.596261e-001,
- -1.051544e+000,
- -1.546262e-001,
- 2.371731e-001,
- 1.200502e+001,
- -4.527291e+000,
- 7.268862e-002,
- 5.571478e-001,
- 2.532873e+000,
- 6.662000e-001,
- // albedo 0, turbidity 8
- -1.375576e+000,
- -4.840019e-001,
- -8.121290e+000,
- 8.058140e+000,
- -1.445661e-002,
- 5.123314e-001,
- 5.813321e-002,
- 3.203219e+000,
- 5.442318e-001,
- -2.325221e+000,
- -1.241463e+000,
- -7.063430e+000,
- 8.741369e+000,
- -7.829950e-002,
- 8.844273e-001,
- -3.471106e-002,
- 1.740583e-001,
- 2.814079e-001,
- -1.228700e+000,
- -2.013412e-001,
- 2.949042e+000,
- -7.371945e+000,
- 1.071753e-001,
- -2.491970e-001,
- 2.265223e-001,
- 6.391504e+000,
- 1.172389e+000,
- -7.601786e-001,
- -1.680631e-001,
- -7.584444e-001,
- 8.541356e+000,
- 8.222291e-002,
- 6.729633e-001,
- 3.206615e-001,
- -3.700940e+000,
- 2.710054e-001,
- -1.191166e+000,
- -2.672347e-001,
- 2.927498e-001,
- -9.713613e+000,
- -4.783721e-001,
- 2.352803e-001,
- 2.161949e-001,
- 2.691481e+000,
- 8.745447e-001,
- -1.030135e+000,
- -1.653301e-001,
- 2.263443e-001,
- 1.296157e+001,
- -4.650644e+000,
- 7.055709e-003,
- 5.091975e-001,
- 2.000370e+000,
- 6.603839e-001,
- // albedo 0, turbidity 9
- -1.508018e+000,
- -6.460933e-001,
- -6.402745e+000,
- 6.545995e+000,
- -3.750320e-002,
- 6.921803e-001,
- 3.309819e-003,
- 2.797527e+000,
- 6.978446e-001,
- -2.333308e+000,
- -1.167837e+000,
- -1.746787e+001,
- 1.868630e+001,
- -8.948229e-003,
- 5.621946e-001,
- -3.402626e-002,
- 1.217943e+000,
- 1.149865e-002,
- -2.665953e+000,
- -1.226307e+000,
- 7.169725e+000,
- -1.159434e+001,
- 3.583420e-002,
- -3.074378e-001,
- 3.412248e-001,
- 4.422122e+000,
- 1.283791e+000,
- -9.705116e-002,
- 8.312991e-002,
- -2.160462e+000,
- 1.028235e+001,
- 3.543357e-002,
- 1.032049e+000,
- 1.058310e-001,
- -2.972898e+000,
- 2.418628e-001,
- -1.329617e+000,
- -3.699557e-001,
- 5.560117e-001,
- -9.730113e+000,
- 9.938865e-002,
- -3.071488e-001,
- 2.510691e-001,
- 1.777111e+000,
- 8.705142e-001,
- -1.019387e+000,
- -1.893247e-001,
- 1.194079e-001,
- 1.239436e+001,
- -4.799224e+000,
- 2.940213e-001,
- 4.841268e-001,
- 1.529724e+000,
- 6.582615e-001,
- // albedo 0, turbidity 10
- -1.896737e+000,
- -1.005442e+000,
- -6.411032e+000,
- 6.548220e+000,
- -3.227596e-002,
- 5.717262e-001,
- -8.115192e-006,
- 2.296704e+000,
- 9.000749e-001,
- -2.411116e+000,
- -1.225587e+000,
- -1.753629e+001,
- 1.829393e+001,
- 1.247555e-002,
- 2.364616e-001,
- -5.114637e-003,
- 1.603778e+000,
- -2.224156e-001,
- -4.707121e+000,
- -2.074977e+000,
- 7.942300e+000,
- -1.132407e+001,
- -5.415654e-002,
- 5.446811e-001,
- 1.032493e-001,
- 4.010235e+000,
- 1.369802e+000,
- 1.010482e-001,
- -4.013305e-001,
- -2.674579e+000,
- 9.779409e+000,
- 1.782506e-001,
- 7.053045e-001,
- 4.200002e-001,
- -2.400671e+000,
- 1.953165e-001,
- -1.243526e+000,
- -3.391255e-001,
- 8.848882e-001,
- -9.789025e+000,
- -3.997324e-001,
- -9.546227e-001,
- -1.044017e-001,
- 6.010593e-001,
- 8.714462e-001,
- -1.014633e+000,
- -1.730009e-001,
- -7.738934e-002,
- 1.390903e+001,
- -4.847307e+000,
- 1.076059e+000,
- 5.685743e-001,
- 1.572992e+000,
- 6.561432e-001,
- // albedo 1, turbidity 1
- -1.122998e+000,
- -1.881183e-001,
- -1.030709e+001,
- 1.158932e+001,
- -4.079495e-002,
- 9.603774e-001,
- 3.079436e-002,
- 4.009235e+000,
- 5.060745e-001,
- -1.134790e+000,
- -1.539688e-001,
- 5.478405e+000,
- -4.217270e+000,
- -1.043858e-001,
- 7.165008e-001,
- 1.524765e-002,
- 6.473623e+000,
- 4.207882e-001,
- -1.134957e+000,
- -3.513318e-001,
- 7.393837e-001,
- 1.354415e+000,
- -4.764078e-001,
- 1.690441e+000,
- -5.492640e-002,
- -5.563523e+000,
- 1.145743e+000,
- -1.058344e+000,
- -5.758503e-002,
- 1.168230e+000,
- 3.269824e-001,
- 1.795193e-001,
- 7.849011e-001,
- 7.441853e-002,
- 6.904804e+000,
- 2.818790e-001,
- -1.075194e+000,
- -2.355813e-001,
- 2.463685e+000,
- -1.536505e+000,
- -7.505771e+000,
- 9.619712e-001,
- -6.465851e-002,
- -1.355492e+000,
- 8.489847e-001,
- -1.079030e+000,
- -1.465328e-001,
- 1.773838e+000,
- 2.310131e+000,
- -3.136065e+000,
- 3.507952e-001,
- 4.435014e-002,
- 2.819225e+000,
- 5.689008e-001,
- // albedo 1, turbidity 2
- -1.125833e+000,
- -1.870849e-001,
- -9.555833e+000,
- 1.059713e+001,
- -4.225402e-002,
- 9.164663e-001,
- 4.338796e-002,
- 4.400980e+000,
- 6.056119e-001,
- -1.127440e+000,
- -1.551891e-001,
- 4.755621e+000,
- -4.408806e+000,
- -7.851763e-002,
- 2.268284e-001,
- 1.460070e-001,
- 7.048003e+000,
- 3.525997e-001,
- -1.143788e+000,
- -3.170178e-001,
- 5.480669e-001,
- 2.041830e+000,
- -4.532139e-001,
- 2.302233e+000,
- -1.887419e-001,
- -4.489221e+000,
- 1.250967e+000,
- -1.032849e+000,
- 7.376031e-003,
- 5.666073e-001,
- -2.312203e-001,
- 4.862894e-001,
- -1.748294e-001,
- 3.572870e-001,
- 8.380522e+000,
- 1.302333e-001,
- -1.093728e+000,
- -2.786977e-001,
- 2.641272e+000,
- -1.507494e+000,
- -8.731243e+000,
- 1.684055e+000,
- -2.023377e-001,
- -2.176398e+000,
- 1.013249e+000,
- -1.076578e+000,
- -1.456205e-001,
- 1.693935e+000,
- 2.945003e+000,
- -2.822673e+000,
- -2.520033e-001,
- 1.517034e-001,
- 2.649109e+000,
- 5.179094e-001,
- // albedo 1, turbidity 3
- -1.146417e+000,
- -2.119353e-001,
- -7.187525e+000,
- 8.058599e+000,
- -5.256438e-002,
- 8.375733e-001,
- 3.887093e-002,
- 4.222111e+000,
- 6.695347e-001,
- -1.173674e+000,
- -2.067025e-001,
- 2.899359e+000,
- -2.804918e+000,
- -8.473899e-002,
- 3.944225e-003,
- 1.340641e-001,
- 6.160887e+000,
- 4.527141e-001,
- -1.090098e+000,
- -2.599633e-001,
- 9.180856e-001,
- 1.092710e+000,
- -4.215019e-001,
- 2.427660e+000,
- -9.277667e-002,
- -2.123523e+000,
- 1.058159e+000,
- -1.084460e+000,
- 8.056181e-003,
- -2.453510e-001,
- 6.619567e-001,
- 4.668118e-001,
- -9.526719e-001,
- 4.648454e-001,
- 8.001572e+000,
- 3.054194e-001,
- -1.053728e+000,
- -2.765784e-001,
- 2.792388e+000,
- -3.489517e+000,
- -8.150535e+000,
- 2.195757e+000,
- -2.017234e-001,
- -2.128017e+000,
- 9.326589e-001,
- -1.099348e+000,
- -1.593939e-001,
- 1.568292e+000,
- 7.247853e+000,
- -2.933000e+000,
- -5.890481e-001,
- 1.724440e-001,
- 2.433484e+000,
- 5.736558e-001,
- // albedo 1, turbidity 4
- -1.185983e+000,
- -2.581184e-001,
- -7.761056e+000,
- 8.317053e+000,
- -3.351773e-002,
- 6.676667e-001,
- 5.941733e-002,
- 3.820727e+000,
- 6.324032e-001,
- -1.268591e+000,
- -3.398067e-001,
- 2.348503e+000,
- -2.023779e+000,
- -5.368458e-002,
- 1.083282e-001,
- 8.402858e-002,
- 3.910254e+000,
- 5.577481e-001,
- -1.071353e+000,
- -1.992459e-001,
- 7.878387e-001,
- 1.974702e-001,
- -3.033058e-001,
- 2.335298e+000,
- -8.205259e-002,
- 7.954454e-001,
- 9.972312e-001,
- -1.089513e+000,
- -3.104364e-002,
- -5.995746e-001,
- 2.330281e+000,
- 6.581939e-001,
- -1.821467e+000,
- 6.679973e-001,
- 5.090195e+000,
- 3.125161e-001,
- -1.040214e+000,
- -2.570934e-001,
- 2.660489e+000,
- -6.506045e+000,
- -7.053586e+000,
- 2.763153e+000,
- -2.433632e-001,
- -7.648176e-001,
- 9.452937e-001,
- -1.116052e+000,
- -1.831993e-001,
- 1.457694e+000,
- 1.163608e+001,
- -3.216426e+000,
- -1.045594e+000,
- 2.285002e-001,
- 1.817407e+000,
- 5.810396e-001,
- // albedo 1, turbidity 5
- -1.230134e+000,
- -3.136264e-001,
- -8.909301e+000,
- 9.145006e+000,
- -1.055387e-002,
- 4.467317e-001,
- 1.016826e-001,
- 3.342964e+000,
- 5.633840e-001,
- -1.442907e+000,
- -5.593147e-001,
- 2.156447e+000,
- -1.241657e+000,
- -3.512130e-002,
- 3.050274e-001,
- 1.797175e-002,
- 1.742358e+000,
- 5.977153e-001,
- -1.027627e+000,
- -6.481539e-002,
- 4.351975e-001,
- -1.051677e+000,
- -2.030672e-001,
- 1.942684e+000,
- -3.615993e-002,
- 4.050266e+000,
- 9.801624e-001,
- -1.082110e+000,
- -1.578209e-001,
- -3.397511e-001,
- 4.163851e+000,
- 6.650368e-001,
- -1.841730e+000,
- 7.062544e-001,
- 6.789881e-001,
- 3.172623e-001,
- -1.047447e+000,
- -1.977560e-001,
- 2.183364e+000,
- -8.805249e+000,
- -5.483962e+000,
- 2.551309e+000,
- -1.779640e-001,
- 1.519501e+000,
- 9.212536e-001,
- -1.111853e+000,
- -1.935736e-001,
- 1.394408e+000,
- 1.392405e+001,
- -3.465430e+000,
- -1.068432e+000,
- 2.388671e-001,
- 1.455336e+000,
- 6.233425e-001,
- // albedo 1, turbidity 6
- -1.262238e+000,
- -3.546341e-001,
- -1.008703e+001,
- 1.020084e+001,
- -1.852187e-003,
- 3.537580e-001,
- 1.239199e-001,
- 3.056093e+000,
- 5.132052e-001,
- -1.613810e+000,
- -7.355585e-001,
- 2.760123e+000,
- -1.685253e+000,
- -2.517552e-002,
- 2.914258e-001,
- 4.743448e-003,
- 8.689596e-001,
- 5.674192e-001,
- -9.462336e-001,
- 2.950767e-002,
- -2.613816e-001,
- -7.398653e-001,
- -1.315558e-001,
- 1.901042e+000,
- -6.447844e-002,
- 4.969341e+000,
- 1.027342e+000,
- -1.111481e+000,
- -2.194054e-001,
- -9.004538e-002,
- 3.983442e+000,
- 4.871278e-001,
- -1.965315e+000,
- 7.956121e-001,
- -2.363225e-001,
- 2.718037e-001,
- -1.036397e+000,
- -1.827106e-001,
- 1.964747e+000,
- -8.870759e+000,
- -4.208011e+000,
- 2.461215e+000,
- -2.158905e-001,
- 1.561676e+000,
- 9.436866e-001,
- -1.113769e+000,
- -1.947819e-001,
- 1.300720e+000,
- 1.516476e+001,
- -4.088732e+000,
- -1.069384e+000,
- 2.836434e-001,
- 1.671451e+000,
- 6.229612e-001,
- // albedo 1, turbidity 7
- -1.328069e+000,
- -4.244047e-001,
- -8.417040e+000,
- 8.552244e+000,
- -6.813504e-003,
- 4.127422e-001,
- 9.619897e-002,
- 2.854227e+000,
- 5.059880e-001,
- -1.927552e+000,
- -1.025290e+000,
- 9.529576e-001,
- 4.255950e-001,
- -3.738779e-002,
- 2.584586e-001,
- 4.911004e-002,
- -2.640913e-001,
- 4.138626e-001,
- -8.488094e-001,
- 1.435988e-001,
- 6.356807e-001,
- -2.895732e+000,
- -8.473961e-002,
- 1.701305e+000,
- -1.323908e-001,
- 6.499338e+000,
- 1.210928e+000,
- -1.128313e+000,
- -3.397048e-001,
- -4.043140e-001,
- 6.265097e+000,
- 5.482395e-001,
- -2.057614e+000,
- 8.884087e-001,
- -2.943879e+000,
- 9.760301e-002,
- -1.039764e+000,
- -1.494772e-001,
- 1.781915e+000,
- -1.153012e+001,
- -3.379232e+000,
- 2.517231e+000,
- -2.764393e-001,
- 2.588849e+000,
- 1.052120e+000,
- -1.108447e+000,
- -2.012251e-001,
- 1.198640e+000,
- 1.925331e+001,
- -4.423892e+000,
- -1.257122e+000,
- 3.395690e-001,
- 1.481220e+000,
- 5.880175e-001,
- // albedo 1, turbidity 8
- -1.374185e+000,
- -4.967434e-001,
- -7.401318e+000,
- 7.724021e+000,
- -2.345723e-002,
- 5.979653e-001,
- 2.436346e-002,
- 2.658970e+000,
- 6.014891e-001,
- -2.310933e+000,
- -1.290290e+000,
- -1.301909e+000,
- 2.557806e+000,
- -3.744449e-002,
- 8.982861e-002,
- 1.090613e-001,
- -4.398363e-001,
- 1.184329e-001,
- -1.124730e+000,
- -9.921830e-002,
- 1.366902e+000,
- -4.172489e+000,
- -5.078016e-002,
- 1.393597e+000,
- -9.323843e-002,
- 6.452721e+000,
- 1.435913e+000,
- -8.468477e-001,
- -2.744819e-001,
- -4.347200e-001,
- 6.713362e+000,
- 6.127133e-001,
- -1.685634e+000,
- 7.360941e-001,
- -4.535502e+000,
- -2.920866e-002,
- -1.165242e+000,
- -2.008697e-001,
- 1.438778e+000,
- -1.008936e+001,
- -2.214771e+000,
- 2.102909e+000,
- -1.763085e-001,
- 2.859075e+000,
- 1.093470e+000,
- -1.074614e+000,
- -2.066374e-001,
- 1.131891e+000,
- 1.630063e+001,
- -4.801441e+000,
- -1.112590e+000,
- 3.595785e-001,
- 1.122227e+000,
- 5.794610e-001,
- // albedo 1, turbidity 9
- -1.521515e+000,
- -6.835604e-001,
- -5.571044e+000,
- 6.028774e+000,
- -4.253715e-002,
- 6.875746e-001,
- -5.279456e-006,
- 2.180150e+000,
- 8.487705e-001,
- -2.240415e+000,
- -1.171166e+000,
- -7.182771e+000,
- 8.417068e+000,
- -1.932866e-002,
- 1.101887e-001,
- -1.098862e-002,
- 6.242195e-001,
- -2.393875e-001,
- -2.712354e+000,
- -1.198830e+000,
- 3.180200e+000,
- -6.768130e+000,
- -2.563386e-003,
- 7.984607e-001,
- 2.764376e-001,
- 4.695358e+000,
- 1.557045e+000,
- -3.655172e-002,
- -2.142321e-002,
- -9.138120e-001,
- 7.932786e+000,
- 3.516542e-001,
- -7.994343e-001,
- 1.786761e-001,
- -4.208399e+000,
- 1.820576e-002,
- -1.368610e+000,
- -2.656212e-001,
- 1.249397e+000,
- -8.317818e+000,
- -8.962772e-001,
- 1.423249e+000,
- 1.478381e-001,
- 2.191660e+000,
- 1.007748e+000,
- -1.041753e+000,
- -2.453366e-001,
- 1.061102e+000,
- 1.130172e+001,
- -4.739312e+000,
- -9.223334e-001,
- 2.982776e-001,
- 6.162931e-001,
- 6.080302e-001,
- // albedo 1, turbidity 10
- -1.989159e+000,
- -1.095160e+000,
- -2.915550e+000,
- 3.275339e+000,
- -5.735765e-002,
- 5.742174e-001,
- -7.683288e-006,
- 1.763400e+000,
- 9.001342e-001,
- -2.070020e+000,
- -1.086338e+000,
- -1.095898e+001,
- 1.206960e+001,
- 3.780123e-002,
- -1.774699e-002,
- -5.881348e-004,
- 1.333819e+000,
- -2.605423e-001,
- -5.249653e+000,
- -2.383040e+000,
- 6.160406e+000,
- -9.097138e+000,
- -1.955319e-001,
- 1.651785e+000,
- 6.016463e-004,
- 3.021824e+000,
- 1.493574e+000,
- 4.685432e-001,
- -2.358662e-001,
- -2.666433e+000,
- 9.685763e+000,
- 5.804928e-001,
- -1.521875e+000,
- 5.668989e-001,
- -1.548136e+000,
- 1.688642e-002,
- -1.296891e+000,
- -3.449031e-001,
- 1.928548e+000,
- -1.167560e+001,
- -1.627615e+000,
- 1.355603e+000,
- -1.929074e-001,
- -6.568952e-001,
- 1.009774e+000,
- -1.067288e+000,
- -2.410392e-001,
- 7.147961e-001,
- 1.783840e+001,
- -4.374399e+000,
- -6.588777e-001,
- 3.329831e-001,
- 1.012066e+000,
- 6.118645e-001,
-};
-
-static const double datasetXYZRad2[] = {
- // albedo 0, turbidity 1
- 1.632341e+000,
- 1.395230e+000,
- 1.375634e+000,
- 1.238193e+001,
- 5.921102e+000,
- 7.766508e+000,
- // albedo 0, turbidity 2
- 1.597115e+000,
- 1.554617e+000,
- 3.932382e-001,
- 1.505284e+001,
- 5.725234e+000,
- 8.158155e+000,
- // albedo 0, turbidity 3
- 1.522034e+000,
- 1.844545e+000,
- -1.322862e+000,
- 1.918382e+001,
- 5.440769e+000,
- 8.837119e+000,
- // albedo 0, turbidity 4
- 1.403048e+000,
- 2.290852e+000,
- -4.013792e+000,
- 2.485100e+001,
- 5.521888e+000,
- 9.845547e+000,
- // albedo 0, turbidity 5
- 1.286364e+000,
- 2.774498e+000,
- -6.648221e+000,
- 2.964151e+001,
- 5.923777e+000,
- 1.097075e+001,
- // albedo 0, turbidity 6
- 1.213544e+000,
- 3.040195e+000,
- -8.092676e+000,
- 3.186082e+001,
- 6.789782e+000,
- 1.158899e+001,
- // albedo 0, turbidity 7
- 1.122622e+000,
- 3.347465e+000,
- -9.649016e+000,
- 3.343824e+001,
- 9.347715e+000,
- 1.231374e+001,
- // albedo 0, turbidity 8
- 1.007356e+000,
- 3.543858e+000,
- -1.053520e+001,
- 3.239842e+001,
- 1.483962e+001,
- 1.331718e+001,
- // albedo 0, turbidity 9
- 8.956642e-001,
- 3.278700e+000,
- -9.254933e+000,
- 2.557923e+001,
- 2.489677e+001,
- 1.476166e+001,
- // albedo 0, turbidity 10
- 7.985143e-001,
- 2.340404e+000,
- -4.928274e+000,
- 1.141787e+001,
- 3.961501e+001,
- 1.682448e+001,
- // albedo 1, turbidity 1
- 1.745162e+000,
- 1.639467e+000,
- 1.342721e+000,
- 1.166033e+001,
- 1.490124e+001,
- 1.774031e+001,
- // albedo 1, turbidity 2
- 1.708439e+000,
- 1.819144e+000,
- 2.834399e-001,
- 1.448066e+001,
- 1.459214e+001,
- 1.858679e+001,
- // albedo 1, turbidity 3
- 1.631720e+000,
- 2.094799e+000,
- -1.378825e+000,
- 1.843198e+001,
- 1.463173e+001,
- 1.962881e+001,
- // albedo 1, turbidity 4
- 1.516536e+000,
- 2.438729e+000,
- -3.624121e+000,
- 2.298621e+001,
- 1.599782e+001,
- 2.070027e+001,
- // albedo 1, turbidity 5
- 1.405863e+000,
- 2.785191e+000,
- -5.705236e+000,
- 2.645121e+001,
- 1.768330e+001,
- 2.191903e+001,
- // albedo 1, turbidity 6
- 1.344052e+000,
- 2.951807e+000,
- -6.683851e+000,
- 2.744271e+001,
- 1.985706e+001,
- 2.229452e+001,
- // albedo 1, turbidity 7
- 1.245827e+000,
- 3.182923e+000,
- -7.822960e+000,
- 2.791395e+001,
- 2.327254e+001,
- 2.315910e+001,
- // albedo 1, turbidity 8
- 1.132305e+000,
- 3.202593e+000,
- -8.008429e+000,
- 2.521093e+001,
- 3.000014e+001,
- 2.405306e+001,
- // albedo 1, turbidity 9
- 1.020330e+000,
- 2.820556e+000,
- -6.238704e+000,
- 1.709276e+001,
- 4.077916e+001,
- 2.509949e+001,
- // albedo 1, turbidity 10
- 9.031570e-001,
- 1.863917e+000,
- -1.955738e+000,
- 3.032665e+000,
- 5.434290e+001,
- 2.641780e+001,
-};
-
-static const double datasetXYZ3[] = {
- // albedo 0, turbidity 1
- -1.310023e+000,
- -4.407658e-001,
- -3.640340e+001,
- 3.683292e+001,
- -8.124762e-003,
- 5.297961e-001,
- 1.188633e-002,
- 3.138320e+000,
- 5.134778e-001,
- -1.424100e+000,
- -5.501606e-001,
- -1.753510e+001,
- 1.822769e+001,
- -1.539272e-002,
- 6.366826e-001,
- 2.661996e-003,
- 2.659915e+000,
- 4.071138e-001,
- -1.103436e+000,
- -1.884105e-001,
- 6.425322e+000,
- -6.910579e+000,
- -2.019861e-002,
- 3.553271e-001,
- -1.589061e-002,
- 5.345985e+000,
- 8.790218e-001,
- -1.186200e+000,
- -4.307514e-001,
- -3.957947e+000,
- 5.979352e+000,
- -5.348869e-002,
- 1.736117e+000,
- 3.491346e-002,
- -2.692261e+000,
- 5.610506e-001,
- -1.006038e+000,
- -1.305995e-001,
- 4.473513e+000,
- -3.806719e+000,
- 1.419407e-001,
- -2.148238e-002,
- -5.081185e-002,
- 3.735362e+000,
- 5.358280e-001,
- -1.078507e+000,
- -1.633754e-001,
- -3.812368e+000,
- 4.381700e+000,
- 2.988122e-002,
- 1.754224e+000,
- 1.472376e-001,
- 3.722798e+000,
- 4.999157e-001,
- // albedo 0, turbidity 2
- -1.333582e+000,
- -4.649908e-001,
- -3.359528e+001,
- 3.404375e+001,
- -9.384242e-003,
- 5.587511e-001,
- 5.726310e-003,
- 3.073145e+000,
- 5.425529e-001,
- -1.562624e+000,
- -7.107068e-001,
- -1.478170e+001,
- 1.559839e+001,
- -1.462375e-002,
- 5.050133e-001,
- 2.516017e-002,
- 1.604696e+000,
- 2.902403e-001,
- -8.930158e-001,
- 4.068077e-002,
- 1.373481e+000,
- -2.342752e+000,
- -2.098058e-002,
- 6.248686e-001,
- -5.258363e-002,
- 7.058214e+000,
- 1.150373e+000,
- -1.262823e+000,
- -4.818353e-001,
- 8.892610e-004,
- 1.923120e+000,
- -4.979718e-002,
- 1.040693e+000,
- 1.558103e-001,
- -2.852480e+000,
- 2.420691e-001,
- -9.968383e-001,
- -1.200648e-001,
- 1.324342e+000,
- -9.430889e-001,
- 1.931098e-001,
- 4.436916e-001,
- -7.320456e-002,
- 4.215931e+000,
- 7.898019e-001,
- -1.078185e+000,
- -1.718192e-001,
- -1.720191e+000,
- 2.358918e+000,
- 2.765637e-002,
- 1.260245e+000,
- 2.021941e-001,
- 3.395483e+000,
- 5.173628e-001,
- // albedo 0, turbidity 3
- -1.353023e+000,
- -4.813523e-001,
- -3.104920e+001,
- 3.140156e+001,
- -9.510741e-003,
- 5.542030e-001,
- 8.135471e-003,
- 3.136646e+000,
- 5.215989e-001,
- -1.624704e+000,
- -7.990201e-001,
- -2.167125e+001,
- 2.246341e+001,
- -1.163533e-002,
- 5.415746e-001,
- 2.618378e-002,
- 1.139214e+000,
- 3.444357e-001,
- -7.983610e-001,
- 1.417476e-001,
- 9.914841e+000,
- -1.081503e+001,
- -1.218845e-002,
- 3.411392e-001,
- -6.137698e-002,
- 7.445848e+000,
- 1.180080e+000,
- -1.266679e+000,
- -4.288977e-001,
- -5.818701e+000,
- 6.986437e+000,
- -8.180711e-002,
- 1.397403e+000,
- 2.016916e-001,
- -1.275731e+000,
- 2.592773e-001,
- -1.009707e+000,
- -1.537754e-001,
- 3.496378e+000,
- -3.013726e+000,
- 2.421150e-001,
- -2.831925e-001,
- 3.003395e-002,
- 3.702862e+000,
- 7.746320e-001,
- -1.075646e+000,
- -1.768747e-001,
- -1.347762e+000,
- 1.989004e+000,
- 1.375836e-002,
- 1.764810e+000,
- 1.330018e-001,
- 3.230864e+000,
- 6.626210e-001,
- // albedo 0, turbidity 4
- -1.375269e+000,
- -5.103569e-001,
- -3.442661e+001,
- 3.478703e+001,
- -8.460009e-003,
- 5.408643e-001,
- 4.813323e-003,
- 3.016078e+000,
- 5.062069e-001,
- -1.821679e+000,
- -9.766461e-001,
- -1.926488e+001,
- 1.997912e+001,
- -9.822567e-003,
- 3.649556e-001,
- 4.316092e-002,
- 8.930190e-001,
- 4.166527e-001,
- -6.633542e-001,
- 1.997841e-001,
- 2.395592e+000,
- -3.117175e+000,
- -1.080884e-002,
- 8.983814e-001,
- -1.375825e-001,
- 6.673463e+000,
- 1.115663e+000,
- -1.303240e+000,
- -3.612712e-001,
- 8.292959e-002,
- 3.381364e-001,
- -6.078648e-002,
- 3.229247e-001,
- 3.680987e-001,
- 7.046755e-001,
- 3.144924e-001,
- -9.952598e-001,
- -2.039076e-001,
- 4.026851e-001,
- 2.686684e-001,
- 1.640712e-001,
- 5.186341e-001,
- -1.205520e-002,
- 2.659613e+000,
- 8.030394e-001,
- -1.098579e+000,
- -2.151992e-001,
- 6.558198e-001,
- -7.436900e-004,
- -1.421817e-003,
- 1.073701e+000,
- 1.886875e-001,
- 2.536857e+000,
- 6.673923e-001,
- // albedo 0, turbidity 5
- -1.457986e+000,
- -5.906842e-001,
- -3.812464e+001,
- 3.838539e+001,
- -6.024357e-003,
- 4.741484e-001,
- 1.209223e-002,
- 2.818432e+000,
- 5.012433e-001,
- -1.835728e+000,
- -1.003405e+000,
- -6.848129e+000,
- 7.601943e+000,
- -1.277375e-002,
- 4.785598e-001,
- 3.366853e-002,
- 1.097701e+000,
- 4.636635e-001,
- -8.491348e-001,
- 9.466365e-003,
- -2.685226e+000,
- 2.004060e+000,
- -1.168708e-002,
- 6.752316e-001,
- -1.543371e-001,
- 5.674759e+000,
- 1.039534e+000,
- -1.083379e+000,
- -1.506790e-001,
- 7.328236e-001,
- -5.095568e-001,
- -8.609153e-002,
- 4.448820e-001,
- 4.174662e-001,
- 1.481556e+000,
- 3.942551e-001,
- -1.117089e+000,
- -3.337605e-001,
- 2.502281e-001,
- 4.036323e-001,
- 2.673899e-001,
- 2.829817e-001,
- 2.242450e-002,
- 2.043207e+000,
- 7.706902e-001,
- -1.071648e+000,
- -2.126200e-001,
- 6.069466e-001,
- -1.456290e-003,
- -5.515960e-001,
- 1.046755e+000,
- 1.985021e-001,
- 2.290245e+000,
- 6.876058e-001,
- // albedo 0, turbidity 6
- -1.483903e+000,
- -6.309647e-001,
- -4.380213e+001,
- 4.410537e+001,
- -5.712161e-003,
- 5.195992e-001,
- 2.028428e-003,
- 2.687114e+000,
- 5.098321e-001,
- -2.053976e+000,
- -1.141473e+000,
- 5.109183e-001,
- 8.060391e-002,
- -1.033983e-002,
- 4.066532e-001,
- 4.869627e-002,
- 1.161722e+000,
- 4.039525e-001,
- -6.348185e-001,
- 7.651292e-002,
- -1.031327e+001,
- 1.007598e+001,
- -2.083688e-002,
- 7.359516e-001,
- -2.029459e-001,
- 5.013257e+000,
- 1.077649e+000,
- -1.228630e+000,
- -1.650496e-001,
- 4.077157e-002,
- -7.189167e-001,
- -5.092220e-002,
- 2.959814e-001,
- 5.111496e-001,
- 2.540433e+000,
- 3.615330e-001,
- -1.041883e+000,
- -3.278413e-001,
- -6.691911e-002,
- 1.307364e+000,
- 2.166663e-001,
- 3.000595e-001,
- -3.157136e-003,
- 1.389208e+000,
- 7.999026e-001,
- -1.103556e+000,
- -2.443602e-001,
- 4.705347e-001,
- -9.296482e-004,
- -5.309920e-001,
- 9.654511e-001,
- 2.142587e-001,
- 2.244723e+000,
- 6.839976e-001,
- // albedo 0, turbidity 7
- -1.555684e+000,
- -6.962113e-001,
- -4.647983e+001,
- 4.674270e+001,
- -5.034895e-003,
- 4.755090e-001,
- -9.502561e-007,
- 2.626569e+000,
- 5.056194e-001,
- -1.998288e+000,
- -1.124720e+000,
- -1.629586e+000,
- 2.187993e+000,
- -8.284384e-003,
- 3.845258e-001,
- 5.726240e-002,
- 1.185644e+000,
- 4.255812e-001,
- -1.032570e+000,
- -2.513850e-001,
- -3.721112e+000,
- 3.506967e+000,
- -2.186561e-002,
- 9.436049e-001,
- -2.451412e-001,
- 4.725724e+000,
- 1.039256e+000,
- -8.597532e-001,
- 9.073332e-002,
- -2.553741e+000,
- 1.993237e+000,
- -4.390891e-002,
- -2.046928e-001,
- 5.515623e-001,
- 1.909127e+000,
- 3.948212e-001,
- -1.210482e+000,
- -4.477622e-001,
- -2.267805e-001,
- 1.219488e+000,
- 1.336186e-001,
- 6.866897e-001,
- 2.808997e-002,
- 1.600403e+000,
- 7.816409e-001,
- -1.078168e+000,
- -2.699261e-001,
- 2.537282e-001,
- 3.820684e-001,
- -4.425103e-001,
- 5.298235e-001,
- 2.185217e-001,
- 1.728679e+000,
- 6.882743e-001,
- // albedo 0, turbidity 8
- -1.697968e+000,
- -8.391488e-001,
- -5.790105e+001,
- 5.814120e+001,
- -3.404760e-003,
- 4.265140e-001,
- -1.796301e-006,
- 2.368442e+000,
- 5.324429e-001,
- -2.141552e+000,
- -1.172230e+000,
- 1.677872e+001,
- -1.641470e+001,
- -5.732425e-003,
- 2.002199e-001,
- 6.841834e-002,
- 1.485338e+000,
- 3.215763e-001,
- -1.442946e+000,
- -7.264245e-001,
- -9.503706e+000,
- 9.650462e+000,
- -2.120995e-002,
- 1.419263e+000,
- -2.893098e-001,
- 3.860731e+000,
- 1.120857e+000,
- -5.696752e-001,
- 3.411279e-001,
- -2.931035e-001,
- -6.512552e-001,
- -1.068437e-001,
- -1.085661e+000,
- 6.107549e-001,
- 1.459503e+000,
- 3.210336e-001,
- -1.313839e+000,
- -5.921371e-001,
- -2.332222e-001,
- 1.648196e+000,
- 2.492787e-001,
- 1.381033e+000,
- -1.993392e-002,
- 9.812560e-001,
- 8.316329e-001,
- -1.087464e+000,
- -3.195534e-001,
- 2.902095e-001,
- 3.383709e-001,
- -8.798482e-001,
- 1.494668e-002,
- 2.529703e-001,
- 1.452644e+000,
- 6.693870e-001,
- // albedo 0, turbidity 9
- -2.068582e+000,
- -1.118605e+000,
- -5.081598e+001,
- 5.097486e+001,
- -3.280669e-003,
- 4.067371e-001,
- -2.544951e-006,
- 2.179497e+000,
- 5.778017e-001,
- -1.744693e+000,
- -8.537207e-001,
- 2.234361e+001,
- -2.208318e+001,
- -5.932616e-003,
- 1.035049e-001,
- 5.742772e-002,
- 1.977880e+000,
- 2.124846e-001,
- -3.287515e+000,
- -2.140268e+000,
- -1.249566e+001,
- 1.240091e+001,
- -2.409349e-002,
- 1.397821e+000,
- -2.371627e-001,
- 2.771192e+000,
- 1.170496e+000,
- 5.502311e-001,
- 1.046630e+000,
- 2.193517e+000,
- -2.220400e+000,
- -1.064394e-001,
- -1.017926e+000,
- 4.795457e-001,
- 1.030644e+000,
- 3.177516e-001,
- -1.719734e+000,
- -9.536198e-001,
- -6.586821e-001,
- 1.386361e+000,
- -2.513065e-002,
- 1.187011e+000,
- 6.542539e-002,
- 5.296055e-001,
- 8.082660e-001,
- -1.005700e+000,
- -3.028096e-001,
- 4.470957e-002,
- 1.007760e+000,
- -8.119016e-001,
- 3.153338e-002,
- 2.311321e-001,
- 1.182208e+000,
- 6.824758e-001,
- // albedo 0, turbidity 10
- -2.728867e+000,
- -1.580388e+000,
- -3.079627e+001,
- 3.092586e+001,
- -4.197673e-003,
- 3.154759e-001,
- -3.897675e-006,
- 1.920567e+000,
- 6.664791e-001,
- -1.322495e+000,
- -7.249275e-001,
- 1.477660e+001,
- -1.468154e+001,
- -9.044857e-003,
- 5.624314e-002,
- 6.498392e-002,
- 2.047389e+000,
- 6.367540e-002,
- -6.102376e+000,
- -3.473018e+000,
- -9.926071e+000,
- 9.637797e+000,
- -1.097909e-002,
- 1.103498e+000,
- -2.424521e-001,
- 2.520748e+000,
- 1.240260e+000,
- 1.351796e+000,
- 1.018588e+000,
- 2.009081e+000,
- -1.333394e+000,
- -1.979125e-001,
- -3.318292e-001,
- 4.476624e-001,
- 9.095235e-001,
- 2.955611e-001,
- -1.774467e+000,
- -1.079880e+000,
- -8.084680e-002,
- 2.577697e-001,
- -1.149295e-001,
- 4.975303e-001,
- 2.931611e-003,
- -3.803171e-001,
- 8.002794e-001,
- -9.898401e-001,
- -2.542513e-001,
- -7.530911e-002,
- 1.870355e+000,
- -1.521918e+000,
- 2.405164e-001,
- 2.964615e-001,
- 1.334800e+000,
- 6.789053e-001,
- // albedo 1, turbidity 1
- -1.279730e+000,
- -4.290674e-001,
- -4.277972e+001,
- 4.343305e+001,
- -6.541826e-003,
- 4.945086e-001,
- 1.425338e-002,
- 2.685244e+000,
- 5.011313e-001,
- -1.449506e+000,
- -5.766374e-001,
- -1.688496e+001,
- 1.781118e+001,
- -1.121649e-002,
- 3.545020e-001,
- 2.287338e-002,
- 1.904281e+000,
- 4.936998e-001,
- -1.021980e+000,
- -1.897574e-001,
- 2.482462e+000,
- -2.941725e+000,
- -1.570448e-002,
- 7.532578e-001,
- -4.256800e-002,
- 5.239660e+000,
- 4.983116e-001,
- -1.162608e+000,
- -3.428049e-001,
- 3.974358e+000,
- -1.527935e+000,
- -3.919201e-002,
- 8.758593e-001,
- 7.291363e-002,
- -3.455257e+000,
- 8.007426e-001,
- -9.929985e-001,
- -8.712006e-002,
- -7.397313e-001,
- 1.348372e+000,
- 9.511685e-002,
- 3.233584e-001,
- -7.549148e-002,
- 5.806452e+000,
- 4.990042e-001,
- -1.084996e+000,
- -1.739767e-001,
- 1.580475e-001,
- 9.088180e-001,
- 6.871433e-002,
- 5.933079e-001,
- 1.188921e-001,
- 3.074079e+000,
- 4.999327e-001,
- // albedo 1, turbidity 2
- -1.317009e+000,
- -4.661946e-001,
- -4.255347e+001,
- 4.312782e+001,
- -5.727235e-003,
- 4.285447e-001,
- 2.189854e-002,
- 2.608310e+000,
- 5.190700e-001,
- -1.469236e+000,
- -6.282139e-001,
- -1.241404e+001,
- 1.348765e+001,
- -1.204770e-002,
- 5.070285e-001,
- -7.280216e-004,
- 1.491533e+000,
- 3.635064e-001,
- -9.713808e-001,
- -8.138038e-002,
- 3.709854e-001,
- -1.041174e+000,
- -1.814075e-002,
- 5.060860e-001,
- -2.053756e-002,
- 6.161431e+000,
- 1.093736e+000,
- -1.159057e+000,
- -3.698074e-001,
- 2.711209e+000,
- -6.006479e-001,
- -4.896926e-002,
- 9.273957e-001,
- 1.137712e-001,
- -3.496828e+000,
- 2.867109e-001,
- -1.011601e+000,
- -8.201890e-002,
- 2.105725e-001,
- 4.597520e-001,
- 1.478925e-001,
- 2.138940e-001,
- -5.660670e-002,
- 6.057755e+000,
- 7.859121e-001,
- -1.078020e+000,
- -1.811580e-001,
- 1.646622e-001,
- 8.348426e-001,
- 1.149064e-001,
- 4.985738e-001,
- 1.376605e-001,
- 2.746607e+000,
- 4.999626e-001,
- // albedo 1, turbidity 3
- -1.325672e+000,
- -4.769313e-001,
- -4.111215e+001,
- 4.168293e+001,
- -6.274997e-003,
- 4.649469e-001,
- 1.119411e-002,
- 2.631267e+000,
- 5.234546e-001,
- -1.619391e+000,
- -8.000253e-001,
- -1.534098e+001,
- 1.632706e+001,
- -1.012023e-002,
- 4.242255e-001,
- 2.931597e-002,
- 8.925807e-001,
- 3.314765e-001,
- -7.356979e-001,
- 1.368406e-001,
- 2.972579e+000,
- -3.535359e+000,
- -1.318948e-002,
- 4.607620e-001,
- -7.182778e-002,
- 6.254100e+000,
- 1.236299e+000,
- -1.316217e+000,
- -4.194427e-001,
- 3.489902e-002,
- 1.289849e+000,
- -4.755960e-002,
- 1.138222e+000,
- 1.975992e-001,
- -8.991542e-001,
- 2.290572e-001,
- -9.502188e-001,
- -1.172703e-001,
- 1.405202e+000,
- -3.061919e-001,
- 1.058772e-001,
- -3.760592e-001,
- -1.983179e-002,
- 3.562353e+000,
- 7.895959e-001,
- -1.100117e+000,
- -1.900567e-001,
- 4.925030e-001,
- 5.250225e-001,
- 1.576804e-001,
- 1.042701e+000,
- 7.330743e-002,
- 2.796064e+000,
- 6.749783e-001,
- // albedo 1, turbidity 4
- -1.354183e+000,
- -5.130625e-001,
- -4.219268e+001,
- 4.271772e+001,
- -5.365373e-003,
- 4.136743e-001,
- 1.235172e-002,
- 2.520122e+000,
- 5.187269e-001,
- -1.741434e+000,
- -9.589761e-001,
- -8.230339e+000,
- 9.296799e+000,
- -9.600162e-003,
- 4.994969e-001,
- 2.955452e-002,
- 3.667099e-001,
- 3.526999e-001,
- -6.917347e-001,
- 2.154887e-001,
- -8.760264e-001,
- 2.334121e-001,
- -1.909621e-002,
- 4.748033e-001,
- -1.138514e-001,
- 6.515360e+000,
- 1.225097e+000,
- -1.293189e+000,
- -4.218700e-001,
- 1.620952e+000,
- -7.858597e-001,
- -3.769410e-002,
- 6.636786e-001,
- 3.364945e-001,
- -5.341017e-001,
- 2.128347e-001,
- -9.735521e-001,
- -1.325495e-001,
- 1.007517e+000,
- 2.598258e-001,
- 6.762169e-002,
- 1.421018e-003,
- -6.915987e-002,
- 3.185897e+000,
- 8.641956e-001,
- -1.094800e+000,
- -1.962062e-001,
- 5.755591e-001,
- 2.906259e-001,
- 2.625748e-001,
- 7.644049e-001,
- 1.347492e-001,
- 2.677126e+000,
- 6.465460e-001,
- // albedo 1, turbidity 5
- -1.393063e+000,
- -5.578338e-001,
- -4.185249e+001,
- 4.233504e+001,
- -5.435640e-003,
- 4.743765e-001,
- 7.422477e-003,
- 2.442801e+000,
- 5.211707e-001,
- -1.939487e+000,
- -1.128509e+000,
- -8.974257e+000,
- 9.978383e+000,
- -7.965597e-003,
- 2.948830e-001,
- 4.436763e-002,
- 2.839868e-001,
- 3.440424e-001,
- -6.011562e-001,
- 2.354877e-001,
- -3.079820e+000,
- 2.585094e+000,
- -2.002701e-002,
- 7.793909e-001,
- -1.598414e-001,
- 5.834678e+000,
- 1.202856e+000,
- -1.315676e+000,
- -3.903446e-001,
- 1.701900e+000,
- -1.304609e+000,
- -1.045121e-002,
- 2.747707e-001,
- 4.143967e-001,
- 3.197102e-001,
- 2.637580e-001,
- -9.618628e-001,
- -1.625841e-001,
- 1.187138e+000,
- 1.497802e-001,
- -5.590954e-006,
- 3.178475e-002,
- -4.153145e-002,
- 2.496096e+000,
- 8.195082e-001,
- -1.111554e+000,
- -2.365546e-001,
- 7.831875e-001,
- 2.018684e-001,
- 2.074369e-001,
- 7.395978e-001,
- 1.225730e-001,
- 1.876478e+000,
- 6.821167e-001,
- // albedo 1, turbidity 6
- -1.427879e+000,
- -5.994879e-001,
- -3.531016e+001,
- 3.581581e+001,
- -6.431497e-003,
- 4.554192e-001,
- 7.348731e-004,
- 2.334619e+000,
- 5.233377e-001,
- -1.998177e+000,
- -1.206633e+000,
- -2.146510e+001,
- 2.242237e+001,
- -5.857596e-003,
- 2.755663e-001,
- 6.384795e-002,
- 1.358244e-001,
- 3.328437e-001,
- -6.440630e-001,
- 2.058571e-001,
- 2.155499e+000,
- -2.587968e+000,
- -1.840023e-002,
- 8.826555e-001,
- -2.222452e-001,
- 5.847073e+000,
- 1.228387e+000,
- -1.229071e+000,
- -3.360441e-001,
- -3.429599e-001,
- 6.179469e-001,
- 2.029610e-003,
- 8.899319e-002,
- 5.041624e-001,
- 1.882964e-001,
- 2.252040e-001,
- -1.022905e+000,
- -2.101621e-001,
- 1.915689e+000,
- -6.498794e-001,
- -3.463651e-002,
- 8.954605e-002,
- -6.797854e-002,
- 2.417705e+000,
- 8.568618e-001,
- -1.082538e+000,
- -2.007723e-001,
- 4.731009e-001,
- 4.077267e-001,
- 1.324289e-001,
- 6.514880e-001,
- 1.702912e-001,
- 2.309383e+000,
- 6.600895e-001,
- // albedo 1, turbidity 7
- -1.472139e+000,
- -6.499815e-001,
- -3.428465e+001,
- 3.469659e+001,
- -5.747023e-003,
- 4.174167e-001,
- 1.688597e-003,
- 2.323046e+000,
- 5.395191e-001,
- -2.161176e+000,
- -1.353089e+000,
- -2.226827e+001,
- 2.329138e+001,
- -5.583808e-003,
- 2.364793e-001,
- 6.096656e-002,
- 1.944666e-003,
- 2.861624e-001,
- -6.593044e-001,
- 1.393558e-001,
- 4.698373e+000,
- -5.193883e+000,
- -1.998390e-002,
- 1.095635e+000,
- -2.391254e-001,
- 5.598103e+000,
- 1.236193e+000,
- -1.195717e+000,
- -2.972715e-001,
- 4.648953e-002,
- 3.024588e-001,
- 5.003313e-003,
- -3.754741e-001,
- 5.247265e-001,
- -1.381312e-001,
- 2.493896e-001,
- -1.020139e+000,
- -2.253524e-001,
- 3.548437e-001,
- 7.030485e-001,
- -2.107076e-002,
- 4.581395e-001,
- -3.243757e-002,
- 2.453259e+000,
- 8.323623e-001,
- -1.098770e+000,
- -2.435780e-001,
- 8.761614e-001,
- 1.941613e-001,
- -1.990692e-001,
- 3.761139e-001,
- 1.657412e-001,
- 1.590503e+000,
- 6.741417e-001,
- // albedo 1, turbidity 8
- -1.648007e+000,
- -8.205121e-001,
- -4.435106e+001,
- 4.479801e+001,
- -4.181353e-003,
- 3.854830e-001,
- -1.842385e-006,
- 2.000281e+000,
- 5.518363e-001,
- -2.140986e+000,
- -1.282239e+000,
- -3.979213e+000,
- 4.672459e+000,
- -5.008582e-003,
- 2.421920e-001,
- 6.253602e-002,
- 6.612713e-001,
- 2.555851e-001,
- -1.300502e+000,
- -5.137898e-001,
- 5.179821e-001,
- -4.032341e-001,
- -2.066785e-002,
- 1.087929e+000,
- -2.615309e-001,
- 4.225887e+000,
- 1.229237e+000,
- -6.963340e-001,
- 9.241060e-002,
- 6.936356e-002,
- -3.588571e-001,
- -5.461843e-002,
- -5.616643e-001,
- 5.484166e-001,
- -4.776267e-002,
- 2.414935e-001,
- -1.233179e+000,
- -4.325498e-001,
- 6.479813e-001,
- 8.368356e-001,
- 2.458875e-001,
- 6.464752e-001,
- -2.897097e-002,
- 1.561773e+000,
- 8.518598e-001,
- -1.051023e+000,
- -2.533690e-001,
- 1.004294e+000,
- 3.028083e-001,
- -1.520108e+000,
- 1.607013e-001,
- 1.619975e-001,
- 1.131094e+000,
- 6.706655e-001,
- // albedo 1, turbidity 9
- -1.948249e+000,
- -1.097383e+000,
- -4.453697e+001,
- 4.494902e+001,
- -3.579939e-003,
- 3.491605e-001,
- -2.500253e-006,
- 1.740442e+000,
- 6.188022e-001,
- -2.154253e+000,
- -1.209559e+000,
- 4.144894e+000,
- -3.562411e+000,
- -5.638843e-003,
- 1.067169e-001,
- 7.594858e-002,
- 1.005280e+000,
- 1.072543e-001,
- -2.513259e+000,
- -1.507208e+000,
- -1.602979e+000,
- 1.404154e+000,
- -5.560750e-003,
- 1.240490e+000,
- -2.852117e-001,
- 3.485252e+000,
- 1.349321e+000,
- -7.832214e-002,
- 3.655626e-001,
- 3.856288e-001,
- 6.867894e-001,
- -1.609523e-001,
- -6.704306e-001,
- 5.357301e-001,
- -6.457935e-001,
- 1.479503e-001,
- -1.354784e+000,
- -5.454375e-001,
- 8.797469e-001,
- -1.466514e+000,
- 7.134420e-001,
- 5.934903e-001,
- -2.911178e-002,
- 8.643737e-001,
- 9.030724e-001,
- -1.048324e+000,
- -2.738736e-001,
- 8.783074e-001,
- 3.246188e+000,
- -4.435369e+000,
- 1.251791e-001,
- 1.783486e-001,
- 1.064657e+000,
- 6.522878e-001,
- // albedo 1, turbidity 10
- -2.770408e+000,
- -1.618911e+000,
- -2.504031e+001,
- 2.531674e+001,
- -4.239279e-003,
- 3.241013e-001,
- -3.764484e-006,
- 1.586843e+000,
- 7.035906e-001,
- -1.913500e+000,
- -1.144014e+000,
- -1.080587e+001,
- 1.153677e+001,
- -1.003197e-002,
- 1.577515e-001,
- 5.217789e-002,
- 1.225278e+000,
- 5.172771e-003,
- -5.293208e+000,
- -2.876463e+000,
- 2.087053e+000,
- -3.201552e+000,
- 3.892964e-003,
- 5.323930e-001,
- -2.034512e-001,
- 2.617760e+000,
- 1.273597e+000,
- 9.060340e-001,
- 3.773409e-001,
- -6.399945e-001,
- 3.213979e+000,
- -9.112172e-002,
- 6.494055e-001,
- 3.953280e-001,
- 5.047796e-001,
- 2.998695e-001,
- -1.482179e+000,
- -6.778310e-001,
- 1.161775e+000,
- -3.004872e+000,
- 4.774797e-001,
- -4.969248e-001,
- -3.512074e-003,
- -1.307190e+000,
- 7.927378e-001,
- -9.863181e-001,
- -1.803364e-001,
- 5.810824e-001,
- 4.580570e+000,
- -3.863454e+000,
- 5.328174e-001,
- 2.272821e-001,
- 1.771114e+000,
- 6.791814e-001,
-};
-
-static const double datasetXYZRad3[] = {
- // albedo 0, turbidity 1
- 1.168084e+000,
- 2.156455e+000,
- -3.980314e+000,
- 1.989302e+001,
- 1.328335e+001,
- 1.435621e+001,
- // albedo 0, turbidity 2
- 1.135488e+000,
- 2.294701e+000,
- -4.585886e+000,
- 2.090208e+001,
- 1.347840e+001,
- 1.467658e+001,
- // albedo 0, turbidity 3
- 1.107408e+000,
- 2.382765e+000,
- -5.112357e+000,
- 2.147823e+001,
- 1.493128e+001,
- 1.460882e+001,
- // albedo 0, turbidity 4
- 1.054193e+000,
- 2.592891e+000,
- -6.115000e+000,
- 2.268967e+001,
- 1.635672e+001,
- 1.518999e+001,
- // albedo 0, turbidity 5
- 1.006946e+000,
- 2.705420e+000,
- -6.698930e+000,
- 2.291830e+001,
- 1.834324e+001,
- 1.570651e+001,
- // albedo 0, turbidity 6
- 9.794044e-001,
- 2.742440e+000,
- -6.805283e+000,
- 2.225271e+001,
- 2.050797e+001,
- 1.563130e+001,
- // albedo 0, turbidity 7
- 9.413577e-001,
- 2.722009e+000,
- -6.760707e+000,
- 2.098242e+001,
- 2.342588e+001,
- 1.605011e+001,
- // albedo 0, turbidity 8
- 8.917923e-001,
- 2.592780e+000,
- -6.152635e+000,
- 1.774141e+001,
- 2.858324e+001,
- 1.657910e+001,
- // albedo 0, turbidity 9
- 8.288391e-001,
- 2.153434e+000,
- -4.118327e+000,
- 1.078118e+001,
- 3.681710e+001,
- 1.738139e+001,
- // albedo 0, turbidity 10
- 7.623528e-001,
- 1.418187e+000,
- -8.845235e-001,
- 7.590129e-001,
- 4.629859e+001,
- 1.921657e+001,
- // albedo 1, turbidity 1
- 1.352858e+000,
- 2.048862e+000,
- -2.053393e+000,
- 1.405874e+001,
- 3.045344e+001,
- 3.044430e+001,
- // albedo 1, turbidity 2
- 1.330497e+000,
- 2.126497e+000,
- -2.466296e+000,
- 1.467559e+001,
- 3.090738e+001,
- 3.069707e+001,
- // albedo 1, turbidity 3
- 1.286344e+000,
- 2.200436e+000,
- -2.877228e+000,
- 1.492701e+001,
- 3.236288e+001,
- 3.077223e+001,
- // albedo 1, turbidity 4
- 1.234428e+000,
- 2.289628e+000,
- -3.404699e+000,
- 1.499436e+001,
- 3.468390e+001,
- 3.084842e+001,
- // albedo 1, turbidity 5
- 1.178660e+000,
- 2.306071e+000,
- -3.549159e+000,
- 1.411006e+001,
- 3.754188e+001,
- 3.079730e+001,
- // albedo 1, turbidity 6
- 1.151366e+000,
- 2.333005e+000,
- -3.728627e+000,
- 1.363374e+001,
- 3.905894e+001,
- 3.092599e+001,
- // albedo 1, turbidity 7
- 1.101593e+000,
- 2.299422e+000,
- -3.565787e+000,
- 1.196745e+001,
- 4.188472e+001,
- 3.102755e+001,
- // albedo 1, turbidity 8
- 1.038322e+000,
- 2.083539e+000,
- -2.649585e+000,
- 8.037389e+000,
- 4.700869e+001,
- 3.065948e+001,
- // albedo 1, turbidity 9
- 9.596146e-001,
- 1.671470e+000,
- -8.751538e-001,
- 1.679772e+000,
- 5.345784e+001,
- 3.054520e+001,
- // albedo 1, turbidity 10
- 8.640731e-001,
- 9.858301e-001,
- 1.854956e+000,
- -6.798097e+000,
- 5.936468e+001,
- 3.110255e+001,
-};
-
-static const double *datasetsXYZ[] = {datasetXYZ1, datasetXYZ2, datasetXYZ3};
-
-static const double *datasetsXYZRad[] = {datasetXYZRad1, datasetXYZRad2, datasetXYZRad3};
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_sky_nishita.cpp b/intern/cycles/util/util_sky_nishita.cpp
deleted file mode 100644
index 92397804d43..00000000000
--- a/intern/cycles/util/util_sky_nishita.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * 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 "util/util_math.h"
-#include "util/util_sky_model.h"
-
-CCL_NAMESPACE_BEGIN
-
-/* Constants */
-static const float rayleigh_scale = 8000.0f; // Rayleigh scale height (m)
-static const float mie_scale = 1200.0f; // Mie scale height (m)
-static const float mie_coeff = 2e-5f; // Mie scattering coefficient
-static const float mie_G = 0.76f; // aerosols anisotropy
-static const float earth_radius = 6360000.0f; // radius of Earth (m)
-static const float atmosphere_radius = 6420000.0f; // radius of atmosphere (m)
-static const int steps = 32; // segments per primary ray
-static const int steps_light = 16; // segments per sun connection ray
-static const int num_wavelengths = 21; // number of wavelengths
-/* irradiance at top of atmosphere */
-static const float irradiance[] = {
- 1.45756829855592995315f, 1.56596305559738380175f, 1.65148449067670455293f,
- 1.71496242737209314555f, 1.75797983805020541226f, 1.78256407885924539336f,
- 1.79095108475838560302f, 1.78541550133410664714f, 1.76815554864306845317f,
- 1.74122069647250410362f, 1.70647127164943679389f, 1.66556087452739887134f,
- 1.61993437242451854274f, 1.57083597368892080581f, 1.51932335059305478886f,
- 1.46628494965214395407f, 1.41245852740172450623f, 1.35844961970384092709f,
- 1.30474913844739281998f, 1.25174963272610817455f, 1.19975998755420620867f};
-/* Rayleigh scattering coefficient */
-static const float rayleigh_coeff[] = {
- 0.00005424820087636473f, 0.00004418549866505454f, 0.00003635151910165377f,
- 0.00003017929012024763f, 0.00002526320226989157f, 0.00002130859310621843f,
- 0.00001809838025320633f, 0.00001547057129129042f, 0.00001330284977336850f,
- 0.00001150184784075764f, 0.00000999557429990163f, 0.00000872799973630707f,
- 0.00000765513700977967f, 0.00000674217203751443f, 0.00000596134125832052f,
- 0.00000529034598065810f, 0.00000471115687557433f, 0.00000420910481110487f,
- 0.00000377218381260133f, 0.00000339051255477280f, 0.00000305591531679811f};
-/* Ozone absorption coefficient */
-static const float ozone_coeff[] = {
- 0.00000000325126849861f, 0.00000000585395365047f, 0.00000001977191155085f,
- 0.00000007309568762914f, 0.00000020084561514287f, 0.00000040383958096161f,
- 0.00000063551335912363f, 0.00000096707041180970f, 0.00000154797400424410f,
- 0.00000209038647223331f, 0.00000246128056164565f, 0.00000273551299461512f,
- 0.00000215125863128643f, 0.00000159051840791988f, 0.00000112356197979857f,
- 0.00000073527551487574f, 0.00000046450130357806f, 0.00000033096079921048f,
- 0.00000022512612292678f, 0.00000014879129266490f, 0.00000016828623364192f};
-/* CIE XYZ color matching functions */
-static const float cmf_xyz[][3] = {{0.00136800000f, 0.00003900000f, 0.00645000100f},
- {0.01431000000f, 0.00039600000f, 0.06785001000f},
- {0.13438000000f, 0.00400000000f, 0.64560000000f},
- {0.34828000000f, 0.02300000000f, 1.74706000000f},
- {0.29080000000f, 0.06000000000f, 1.66920000000f},
- {0.09564000000f, 0.13902000000f, 0.81295010000f},
- {0.00490000000f, 0.32300000000f, 0.27200000000f},
- {0.06327000000f, 0.71000000000f, 0.07824999000f},
- {0.29040000000f, 0.95400000000f, 0.02030000000f},
- {0.59450000000f, 0.99500000000f, 0.00390000000f},
- {0.91630000000f, 0.87000000000f, 0.00165000100f},
- {1.06220000000f, 0.63100000000f, 0.00080000000f},
- {0.85444990000f, 0.38100000000f, 0.00019000000f},
- {0.44790000000f, 0.17500000000f, 0.00002000000f},
- {0.16490000000f, 0.06100000000f, 0.00000000000f},
- {0.04677000000f, 0.01700000000f, 0.00000000000f},
- {0.01135916000f, 0.00410200000f, 0.00000000000f},
- {0.00289932700f, 0.00104700000f, 0.00000000000f},
- {0.00069007860f, 0.00024920000f, 0.00000000000f},
- {0.00016615050f, 0.00006000000f, 0.00000000000f},
- {0.00004150994f, 0.00001499000f, 0.00000000000f}};
-
-static float3 geographical_to_direction(float lat, float lon)
-{
- return make_float3(cosf(lat) * cosf(lon), cosf(lat) * sinf(lon), sinf(lat));
-}
-
-static float3 spec_to_xyz(float *spectrum)
-{
- float3 xyz = make_float3(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < num_wavelengths; i++) {
- xyz.x += cmf_xyz[i][0] * spectrum[i];
- xyz.y += cmf_xyz[i][1] * spectrum[i];
- xyz.z += cmf_xyz[i][2] * spectrum[i];
- }
- return xyz * (20 * 683 * 1e-9f);
-}
-
-/* Atmosphere volume models */
-
-static float density_rayleigh(float height)
-{
- return expf(-height / rayleigh_scale);
-}
-
-static float density_mie(float height)
-{
- return expf(-height / mie_scale);
-}
-
-static float density_ozone(float height)
-{
- float den = 0.0f;
- if (height >= 10000.0f && height < 25000.0f)
- den = 1.0f / 15000.0f * height - 2.0f / 3.0f;
- else if (height >= 25000 && height < 40000)
- den = -(1.0f / 15000.0f * height - 8.0f / 3.0f);
- return den;
-}
-
-static float phase_rayleigh(float mu)
-{
- return 3.0f / (16.0f * M_PI_F) * (1.0f + sqr(mu));
-}
-
-static float phase_mie(float mu)
-{
- static const float sqr_G = mie_G * mie_G;
-
- return (3.0f * (1.0f - sqr_G) * (1.0f + sqr(mu))) /
- (8.0f * M_PI_F * (2.0f + sqr_G) * powf((1.0f + sqr_G - 2.0f * mie_G * mu), 1.5));
-}
-
-/* Intersection helpers */
-static bool surface_intersection(float3 pos, float3 dir)
-{
- if (dir.z >= 0)
- return false;
- float t = dot(dir, -pos) / len_squared(dir);
- float D = pos.x * pos.x - 2.0f * (-pos.x) * dir.x * t + dir.x * t * dir.x * t + pos.y * pos.y -
- 2.0f * (-pos.y) * dir.y * t + (dir.y * t) * (dir.y * t) + pos.z * pos.z -
- 2.0f * (-pos.z) * dir.z * t + dir.z * t * dir.z * t;
- return (D <= sqr(earth_radius));
-}
-
-static float3 atmosphere_intersection(float3 pos, float3 dir)
-{
- float b = -2.0f * dot(dir, -pos);
- float c = len_squared(pos) - sqr(atmosphere_radius);
- float t = (-b + sqrtf(b * b - 4.0f * c)) / 2.0f;
- return make_float3(pos.x + dir.x * t, pos.y + dir.y * t, pos.z + dir.z * t);
-}
-
-static float3 ray_optical_depth(float3 ray_origin, float3 ray_dir)
-{
- /* This code computes the optical depth along a ray through the atmosphere. */
- float3 ray_end = atmosphere_intersection(ray_origin, ray_dir);
- float ray_length = distance(ray_origin, ray_end);
-
- /* To compute the optical depth, we step along the ray in segments and
- * accumulate the optical depth along each segment. */
- float segment_length = ray_length / steps_light;
- float3 segment = segment_length * ray_dir;
-
- /* Instead of tracking the transmission spectrum across all wavelengths directly,
- * we use the fact that the density always has the same spectrum for each type of
- * scattering, so we split the density into a constant spectrum and a factor and
- * only track the factors. */
- float3 optical_depth = make_float3(0.0f, 0.0f, 0.0f);
-
- /* The density of each segment is evaluated at its middle. */
- float3 P = ray_origin + 0.5f * segment;
- for (int i = 0; i < steps_light; i++) {
- /* Compute height above sea level. */
- float height = len(P) - earth_radius;
-
- /* Accumulate optical depth of this segment (density is assumed to be constant along it). */
- float3 density = make_float3(
- density_rayleigh(height), density_mie(height), density_ozone(height));
- optical_depth += segment_length * density;
-
- /* Advance along ray. */
- P += segment;
- }
-
- return optical_depth;
-}
-
-/* Single Scattering implementation */
-static void single_scattering(float3 ray_dir,
- float3 sun_dir,
- float3 ray_origin,
- float air_density,
- float dust_density,
- float ozone_density,
- float *r_spectrum)
-{
- /* This code computes single-inscattering along a ray through the atmosphere. */
- float3 ray_end = atmosphere_intersection(ray_origin, ray_dir);
- float ray_length = distance(ray_origin, ray_end);
-
- /* To compute the inscattering, we step along the ray in segments and accumulate
- * the inscattering as well as the optical depth along each segment. */
- float segment_length = ray_length / steps;
- float3 segment = segment_length * ray_dir;
-
- /* Instead of tracking the transmission spectrum across all wavelengths directly,
- * we use the fact that the density always has the same spectrum for each type of
- * scattering, so we split the density into a constant spectrum and a factor and
- * only track the factors. */
- float3 optical_depth = make_float3(0.0f, 0.0f, 0.0f);
-
- /* Zero out light accumulation. */
- for (int wl = 0; wl < num_wavelengths; wl++) {
- r_spectrum[wl] = 0.0f;
- }
-
- /* Compute phase function for scattering and the density scale factor. */
- float mu = dot(ray_dir, sun_dir);
- float3 phase_function = make_float3(phase_rayleigh(mu), phase_mie(mu), 0.0f);
- float3 density_scale = make_float3(air_density, dust_density, ozone_density);
-
- /* The density and in-scattering of each segment is evaluated at its middle. */
- float3 P = ray_origin + 0.5f * segment;
- for (int i = 0; i < steps; i++) {
- /* Compute height above sea level. */
- float height = len(P) - earth_radius;
-
- /* Evaluate and accumulate optical depth along the ray. */
- float3 density = density_scale * make_float3(density_rayleigh(height),
- density_mie(height),
- density_ozone(height));
- optical_depth += segment_length * density;
-
- /* If the earth isn't in the way, evaluate inscattering from the sun. */
- if (!surface_intersection(P, sun_dir)) {
- float3 light_optical_depth = density_scale * ray_optical_depth(P, sun_dir);
- float3 total_optical_depth = optical_depth + light_optical_depth;
-
- /* attenuation of light */
- for (int wl = 0; wl < num_wavelengths; wl++) {
- float3 extinction_density = total_optical_depth * make_float3(rayleigh_coeff[wl],
- 1.11f * mie_coeff,
- ozone_coeff[wl]);
- float attenuation = expf(-reduce_add(extinction_density));
-
- float3 scattering_density = density * make_float3(rayleigh_coeff[wl], mie_coeff, 0.0f);
-
- /* The total inscattered radiance from one segment is:
- * Tr(A<->B) * Tr(B<->C) * sigma_s * phase * L * segment_length
- *
- * These terms are:
- * Tr(A<->B): Transmission from start to scattering position (tracked in optical_depth)
- * Tr(B<->C): Transmission from scattering position to light (computed in
- * ray_optical_depth) sigma_s: Scattering density phase: Phase function of the scattering
- * type (Rayleigh or Mie) L: Radiance coming from the light source segment_length: The
- * length of the segment
- *
- * The code here is just that, with a bit of additional optimization to not store full
- * spectra for the optical depth.
- */
- r_spectrum[wl] += attenuation * reduce_add(phase_function * scattering_density) *
- irradiance[wl] * segment_length;
- }
- }
-
- /* Advance along ray. */
- P += segment;
- }
-}
-
-/* calculate texture array */
-void nishita_skymodel_precompute_texture(float *pixels,
- int stride,
- int start_y,
- int end_y,
- int width,
- int height,
- float sun_elevation,
- float altitude,
- float air_density,
- float dust_density,
- float ozone_density)
-{
- /* calculate texture pixels */
- float spectrum[num_wavelengths];
- int half_width = width / 2;
- float3 cam_pos = make_float3(0, 0, earth_radius + altitude);
- float3 sun_dir = geographical_to_direction(sun_elevation, 0.0f);
-
- float latitude_step = M_PI_2_F / height;
- float longitude_step = M_2PI_F / width;
-
- for (int y = start_y; y < end_y; y++) {
- float latitude = latitude_step * y;
-
- float *pixel_row = pixels + (y * width) * stride;
- for (int x = 0; x < half_width; x++) {
- float longitude = longitude_step * x - M_PI_F;
-
- float3 dir = geographical_to_direction(latitude, longitude);
- single_scattering(dir, sun_dir, cam_pos, air_density, dust_density, ozone_density, spectrum);
- float3 xyz = spec_to_xyz(spectrum);
-
- pixel_row[x * stride + 0] = xyz.x;
- pixel_row[x * stride + 1] = xyz.y;
- pixel_row[x * stride + 2] = xyz.z;
- int mirror_x = width - x - 1;
- pixel_row[mirror_x * stride + 0] = xyz.x;
- pixel_row[mirror_x * stride + 1] = xyz.y;
- pixel_row[mirror_x * stride + 2] = xyz.z;
- }
- }
-}
-
-/* Sun disc */
-static void sun_radiation(float3 cam_dir,
- float altitude,
- float air_density,
- float dust_density,
- float solid_angle,
- float *r_spectrum)
-{
- float3 cam_pos = make_float3(0, 0, earth_radius + altitude);
- float3 optical_depth = ray_optical_depth(cam_pos, cam_dir);
-
- /* Compute final spectrum. */
- for (int i = 0; i < num_wavelengths; i++) {
- /* Combine spectra and the optical depth into transmittance. */
- float transmittance = rayleigh_coeff[i] * optical_depth.x * air_density +
- 1.11f * mie_coeff * optical_depth.y * dust_density;
- r_spectrum[i] = (irradiance[i] / solid_angle) * expf(-transmittance);
- }
-}
-
-void nishita_skymodel_precompute_sun(float sun_elevation,
- float angular_diameter,
- float altitude,
- float air_density,
- float dust_density,
- float *pixel_bottom,
- float *pixel_top)
-{
- /* definitions */
- float half_angular = angular_diameter / 2.0f;
- float solid_angle = M_2PI_F * (1.0f - cosf(half_angular));
- float spectrum[num_wavelengths];
- float bottom = sun_elevation - half_angular;
- float top = sun_elevation + half_angular;
- float elevation_bottom, elevation_top;
- float3 pix_bottom, pix_top, sun_dir;
-
- /* compute 2 pixels for sun disc */
- elevation_bottom = (bottom > 0.0f) ? bottom : 0.0f;
- elevation_top = (top > 0.0f) ? top : 0.0f;
- sun_dir = geographical_to_direction(elevation_bottom, 0.0f);
- sun_radiation(sun_dir, altitude, air_density, dust_density, solid_angle, spectrum);
- pix_bottom = spec_to_xyz(spectrum);
- sun_dir = geographical_to_direction(elevation_top, 0.0f);
- sun_radiation(sun_dir, altitude, air_density, dust_density, solid_angle, spectrum);
- pix_top = spec_to_xyz(spectrum);
-
- /* store pixels */
- pixel_bottom[0] = pix_bottom.x;
- pixel_bottom[1] = pix_bottom.y;
- pixel_bottom[2] = pix_bottom.z;
- pixel_top[0] = pix_top.x;
- pixel_top[1] = pix_top.y;
- pixel_top[2] = pix_top.z;
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_sseb.h b/intern/cycles/util/util_sseb.h
index 56f8f676ba1..d817e23c47e 100644
--- a/intern/cycles/util/util_sseb.h
+++ b/intern/cycles/util/util_sseb.h
@@ -57,7 +57,7 @@ struct sseb {
__forceinline sseb(const __m128 input) : m128(input)
{
}
- __forceinline operator const __m128 &(void)const
+ __forceinline operator const __m128 &(void) const
{
return m128;
}
diff --git a/intern/cycles/util/util_ssei.h b/intern/cycles/util/util_ssei.h
index e2bf81310cc..a4db9193206 100644
--- a/intern/cycles/util/util_ssei.h
+++ b/intern/cycles/util/util_ssei.h
@@ -57,7 +57,7 @@ struct ssei {
__forceinline ssei(const __m128i a) : m128(a)
{
}
- __forceinline operator const __m128i &(void)const
+ __forceinline operator const __m128i &(void) const
{
return m128;
}
diff --git a/intern/cycles/util/util_tbb.h b/intern/cycles/util/util_tbb.h
index 301cb80c5b0..206ba106ca6 100644
--- a/intern/cycles/util/util_tbb.h
+++ b/intern/cycles/util/util_tbb.h
@@ -34,6 +34,11 @@ using tbb::blocked_range;
using tbb::enumerable_thread_specific;
using tbb::parallel_for;
+static inline void parallel_for_cancel()
+{
+ tbb::task::self().cancel_group_execution();
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_TBB_H__ */
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index 101122740d7..e8233b7fe6d 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -269,17 +269,17 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
/* extract scale and shear first */
float3 scale, shear;
scale.x = len(colx);
- colx /= scale.x;
+ colx = safe_divide_float3_float(colx, scale.x);
shear.z = dot(colx, coly);
coly -= shear.z * colx;
scale.y = len(coly);
- coly /= scale.y;
+ coly = safe_divide_float3_float(coly, scale.y);
shear.y = dot(colx, colz);
colz -= shear.y * colx;
shear.x = dot(coly, colz);
colz -= shear.x * coly;
scale.z = len(colz);
- colz /= scale.z;
+ colz = safe_divide_float3_float(colz, scale.z);
transform_set_column(&M, 0, colx);
transform_set_column(&M, 1, coly);
@@ -300,6 +300,7 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size)
{
+ /* Decompose and correct rotation. */
for (size_t i = 0; i < size; i++) {
transform_decompose(decomp + i, motion + i);
@@ -310,6 +311,27 @@ void transform_motion_decompose(DecomposedTransform *decomp, const Transform *mo
decomp[i].x = -decomp[i].x;
}
}
+
+ /* Copy rotation to decomposed transform where scale is degenerate. This avoids weird object
+ * rotation interpolation when the scale goes to 0 for a time step.
+ *
+ * Note that this is very simple and naive implementation, which only deals with degenerated
+ * scale happening only on one frame. It is possible to improve it further by interpolating
+ * rotation into s degenerated range using rotation from time-steps from adjacent non-degenerated
+ * time steps. */
+ for (size_t i = 0; i < size; i++) {
+ const float3 scale = make_float3(decomp[i].y.w, decomp[i].z.w, decomp[i].w.w);
+ if (!is_zero(scale)) {
+ continue;
+ }
+
+ if (i > 0) {
+ decomp[i].x = decomp[i - 1].x;
+ }
+ else if (i < size - 1) {
+ decomp[i].x = decomp[i + 1].x;
+ }
+ }
}
Transform transform_from_viewplane(BoundBox2D &viewplane)
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index d0a6264d5cf..d8bbd389aa6 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -466,6 +466,17 @@ ccl_device void transform_motion_array_interpolate(Transform *tfm,
transform_compose(tfm, &decomp);
}
+ccl_device_inline bool transform_isfinite_safe(Transform *tfm)
+{
+ return isfinite4_safe(tfm->x) && isfinite4_safe(tfm->y) && isfinite4_safe(tfm->z);
+}
+
+ccl_device_inline bool transform_decomposed_isfinite_safe(DecomposedTransform *decomp)
+{
+ return isfinite4_safe(decomp->x) && isfinite4_safe(decomp->y) && isfinite4_safe(decomp->z) &&
+ isfinite4_safe(decomp->w);
+}
+
#ifndef __KERNEL_GPU__
class BoundBox2D;