From a29446da526d601a03c9083d19e3c18d7b470f20 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 26 Mar 2019 14:34:18 +0100 Subject: Cycles: sync various master changes to blender2.7. Many of these were left out accidentally. We will only do important bugfixes in blender2.7 for Cycles from this point on. --- intern/cycles/app/CMakeLists.txt | 10 +- intern/cycles/app/io_export_cycles_xml.py | 1 - intern/cycles/blender/addon/engine.py | 2 - intern/cycles/device/device_cpu.cpp | 1 + intern/cycles/device/opencl/opencl.h | 4 +- intern/cycles/device/opencl/opencl_split.cpp | 10 +- .../cycles/kernel/filter/filter_reconstruction.h | 8 +- intern/cycles/kernel/kernel_light.h | 180 +++++++++++++-------- intern/cycles/render/film.cpp | 11 +- intern/cycles/render/image.cpp | 33 ++++ intern/cycles/render/image.h | 4 + intern/cycles/render/light.cpp | 13 +- intern/cycles/render/light.h | 1 + intern/cycles/render/nodes.cpp | 33 ++-- intern/cycles/render/nodes.h | 2 + intern/cycles/render/scene.cpp | 5 +- intern/cycles/render/scene.h | 3 + intern/cycles/render/shader.cpp | 1 + intern/cycles/render/shader.h | 1 + intern/cycles/util/util_ies.cpp | 2 +- intern/cycles/util/util_ies.h | 2 +- intern/cycles/util/util_math_intersect.h | 22 ++- 22 files changed, 234 insertions(+), 115 deletions(-) (limited to 'intern') diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt index 689b8bc08e5..2d7db860b09 100644 --- a/intern/cycles/app/CMakeLists.txt +++ b/intern/cycles/app/CMakeLists.txt @@ -58,7 +58,12 @@ link_directories(${OPENIMAGEIO_LIBPATH} ${JPEG_LIBPATH} ${ZLIB_LIBPATH} ${TIFF_LIBPATH} - ${OPENEXR_LIBPATH}) + ${OPENEXR_LIBPATH} + ${OPENJPEG_LIBPATH}) + +if(WITH_OPENCOLORIO) + link_directories(${OPENCOLORIO_LIBPATH}) +endif() add_definitions(${GL_DEFINITIONS}) @@ -84,13 +89,13 @@ macro(cycles_target_link_libraries target) target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES}) endif() if(WITH_OPENCOLORIO) - link_directories(${OPENCOLORIO_LIBPATH}) target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES}) endif() target_link_libraries( ${target} ${OPENIMAGEIO_LIBRARIES} ${OPENEXR_LIBRARIES} + ${OPENJPEG_LIBRARIES} ${PUGIXML_LIBRARIES} ${BOOST_LIBRARIES} ${CMAKE_DL_LIBS} @@ -148,6 +153,7 @@ if(WITH_CYCLES_CUBIN_COMPILER) extern_cuew ${OPENIMAGEIO_LIBRARIES} ${OPENEXR_LIBRARIES} + ${OPENJPEG_LIBRARIES} ${PUGIXML_LIBRARIES} ${BOOST_LIBRARIES} ${PLATFORM_LINKLIBS} diff --git a/intern/cycles/app/io_export_cycles_xml.py b/intern/cycles/app/io_export_cycles_xml.py index 816536c0071..e7ef182120f 100644 --- a/intern/cycles/app/io_export_cycles_xml.py +++ b/intern/cycles/app/io_export_cycles_xml.py @@ -16,7 +16,6 @@ # XML exporter for generating test files, not intended for end users -import os import xml.etree.ElementTree as etree import xml.dom.minidom as dom diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 83b9a8eee0c..82372538aa8 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -253,8 +253,6 @@ def register_passes(engine, scene, srl): if crl.use_pass_volume_direct: engine.register_pass(scene, srl, "VolumeDir", 3, "RGB", 'COLOR') if crl.use_pass_volume_indirect: engine.register_pass(scene, srl, "VolumeInd", 3, "RGB", 'COLOR') - cscene = scene.cycles - if crl.use_pass_crypto_object: for i in range(0, crl.pass_crypto_depth, 2): engine.register_pass(scene, srl, "CryptoObject" + '{:02d}'.format(i), 4, "RGBA", 'COLOR') diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 370bc48f9f7..73f1fc02b08 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -968,6 +968,7 @@ protected: kg.decoupled_volume_steps[i] = NULL; } kg.decoupled_volume_steps_index = 0; + kg.coverage_asset = kg.coverage_object = kg.coverage_material = NULL; #ifdef WITH_OSL OSLShader::thread_init(&kg, &kernel_globals, &osl_globals); #endif diff --git a/intern/cycles/device/opencl/opencl.h b/intern/cycles/device/opencl/opencl.h index a8ad4a935f7..89761293638 100644 --- a/intern/cycles/device/opencl/opencl.h +++ b/intern/cycles/device/opencl/opencl.h @@ -296,9 +296,9 @@ public: const string& get_log() const { return log; } void report_error(); - /* Wait until this kernel is available to be used + /* Wait until this kernel is available to be used * It will return true when the kernel is available. - * It will return false when the kernel is not available + * It will return false when the kernel is not available * or could not be loaded. */ bool wait_for_availability(); diff --git a/intern/cycles/device/opencl/opencl_split.cpp b/intern/cycles/device/opencl/opencl_split.cpp index fd7eebf0221..489d10b7087 100644 --- a/intern/cycles/device/opencl/opencl_split.cpp +++ b/intern/cycles/device/opencl/opencl_split.cpp @@ -396,8 +396,8 @@ public: OpenCLDevice::OpenCLProgram(device, program_name, device->get_opencl_program_filename(kernel_name), - device->get_build_options(requested_features, - program_name, + device->get_build_options(requested_features, + program_name, device->use_preview_kernels)); kernel->program.add_kernel(ustring("path_trace_" + kernel_name)); @@ -770,7 +770,7 @@ bool OpenCLDevice::load_kernels(const DeviceRequestedFeatures& requested_feature /* Verify we have right opencl version. */ if(!opencl_version_check()) return false; - + load_required_kernels(requested_features); vector programs; @@ -880,7 +880,7 @@ DeviceKernelStatus OpenCLDevice::get_active_kernel_switch_state() { /* Do not switch kernels for background renderings * We do foreground rendering but use the preview kernels - * Check for the optimized kernels + * Check for the optimized kernels * * This works also the other way around, where we are using * optimized kernels but new ones are being compiled due @@ -891,7 +891,7 @@ DeviceKernelStatus OpenCLDevice::get_active_kernel_switch_state() * this as an early exit */ return DEVICE_KERNEL_USING_FEATURE_KERNEL; } - + bool other_kernels_finished = load_kernel_task_pool.finished(); if (use_preview_kernels) { if (other_kernels_finished) { diff --git a/intern/cycles/kernel/filter/filter_reconstruction.h b/intern/cycles/kernel/filter/filter_reconstruction.h index 31a7487c77a..ceda8f71f98 100644 --- a/intern/cycles/kernel/filter/filter_reconstruction.h +++ b/intern/cycles/kernel/filter/filter_reconstruction.h @@ -95,14 +95,16 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, } /* The weighted average of pixel colors (essentially, the NLM-filtered image). - * In case the solution of the linear model fails due to numerical issues, - * fall back to this value. */ + * In case the solution of the linear model fails due to numerical issues or + * returns non-sensical negative values, fall back to this value. */ float3 mean_color = XtWY[0]/XtWX[0]; math_trimatrix_vec3_solve(XtWX, XtWY, (*rank)+1, stride); float3 final_color = XtWY[0]; - if(!isfinite3_safe(final_color)) { + if(!isfinite3_safe(final_color) || + (final_color.x < -0.01f || final_color.y < -0.01f || final_color.z < -0.01f)) + { final_color = mean_color; } diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 2a300d3419e..262d7df1364 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -44,7 +44,7 @@ typedef struct LightSample { * * Note: light_p is modified when sample_coord is true. */ -ccl_device_inline float area_light_sample(float3 P, +ccl_device_inline float rect_light_sample(float3 P, float3 *light_p, float3 axisu, float3 axisv, float randu, float randv, @@ -118,6 +118,60 @@ ccl_device_inline float area_light_sample(float3 P, return 0.0f; } +ccl_device_inline float3 ellipse_sample(float3 ru, float3 rv, float randu, float randv) +{ + to_unit_disk(&randu, &randv); + return ru*randu + rv*randv; +} + +ccl_device float3 disk_light_sample(float3 v, float randu, float randv) +{ + float3 ru, rv; + + make_orthonormals(v, &ru, &rv); + + return ellipse_sample(ru, rv, randu, randv); +} + +ccl_device float3 distant_light_sample(float3 D, float radius, float randu, float randv) +{ + return normalize(D + disk_light_sample(D, randu, randv)*radius); +} + +ccl_device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv) +{ + return disk_light_sample(normalize(P - center), randu, randv)*radius; +} + +ccl_device float spot_light_attenuation(float3 dir, float spot_angle, float spot_smooth, LightSample *ls) +{ + float3 I = ls->Ng; + + float attenuation = dot(dir, I); + + if(attenuation <= spot_angle) { + attenuation = 0.0f; + } + else { + float t = attenuation - spot_angle; + + if(t < spot_smooth && spot_smooth != 0.0f) + attenuation *= smoothstepf(t/spot_smooth); + } + + return attenuation; +} + +ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) +{ + float cos_pi = dot(Ng, I); + + if(cos_pi <= 0.0f) + return 0.0f; + + return t*t/cos_pi; +} + /* Background Light */ #ifdef __BACKGROUND_MIS__ @@ -291,11 +345,19 @@ ccl_device_inline float background_portal_pdf(KernelGlobals *kg, const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal); float3 axisu = make_float3(klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]); float3 axisv = make_float3(klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]); + bool is_round = (klight->area.invarea < 0.0f); - if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL, NULL, NULL)) + if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL, NULL, NULL, is_round)) continue; - portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false); + if(is_round) { + float t; + float3 D = normalize_len(lightpos - P, &t); + portal_pdf += fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t); + } + else { + portal_pdf += rect_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false); + } } if(ignore_portal >= 0) { @@ -345,15 +407,26 @@ ccl_device float3 background_portal_sample(KernelGlobals *kg, const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal); float3 axisu = make_float3(klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]); float3 axisv = make_float3(klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]); - - *pdf = area_light_sample(P, &lightpos, - axisu, axisv, - randu, randv, - true); + bool is_round = (klight->area.invarea < 0.0f); + + float3 D; + if(is_round) { + lightpos += ellipse_sample(axisu*0.5f, axisv*0.5f, randu, randv); + float t; + D = normalize_len(lightpos - P, &t); + *pdf = fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t); + } + else { + *pdf = rect_light_sample(P, &lightpos, + axisu, axisv, + randu, randv, + true); + D = normalize(lightpos - P); + } *pdf /= num_possible; *sampled_portal = p; - return normalize(lightpos - P); + return D; } portal--; @@ -454,55 +527,6 @@ ccl_device float background_light_pdf(KernelGlobals *kg, float3 P, float3 direct /* Regular Light */ -ccl_device float3 disk_light_sample(float3 v, float randu, float randv) -{ - float3 ru, rv; - - make_orthonormals(v, &ru, &rv); - to_unit_disk(&randu, &randv); - - return ru*randu + rv*randv; -} - -ccl_device float3 distant_light_sample(float3 D, float radius, float randu, float randv) -{ - return normalize(D + disk_light_sample(D, randu, randv)*radius); -} - -ccl_device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv) -{ - return disk_light_sample(normalize(P - center), randu, randv)*radius; -} - -ccl_device float spot_light_attenuation(float3 dir, float spot_angle, float spot_smooth, LightSample *ls) -{ - float3 I = ls->Ng; - - float attenuation = dot(dir, I); - - if(attenuation <= spot_angle) { - attenuation = 0.0f; - } - else { - float t = attenuation - spot_angle; - - if(t < spot_smooth && spot_smooth != 0.0f) - attenuation *= smoothstepf(t/spot_smooth); - } - - return attenuation; -} - -ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) -{ - float cos_pi = dot(Ng, I); - - if(cos_pi <= 0.0f) - return 0.0f; - - return t*t/cos_pi; -} - ccl_device_inline bool lamp_light_sample(KernelGlobals *kg, int lamp, float randu, float randv, @@ -597,26 +621,39 @@ ccl_device_inline bool lamp_light_sample(KernelGlobals *kg, float3 D = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]); + float invarea = fabsf(klight->area.invarea); + bool is_round = (klight->area.invarea < 0.0f); if(dot(ls->P - P, D) > 0.0f) { return false; } - float3 inplane = ls->P; - ls->pdf = area_light_sample(P, &ls->P, - axisu, axisv, - randu, randv, - true); + float3 inplane; + + if(is_round) { + inplane = ellipse_sample(axisu*0.5f, axisv*0.5f, randu, randv); + ls->P += inplane; + ls->pdf = invarea; + } + else { + inplane = ls->P; + ls->pdf = rect_light_sample(P, &ls->P, + axisu, axisv, + randu, randv, + true); + inplane = ls->P - inplane; + } - inplane = ls->P - inplane; ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f; ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f; ls->Ng = D; ls->D = normalize_len(ls->P - P, &ls->t); - float invarea = klight->area.invarea; ls->eval_fac = 0.25f*invarea; + if(is_round) { + ls->pdf *= lamp_light_pdf(kg, D, -ls->D, ls->t); + } } } @@ -727,7 +764,8 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, } else if(type == LIGHT_AREA) { /* area light */ - float invarea = klight->area.invarea; + float invarea = fabsf(klight->area.invarea); + bool is_round = (klight->area.invarea < 0.0f); if(invarea == 0.0f) return false; @@ -750,14 +788,20 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, if(!ray_quad_intersect(P, D, 0.0f, t, light_P, axisu, axisv, Ng, &ls->P, &ls->t, - &ls->u, &ls->v)) + &ls->u, &ls->v, + is_round)) { return false; } ls->D = D; ls->Ng = Ng; - ls->pdf = area_light_sample(P, &light_P, axisu, axisv, 0, 0, false); + if(is_round) { + ls->pdf = invarea * lamp_light_pdf(kg, Ng, -D, ls->t); + } + else { + ls->pdf = rect_light_sample(P, &light_P, axisu, axisv, 0, 0, false); + } ls->eval_fac = 0.25f*invarea; } else { diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index b305fa59123..1d1668a20d1 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -329,8 +329,17 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) for(size_t i = 0; i < passes.size(); i++) { Pass& pass = passes[i]; - if(pass.type == PASS_NONE) + if(pass.type == PASS_NONE) { continue; + } + + /* Can't do motion pass if no motion vectors are available. */ + if (pass.type == PASS_MOTION || pass.type == PASS_MOTION_WEIGHT) { + if (scene->need_motion() != Scene::MOTION_PASS) { + kfilm->pass_stride += pass.components; + continue; + } + } int pass_flag = (1 << (pass.type % 32)); if(pass.type <= PASS_CATEGORY_MAIN_END) { diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 341a95c0258..1edd5865836 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -1020,6 +1020,39 @@ void ImageManager::device_update_slot(Device *device, } } +void ImageManager::device_load_builtin(Device *device, + Scene *scene, + Progress& progress) +{ + /* Load only builtin images, Blender needs this to load evaluated + * scene data from depsgraph before it is freed. */ + if(!need_update) { + return; + } + + TaskPool pool; + for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { + for(size_t slot = 0; slot < images[type].size(); slot++) { + if(!images[type][slot]) + continue; + + if(images[type][slot]->need_load) { + if(images[type][slot]->builtin_data) { + pool.push(function_bind(&ImageManager::device_load_image, + this, + device, + scene, + (ImageDataType)type, + slot, + &progress)); + } + } + } + } + + pool.wait_work(); +} + void ImageManager::device_free_builtin(Device *device) { for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index cd7130b3898..1403b9050fd 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -96,6 +96,10 @@ public: int flat_slot, Progress *progress); void device_free(Device *device); + + void device_load_builtin(Device *device, + Scene *scene, + Progress& progress); void device_free_builtin(Device *device); void set_osl_texture_system(void *texture_system); diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 7439f82790d..56d60adf71d 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -118,6 +118,7 @@ NODE_DEFINE(Light) SOCKET_FLOAT(sizeu, "Size U", 1.0f); SOCKET_VECTOR(axisv, "Axis V", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_FLOAT(sizev, "Size V", 1.0f); + SOCKET_BOOLEAN(round, "Round", false); SOCKET_INT(map_resolution, "Map Resolution", 0); @@ -756,12 +757,15 @@ void LightManager::device_update_points(Device *, float3 axisu = light->axisu*(light->sizeu*light->size); float3 axisv = light->axisv*(light->sizev*light->size); float area = len(axisu)*len(axisv); - float invarea = (area > 0.0f)? 1.0f/area: 1.0f; + if(light->round) { + area *= -M_PI_4_F; + } + float invarea = (area != 0.0f)? 1.0f/area: 1.0f; float3 dir = light->dir; dir = safe_normalize(dir); - if(light->use_mis && area > 0.0f) + if(light->use_mis && area != 0.0f) shader_id |= SHADER_USE_MIS; klights[light_index].co[0] = co.x; @@ -829,7 +833,10 @@ void LightManager::device_update_points(Device *, float3 axisu = light->axisu*(light->sizeu*light->size); float3 axisv = light->axisv*(light->sizev*light->size); float area = len(axisu)*len(axisv); - float invarea = (area > 0.0f)? 1.0f/area: 1.0f; + if(light->round) { + area *= -M_PI_4_F; + } + float invarea = (area != 0.0f)? 1.0f/area: 1.0f; float3 dir = light->dir; dir = safe_normalize(dir); diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index e7c06604fc4..a627ec9bdc3 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -51,6 +51,7 @@ public: float sizeu; float3 axisv; float sizev; + bool round; Transform tfm; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 6ba98391a61..cc9dd8f2679 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1520,6 +1520,19 @@ void PointDensityTextureNode::attributes(Shader *shader, ShaderNode::attributes(shader, attributes); } +void PointDensityTextureNode::add_image() +{ + if(slot == -1) { + ImageMetaData metadata; + slot = image_manager->add_image(filename.string(), builtin_data, + false, 0, + interpolation, + EXTENSION_CLIP, + true, + metadata); + } +} + void PointDensityTextureNode::compile(SVMCompiler& compiler) { ShaderInput *vector_in = input("Vector"); @@ -1532,15 +1545,7 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler) image_manager = compiler.image_manager; if(use_density || use_color) { - if(slot == -1) { - ImageMetaData metadata; - slot = image_manager->add_image(filename.string(), builtin_data, - false, 0, - interpolation, - EXTENSION_CLIP, - true, - metadata); - } + add_image(); if(slot != -1) { compiler.stack_assign(vector_in); @@ -1583,15 +1588,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler) image_manager = compiler.image_manager; if(use_density || use_color) { - if(slot == -1) { - ImageMetaData metadata; - slot = image_manager->add_image(filename.string(), builtin_data, - false, 0, - interpolation, - EXTENSION_CLIP, - true, - metadata); - } + add_image(); if(slot != -1) { compiler.parameter("filename", string_printf("@i%d", slot).c_str()); diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 5c27929719a..5571c525e9a 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -268,6 +268,8 @@ public: bool has_spatial_varying() { return true; } bool has_object_dependency() { return true; } + void add_image(); + ustring filename; NodeTexVoxelSpace space; InterpolationType interpolation; diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 59c4f5fccb8..1f551f206ef 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -84,7 +84,10 @@ DeviceScene::DeviceScene(Device *device) } Scene::Scene(const SceneParams& params_, Device *device) -: device(device), dscene(device), params(params_) + : name("Scene"), + device(device), + dscene(device), + params(params_) { memset((void *)&dscene.data, 0, sizeof(dscene.data)); diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 22b2a61743d..e43800fe5c4 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -197,6 +197,9 @@ public: class Scene { public: + /* Optional name. Is used for logging and reporting. */ + string name; + /* data */ Camera *camera; Camera *dicing_camera; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 0f40ab7b15f..3c94f2dfb59 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -208,6 +208,7 @@ Shader::Shader() need_update = true; need_update_mesh = true; + need_sync_object = false; } Shader::~Shader() diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 4c7b2fd433b..05772b9a9cd 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -99,6 +99,7 @@ public: /* synchronization */ bool need_update; bool need_update_mesh; + bool need_sync_object; /* If the shader has only volume components, the surface is assumed to * be transparent. diff --git a/intern/cycles/util/util_ies.cpp b/intern/cycles/util/util_ies.cpp index e1de2e0c6e4..277045d9bc4 100644 --- a/intern/cycles/util/util_ies.cpp +++ b/intern/cycles/util/util_ies.cpp @@ -293,7 +293,7 @@ bool IESFile::process_type_c() { if(h_angles[0] == 90.0f) { /* Some files are stored from 90° to 270°, so we just rotate them to the regular 0°-180° range here. */ - for(int i = 0; i < v_angles.size(); i++) { + for(int i = 0; i < h_angles.size(); i++) { h_angles[i] -= 90.0f; } } diff --git a/intern/cycles/util/util_ies.h b/intern/cycles/util/util_ies.h index 663ad649a9c..096b1fdf803 100644 --- a/intern/cycles/util/util_ies.h +++ b/intern/cycles/util/util_ies.h @@ -40,7 +40,7 @@ protected: bool process_type_c(); /* The brightness distribution is stored in spherical coordinates. - * The horizontal angles correspond to to theta in the regular notation + * The horizontal angles correspond to theta in the regular notation * and always span the full range from 0° to 360°. * The vertical angles correspond to phi and always start at 0°. */ vector v_angles, h_angles; diff --git a/intern/cycles/util/util_math_intersect.h b/intern/cycles/util/util_math_intersect.h index 190c2f5d6b0..aa75783d378 100644 --- a/intern/cycles/util/util_math_intersect.h +++ b/intern/cycles/util/util_math_intersect.h @@ -186,12 +186,17 @@ ccl_device_forceinline bool ray_triangle_intersect( #undef dot3 } +/* Tests for an intersection between a ray and a quad defined by + * its midpoint, normal and sides. + * If ellipse is true, hits outside the ellipse that's enclosed by the + * quad are rejected. + */ ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_mint, float ray_maxt, float3 quad_P, float3 quad_u, float3 quad_v, float3 quad_n, float3 *isect_P, float *isect_t, - float *isect_u, float *isect_v) + float *isect_u, float *isect_v, bool ellipse) { /* Perform intersection test. */ float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n); @@ -200,20 +205,23 @@ ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, } const float3 hit = ray_P + t*ray_D; const float3 inplane = hit - quad_P; - const float u = dot(inplane, quad_u) / dot(quad_u, quad_u) + 0.5f; - if(u < 0.0f || u > 1.0f) { + const float u = dot(inplane, quad_u) / dot(quad_u, quad_u); + if(u < -0.5f || u > 0.5f) { + return false; + } + const float v = dot(inplane, quad_v) / dot(quad_v, quad_v); + if(v < -0.5f || v > 0.5f) { return false; } - const float v = dot(inplane, quad_v) / dot(quad_v, quad_v) + 0.5f; - if(v < 0.0f || v > 1.0f) { + if(ellipse && (u*u + v*v > 0.25f)) { return false; } /* Store the result. */ /* TODO(sergey): Check whether we can avoid some checks here. */ if(isect_P != NULL) *isect_P = hit; if(isect_t != NULL) *isect_t = t; - if(isect_u != NULL) *isect_u = u; - if(isect_v != NULL) *isect_v = v; + if(isect_u != NULL) *isect_u = u + 0.5f; + if(isect_v != NULL) *isect_v = v + 0.5f; return true; } -- cgit v1.2.3