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
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/addon/properties.py18
-rw-r--r--intern/cycles/blender/addon/ui.py8
-rw-r--r--intern/cycles/blender/addon/version_update.py13
-rw-r--r--intern/cycles/blender/blender_object.cpp17
-rw-r--r--intern/cycles/kernel/kernel_emission.h4
-rw-r--r--intern/cycles/kernel/kernel_light.h41
-rw-r--r--intern/cycles/kernel/kernel_types.h5
-rw-r--r--intern/cycles/render/image.cpp56
-rw-r--r--intern/cycles/render/image.h10
-rw-r--r--intern/cycles/render/light.cpp108
10 files changed, 170 insertions, 110 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 8dbd80f3747..4484dcfbfd7 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -128,6 +128,12 @@ enum_volume_interpolation = (
('CUBIC', "Cubic", "Smoothed high quality interpolation, but slower")
)
+enum_world_mis = (
+ ('NONE', "None", "Don't sample the background, faster but might cause noise for non-solid backgrounds"),
+ ('AUTOMATIC', "Auto", "Automatically try to determine the best setting"),
+ ('MANUAL', "Manual", "Manually set the resolution of the sampling map, higher values are slower and require more memory but reduce noise")
+ )
+
enum_device_type = (
('CPU', "CPU", "CPU", 0),
('CUDA', "CUDA", "CUDA", 1),
@@ -938,15 +944,15 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
description="Cycles world settings",
type=cls,
)
- cls.sample_as_light = BoolProperty(
- name="Multiple Importance Sample",
- description="Use multiple importance sampling for the environment, "
- "enabling for non-solid colors is recommended",
- default=True,
+ cls.sampling_method = EnumProperty(
+ name="Sampling method",
+ description="How to sample the background light",
+ items=enum_world_mis,
+ default='AUTOMATIC',
)
cls.sample_map_resolution = IntProperty(
name="Map Resolution",
- description="Importance map size is resolution x resolution; "
+ description="Importance map size is resolution x resolution/2; "
"higher values potentially produce less noise, at the cost of memory and speed",
min=4, max=8192,
default=1024,
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 707f8756f6f..2b11a2eefb0 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1214,11 +1214,13 @@ class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel):
col = split.column()
col.label(text="Surface:")
- col.prop(cworld, "sample_as_light", text="Multiple Importance")
+ col.prop(cworld, "sampling_method", text="Sampling")
sub = col.column(align=True)
- sub.active = cworld.sample_as_light
- sub.prop(cworld, "sample_map_resolution")
+ sub.active = cworld.sampling_method != 'NONE'
+ subsub = sub.row(align=True)
+ subsub.active = cworld.sampling_method == 'MANUAL'
+ subsub.prop(cworld, "sample_map_resolution")
if use_branched_path(context):
subsub = sub.row(align=True)
subsub.active = use_sample_all_lights(context)
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index 292f0a1fa90..dc28bc647b5 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -377,10 +377,6 @@ def do_versions(self):
for world in bpy.data.worlds:
cworld = world.cycles
- # World MIS
- if not cworld.is_property_set("sample_as_light"):
- cworld.sample_as_light = False
-
# World MIS Samples
if not cworld.is_property_set("samples"):
cworld.samples = 4
@@ -431,3 +427,12 @@ def do_versions(self):
if bpy.data.version <= (2, 79, 3):
# Switch to squared roughness convention
square_roughness_nodes_insert()
+
+ for world in bpy.data.worlds:
+ cworld = world.cycles
+ # World MIS
+ if not cworld.is_property_set("sampling_method"):
+ if cworld.get("sample_as_light", False):
+ cworld.sampling_method = 'MANUAL'
+ else:
+ cworld.sampling_method = 'NONE'
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 4919bc4325f..86b04f5030c 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -227,7 +227,15 @@ void BlenderSync::sync_background_light(bool use_portal)
if(b_world) {
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
- bool sample_as_light = get_boolean(cworld, "sample_as_light");
+
+ enum SamplingMethod {
+ SAMPLING_NONE = 0,
+ SAMPLING_AUTOMATIC,
+ SAMPLING_MANUAL,
+ SAMPLING_NUM
+ };
+ int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
+ bool sample_as_light = (sampling_method != SAMPLING_NONE);
if(sample_as_light || use_portal) {
/* test if we need to sync */
@@ -239,7 +247,12 @@ void BlenderSync::sync_background_light(bool use_portal)
b_world.ptr.data != world_map)
{
light->type = LIGHT_BACKGROUND;
- light->map_resolution = get_int(cworld, "sample_map_resolution");
+ if(sampling_method == SAMPLING_MANUAL) {
+ light->map_resolution = get_int(cworld, "sample_map_resolution");
+ }
+ else {
+ light->map_resolution = 0;
+ }
light->shader = scene->default_background;
light->use_mis = sample_as_light;
light->max_bounces = get_int(cworld, "max_bounces");
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index a5556c3be8f..524e2467ebc 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -319,9 +319,9 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
#ifdef __BACKGROUND_MIS__
/* check if background light exists or if we should skip pdf */
- int res = kernel_data.integrator.pdf_background_res;
+ int res_x = kernel_data.integrator.pdf_background_res_x;
- if(!(state->flag & PATH_RAY_MIS_SKIP) && res) {
+ if(!(state->flag & PATH_RAY_MIS_SKIP) && res_x) {
/* multiple importance sampling, get background light pdf for ray
* direction, and compute weight with respect to BSDF pdf */
float pdf = background_light_pdf(kg, ray->P, ray->D);
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index ec7203d36eb..bb182ef1f25 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -143,12 +143,13 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float
/* for the following, the CDF values are actually a pair of floats, with the
* function value as X and the actual CDF as Y. The last entry's function
* value is the CDF total. */
- int res = kernel_data.integrator.pdf_background_res;
- int cdf_count = res + 1;
+ int res_x = kernel_data.integrator.pdf_background_res_x;
+ int res_y = kernel_data.integrator.pdf_background_res_y;
+ int cdf_width = res_x + 1;
/* this is basically std::lower_bound as used by pbrt */
int first = 0;
- int count = res;
+ int count = res_y;
while(count > 0) {
int step = count >> 1;
@@ -163,24 +164,24 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float
}
int index_v = max(0, first - 1);
- kernel_assert(index_v >= 0 && index_v < res);
+ kernel_assert(index_v >= 0 && index_v < res_y);
float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
+ float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
/* importance-sampled V direction */
float dv = inverse_lerp(cdf_v.y, cdf_next_v.y, randv);
- float v = (index_v + dv) / res;
+ float v = (index_v + dv) / res_y;
/* this is basically std::lower_bound as used by pbrt */
first = 0;
- count = res;
+ count = res_x;
while(count > 0) {
int step = count >> 1;
int middle = first + step;
- if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + middle).y < randu) {
+ if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + middle).y < randu) {
first = middle + 1;
count -= step + 1;
}
@@ -189,15 +190,15 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float
}
int index_u = max(0, first - 1);
- kernel_assert(index_u >= 0 && index_u < res);
+ kernel_assert(index_u >= 0 && index_u < res_x);
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u);
- float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u + 1);
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + res);
+ float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u);
+ float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u + 1);
+ float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x);
/* importance-sampled U direction */
float du = inverse_lerp(cdf_u.y, cdf_next_u.y, randu);
- float u = (index_u + du) / res;
+ float u = (index_u + du) / res_x;
/* compute pdf */
float denom = cdf_last_u.x * cdf_last_v.x;
@@ -223,19 +224,21 @@ ccl_device
float background_map_pdf(KernelGlobals *kg, float3 direction)
{
float2 uv = direction_to_equirectangular(direction);
- int res = kernel_data.integrator.pdf_background_res;
+ int res_x = kernel_data.integrator.pdf_background_res_x;
+ int res_y = kernel_data.integrator.pdf_background_res_y;
+ int cdf_width = res_x + 1;
float sin_theta = sinf(uv.y * M_PI_F);
if(sin_theta == 0.0f)
return 0.0f;
- int index_u = clamp(float_to_int(uv.x * res), 0, res - 1);
- int index_v = clamp(float_to_int(uv.y * res), 0, res - 1);
+ int index_u = clamp(float_to_int(uv.x * res_x), 0, res_x - 1);
+ int index_v = clamp(float_to_int(uv.y * res_y), 0, res_y - 1);
/* pdfs in V direction */
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + res);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
+ float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x);
+ float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
float denom = cdf_last_u.x * cdf_last_v.x;
@@ -243,7 +246,7 @@ float background_map_pdf(KernelGlobals *kg, float3 direction)
return 0.0f;
/* pdfs in U direction */
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + index_u);
+ float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u);
float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
return (cdf_u.x * cdf_v.x)/(M_2PI_F * M_PI_F * sin_theta * denom);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 72fbf7be557..5382213e6f7 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1306,7 +1306,8 @@ typedef struct KernelIntegrator {
int num_all_lights;
float pdf_triangles;
float pdf_lights;
- int pdf_background_res;
+ int pdf_background_res_x;
+ int pdf_background_res_y;
float light_inv_rr_threshold;
/* light portals */
@@ -1368,6 +1369,8 @@ typedef struct KernelIntegrator {
int start_sample;
int max_closures;
+
+ int pad1, pad2, pad3;
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 9c5e32e8219..9c6536edc4f 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -94,6 +94,25 @@ device_memory *ImageManager::image_memory(int flat_slot)
return img->mem;
}
+bool ImageManager::get_image_metadata(int flat_slot,
+ ImageMetaData& metadata)
+{
+ if(flat_slot == -1) {
+ return false;
+ }
+
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
+
+ Image *img = images[type][slot];
+ if(img) {
+ metadata = img->metadata;
+ return true;
+ }
+
+ return false;
+}
+
bool ImageManager::get_image_metadata(const string& filename,
void *builtin_data,
ImageMetaData& metadata)
@@ -329,7 +348,7 @@ int ImageManager::add_image(const string& filename,
img = new Image();
img->filename = filename;
img->builtin_data = builtin_data;
- img->builtin_free_cache = metadata.builtin_free_cache;
+ img->metadata = metadata;
img->need_load = true;
img->animated = animated;
img->frame = frame;
@@ -417,11 +436,7 @@ void ImageManager::tag_reload_image(const string& filename,
}
bool ImageManager::file_load_image_generic(Image *img,
- ImageInput **in,
- int &width,
- int &height,
- int &depth,
- int &components)
+ ImageInput **in)
{
if(img->filename == "")
return false;
@@ -449,28 +464,15 @@ bool ImageManager::file_load_image_generic(Image *img,
*in = NULL;
return false;
}
-
- width = spec.width;
- height = spec.height;
- depth = spec.depth;
- components = spec.nchannels;
}
else {
/* load image using builtin images callbacks */
if(!builtin_image_info_cb || !builtin_image_pixels_cb)
return false;
-
- ImageMetaData metadata;
- builtin_image_info_cb(img->filename, img->builtin_data, metadata);
-
- width = metadata.width;
- height = metadata.height;
- depth = metadata.depth;
- components = metadata.channels;
}
/* we only handle certain number of components */
- if(!(components >= 1 && components <= 4)) {
+ if(!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
if(*in) {
(*in)->close();
delete *in;
@@ -493,10 +495,16 @@ bool ImageManager::file_load_image(Image *img,
{
const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
ImageInput *in = NULL;
- int width, height, depth, components;
- if(!file_load_image_generic(img, &in, width, height, depth, components)) {
+ if(!file_load_image_generic(img, &in)) {
return false;
}
+
+ /* Get metadata. */
+ int width = img->metadata.width;
+ int height = img->metadata.height;
+ int depth = img->metadata.depth;
+ int components = img->metadata.channels;
+
/* Read RGBA pixels. */
vector<StorageType> pixels_storage;
StorageType *pixels;
@@ -557,14 +565,14 @@ bool ImageManager::file_load_image(Image *img,
img->builtin_data,
(float*)&pixels[0],
num_pixels * components,
- img->builtin_free_cache);
+ img->metadata.builtin_free_cache);
}
else if(FileFormat == TypeDesc::UINT8) {
builtin_image_pixels_cb(img->filename,
img->builtin_data,
(uchar*)&pixels[0],
num_pixels * components,
- img->builtin_free_cache);
+ img->metadata.builtin_free_cache);
}
else {
/* TODO(dingto): Support half for ImBuf. */
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 5391490d993..4fd09adaa64 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -71,6 +71,8 @@ public:
bool get_image_metadata(const string& filename,
void *builtin_data,
ImageMetaData& metadata);
+ bool get_image_metadata(int flat_slot,
+ ImageMetaData& metadata);
void device_update(Device *device,
Scene *scene,
@@ -110,7 +112,7 @@ public:
struct Image {
string filename;
void *builtin_data;
- bool builtin_free_cache;
+ ImageMetaData metadata;
bool use_alpha;
bool need_load;
@@ -137,11 +139,7 @@ private:
void *osl_texture_system;
bool file_load_image_generic(Image *img,
- ImageInput **in,
- int &width,
- int &height,
- int &depth,
- int &components);
+ ImageInput **in);
template<TypeDesc::BASETYPE FileFormat,
typename StorageType,
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index cbcd2564e6e..20c6a53e58f 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -18,8 +18,10 @@
#include "device/device.h"
#include "render/integrator.h"
#include "render/film.h"
+#include "render/graph.h"
#include "render/light.h"
#include "render/mesh.h"
+#include "render/nodes.h"
#include "render/object.h"
#include "render/scene.h"
#include "render/shader.h"
@@ -32,12 +34,9 @@
CCL_NAMESPACE_BEGIN
-static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels, Progress& progress)
+static void shade_background_pixels(Device *device, DeviceScene *dscene, int width, int height, vector<float3>& pixels, Progress& progress)
{
/* create input */
- int width = res;
- int height = res;
-
device_vector<uint4> d_input(device, "background_input", MEM_READ_ONLY);
device_vector<float4> d_output(device, "background_output", MEM_READ_WRITE);
@@ -120,7 +119,7 @@ NODE_DEFINE(Light)
SOCKET_VECTOR(axisv, "Axis V", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_FLOAT(sizev, "Size V", 1.0f);
- SOCKET_INT(map_resolution, "Map Resolution", 512);
+ SOCKET_INT(map_resolution, "Map Resolution", 0);
SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
@@ -481,40 +480,41 @@ void LightManager::device_update_distribution(Device *, DeviceScene *dscene, Sce
static void background_cdf(int start,
int end,
- int res,
- int cdf_count,
+ int res_x,
+ int res_y,
const vector<float3> *pixels,
float2 *cond_cdf)
{
+ int cdf_width = res_x+1;
/* Conditional CDFs (rows, U direction). */
for(int i = start; i < end; i++) {
- float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
- float3 env_color = (*pixels)[i * res];
+ float sin_theta = sinf(M_PI_F * (i + 0.5f) / res_y);
+ float3 env_color = (*pixels)[i * res_x];
float ave_luminance = average(env_color);
- cond_cdf[i * cdf_count].x = ave_luminance * sin_theta;
- cond_cdf[i * cdf_count].y = 0.0f;
+ cond_cdf[i * cdf_width].x = ave_luminance * sin_theta;
+ cond_cdf[i * cdf_width].y = 0.0f;
- for(int j = 1; j < res; j++) {
- env_color = (*pixels)[i * res + j];
+ for(int j = 1; j < res_x; j++) {
+ env_color = (*pixels)[i * res_x + j];
ave_luminance = average(env_color);
- cond_cdf[i * cdf_count + j].x = ave_luminance * sin_theta;
- cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
+ cond_cdf[i * cdf_width + j].x = ave_luminance * sin_theta;
+ cond_cdf[i * cdf_width + j].y = cond_cdf[i * cdf_width + j - 1].y + cond_cdf[i * cdf_width + j - 1].x / res_x;
}
- float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
+ float cdf_total = cond_cdf[i * cdf_width + res_x - 1].y + cond_cdf[i * cdf_width + res_x - 1].x / res_x;
float cdf_total_inv = 1.0f / cdf_total;
/* stuff the total into the brightness value for the last entry, because
* we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
- cond_cdf[i * cdf_count + res].x = cdf_total;
+ cond_cdf[i * cdf_width + res_x].x = cdf_total;
if(cdf_total > 0.0f)
- for(int j = 1; j < res; j++)
- cond_cdf[i * cdf_count + j].y *= cdf_total_inv;
+ for(int j = 1; j < res_x; j++)
+ cond_cdf[i * cdf_width + j].y *= cdf_total_inv;
- cond_cdf[i * cdf_count + res].y = 1.0f;
+ cond_cdf[i * cdf_width + res_x].y = 1.0f;
}
}
@@ -536,7 +536,8 @@ void LightManager::device_update_background(Device *device,
/* no background light found, signal renderer to skip sampling */
if(!background_light || !background_light->is_enabled) {
- kintegrator->pdf_background_res = 0;
+ kintegrator->pdf_background_res_x = 0;
+ kintegrator->pdf_background_res_y = 0;
return;
}
@@ -545,41 +546,62 @@ void LightManager::device_update_background(Device *device,
assert(kintegrator->use_direct_light);
/* get the resolution from the light's size (we stuff it in there) */
- int res = background_light->map_resolution;
- kintegrator->pdf_background_res = res;
-
- assert(res > 0);
+ int2 res = make_int2(background_light->map_resolution, background_light->map_resolution/2);
+ /* If the resolution isn't set manually, try to find an environment texture. */
+ if (res.x == 0) {
+ Shader *shader = (scene->background->shader) ? scene->background->shader : scene->default_background;
+ foreach(ShaderNode *node, shader->graph->nodes) {
+ if(node->type == EnvironmentTextureNode::node_type) {
+ EnvironmentTextureNode *env = (EnvironmentTextureNode*) node;
+ ImageMetaData metadata;
+ if(env->image_manager && env->image_manager->get_image_metadata(env->slot, metadata)) {
+ res.x = max(res.x, metadata.width);
+ res.y = max(res.y, metadata.height);
+ }
+ }
+ }
+ if (res.x > 0 && res.y > 0) {
+ VLOG(2) << "Automatically set World MIS resolution to " << res.x << " by " << res.y << "\n";
+ }
+ }
+ /* If it's still unknown, just use the default. */
+ if (res.x == 0 || res.y == 0) {
+ res = make_int2(1024, 512);
+ VLOG(2) << "Setting World MIS resolution to default\n";
+ }
+ kintegrator->pdf_background_res_x = res.x;
+ kintegrator->pdf_background_res_y = res.y;
vector<float3> pixels;
- shade_background_pixels(device, dscene, res, pixels, progress);
+ shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
if(progress.get_cancel())
return;
/* build row distributions and column distribution for the infinite area environment light */
- int cdf_count = res + 1;
- float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(cdf_count);
- float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_count * cdf_count);
+ int cdf_width = res.x+1;
+ float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(res.y + 1);
+ float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_width * res.y);
double time_start = time_dt();
- if(res < 512) {
+ if(max(res.x, res.y) < 512) {
/* Small enough resolution, faster to do single-threaded. */
- background_cdf(0, res, res, cdf_count, &pixels, cond_cdf);
+ background_cdf(0, res.x, res.x, res.y, &pixels, cond_cdf);
}
else {
/* Threaded evaluation for large resolution. */
const int num_blocks = TaskScheduler::num_threads();
- const int chunk_size = res / num_blocks;
+ const int chunk_size = res.y / num_blocks;
int start_row = 0;
TaskPool pool;
for(int i = 0; i < num_blocks; ++i) {
const int current_chunk_size =
(i != num_blocks - 1) ? chunk_size
- : (res - i * chunk_size);
+ : (res.y - i * chunk_size);
pool.push(function_bind(&background_cdf,
start_row, start_row + current_chunk_size,
- res,
- cdf_count,
+ res.x,
+ res.y,
&pixels,
cond_cdf));
start_row += current_chunk_size;
@@ -588,22 +610,22 @@ void LightManager::device_update_background(Device *device,
}
/* marginal CDFs (column, V direction, sum of rows) */
- marg_cdf[0].x = cond_cdf[res].x;
+ marg_cdf[0].x = cond_cdf[res.x].x;
marg_cdf[0].y = 0.0f;
- for(int i = 1; i < res; i++) {
- marg_cdf[i].x = cond_cdf[i * cdf_count + res].x;
- marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res;
+ for(int i = 1; i < res.y; i++) {
+ marg_cdf[i].x = cond_cdf[i * cdf_width + res.x].x;
+ marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res.y;
}
- float cdf_total = marg_cdf[res - 1].y + marg_cdf[res - 1].x / res;
- marg_cdf[res].x = cdf_total;
+ float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y;
+ marg_cdf[res.y].x = cdf_total;
if(cdf_total > 0.0f)
- for(int i = 1; i < res; i++)
+ for(int i = 1; i < res.y; i++)
marg_cdf[i].y /= cdf_total;
- marg_cdf[res].y = 1.0f;
+ marg_cdf[res.y].y = 1.0f;
VLOG(2) << "Background MIS build time " << time_dt() - time_start << "\n";