diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/CMakeLists.txt | 2 | ||||
-rw-r--r-- | intern/cycles/render/buffers.h | 46 | ||||
-rw-r--r-- | intern/cycles/render/camera.cpp | 40 | ||||
-rw-r--r-- | intern/cycles/render/denoising.cpp | 64 | ||||
-rw-r--r-- | intern/cycles/render/denoising.h | 4 | ||||
-rw-r--r-- | intern/cycles/render/image_sky.cpp | 33 | ||||
-rw-r--r-- | intern/cycles/render/image_sky.h | 4 | ||||
-rw-r--r-- | intern/cycles/render/light.cpp | 14 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 56 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/render/session.cpp | 71 | ||||
-rw-r--r-- | intern/cycles/render/session.h | 4 |
13 files changed, 230 insertions, 117 deletions
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 ¢er) + { + 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 ¢er_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 ¢er_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/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..1a29663ec5e 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_intensity, "Sun Intensity", 1.0f); SOCKET_FLOAT(sun_elevation, "Sun Elevation", M_PI_2_F); SOCKET_FLOAT(sun_rotation, "Sun Rotation", 0.0f); - SOCKET_INT(altitude, "Altitude", 0); + SOCKET_FLOAT(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..c5033359c6b 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 ¢er_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() @@ -1003,7 +1005,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 +1128,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; |