diff options
Diffstat (limited to 'intern/cycles/render/light.cpp')
-rw-r--r-- | intern/cycles/render/light.cpp | 140 |
1 files changed, 60 insertions, 80 deletions
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 15aa4e047b5..ae1150fc07b 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -14,12 +14,13 @@ * limitations under the License. */ -#include "render/light.h" #include "device/device.h" + #include "render/background.h" #include "render/film.h" #include "render/graph.h" #include "render/integrator.h" +#include "render/light.h" #include "render/mesh.h" #include "render/nodes.h" #include "render/object.h" @@ -27,6 +28,8 @@ #include "render/shader.h" #include "render/stats.h" +#include "integrator/shader_eval.h" + #include "util/util_foreach.h" #include "util/util_hash.h" #include "util/util_logging.h" @@ -43,63 +46,49 @@ static void shade_background_pixels(Device *device, vector<float3> &pixels, Progress &progress) { - /* create input */ - device_vector<uint4> d_input(device, "background_input", MEM_READ_ONLY); - device_vector<float4> d_output(device, "background_output", MEM_READ_WRITE); - - uint4 *d_input_data = d_input.alloc(width * height); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - float u = (x + 0.5f) / width; - float v = (y + 0.5f) / height; - - uint4 in = make_uint4(__float_as_int(u), __float_as_int(v), 0, 0); - d_input_data[x + y * width] = in; - } - } - - /* compute on device */ - d_output.alloc(width * height); - d_output.zero_to_device(); - d_input.copy_to_device(); - + /* Needs to be up to data for attribute access. */ device->const_copy_to("__data", &dscene->data, sizeof(dscene->data)); - DeviceTask main_task(DeviceTask::SHADER); - main_task.shader_input = d_input.device_pointer; - main_task.shader_output = d_output.device_pointer; - main_task.shader_eval_type = SHADER_EVAL_BACKGROUND; - main_task.shader_x = 0; - main_task.shader_w = width * height; - main_task.num_samples = 1; - main_task.get_cancel = function_bind(&Progress::get_cancel, &progress); - - /* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */ - list<DeviceTask> split_tasks; - main_task.split(split_tasks, 1, 128 * 128); - - foreach (DeviceTask &task, split_tasks) { - device->task_add(task); - device->task_wait(); - d_output.copy_from_device(task.shader_x, 1, task.shader_w); - } - - d_input.free(); - - float4 *d_output_data = d_output.data(); - - pixels.resize(width * height); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - pixels[y * width + x].x = d_output_data[y * width + x].x; - pixels[y * width + x].y = d_output_data[y * width + x].y; - pixels[y * width + x].z = d_output_data[y * width + x].z; - } - } + const int size = width * height; + pixels.resize(size); + + /* Evaluate shader on device. */ + ShaderEval shader_eval(device, progress); + shader_eval.eval( + SHADER_EVAL_BACKGROUND, + size, + [&](device_vector<KernelShaderEvalInput> &d_input) { + /* Fill coordinates for shading. */ + KernelShaderEvalInput *d_input_data = d_input.data(); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + float u = (x + 0.5f) / width; + float v = (y + 0.5f) / height; + + KernelShaderEvalInput in; + in.object = OBJECT_NONE; + in.prim = PRIM_NONE; + in.u = u; + in.v = v; + d_input_data[x + y * width] = in; + } + } - d_output.free(); + return size; + }, + [&](device_vector<float4> &d_output) { + /* Copy output to pixel buffer. */ + float4 *d_output_data = d_output.data(); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + pixels[y * width + x].x = d_output_data[y * width + x].x; + pixels[y * width + x].y = d_output_data[y * width + x].y; + pixels[y * width + x].z = d_output_data[y * width + x].z; + } + } + }); } /* Light */ @@ -140,15 +129,16 @@ NODE_DEFINE(Light) SOCKET_BOOLEAN(cast_shadow, "Cast Shadow", true); SOCKET_BOOLEAN(use_mis, "Use Mis", false); + SOCKET_BOOLEAN(use_camera, "Use Camera", true); SOCKET_BOOLEAN(use_diffuse, "Use Diffuse", true); SOCKET_BOOLEAN(use_glossy, "Use Glossy", true); SOCKET_BOOLEAN(use_transmission, "Use Transmission", true); SOCKET_BOOLEAN(use_scatter, "Use Scatter", true); - SOCKET_INT(samples, "Samples", 1); SOCKET_INT(max_bounces, "Max Bounces", 1024); SOCKET_UINT(random_id, "Random ID", 0); + SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", true); SOCKET_BOOLEAN(is_portal, "Is Portal", false); SOCKET_BOOLEAN(is_enabled, "Is Enabled", true); @@ -166,10 +156,6 @@ void Light::tag_update(Scene *scene) { if (is_modified()) { scene->light_manager->tag_update(scene, LightManager::LIGHT_MODIFIED); - - if (samples_is_modified()) { - scene->integrator->tag_update(scene, Integrator::LIGHT_SAMPLES_MODIFIED); - } } } @@ -193,7 +179,6 @@ LightManager::LightManager() { update_flags = UPDATE_ALL; need_update_background = true; - use_light_visibility = false; last_background_enabled = false; last_background_resolution = 0; } @@ -357,21 +342,23 @@ void LightManager::device_update_distribution(Device *, int object_id = j; int shader_flag = 0; + if (!(object->get_visibility() & PATH_RAY_CAMERA)) { + shader_flag |= SHADER_EXCLUDE_CAMERA; + } if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) { shader_flag |= SHADER_EXCLUDE_DIFFUSE; - use_light_visibility = true; } if (!(object->get_visibility() & PATH_RAY_GLOSSY)) { shader_flag |= SHADER_EXCLUDE_GLOSSY; - use_light_visibility = true; } if (!(object->get_visibility() & PATH_RAY_TRANSMIT)) { shader_flag |= SHADER_EXCLUDE_TRANSMIT; - use_light_visibility = true; } if (!(object->get_visibility() & PATH_RAY_VOLUME_SCATTER)) { shader_flag |= SHADER_EXCLUDE_SCATTER; - use_light_visibility = true; + } + if (!(object->get_is_shadow_catcher())) { + shader_flag |= SHADER_EXCLUDE_SHADOW_CATCHER; } size_t mesh_num_triangles = mesh->num_triangles(); @@ -496,10 +483,10 @@ void LightManager::device_update_distribution(Device *, kfilm->pass_shadow_scale = 1.0f; if (kintegrator->pdf_triangles != 0.0f) - kfilm->pass_shadow_scale *= 0.5f; + kfilm->pass_shadow_scale /= 0.5f; if (num_background_lights < num_lights) - kfilm->pass_shadow_scale *= (float)(num_lights - num_background_lights) / (float)num_lights; + kfilm->pass_shadow_scale /= (float)(num_lights - num_background_lights) / (float)num_lights; /* CDF */ dscene->light_distribution.copy_to_device(); @@ -766,25 +753,26 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc if (!light->cast_shadow) shader_id &= ~SHADER_CAST_SHADOW; + if (!light->use_camera) { + shader_id |= SHADER_EXCLUDE_CAMERA; + } if (!light->use_diffuse) { shader_id |= SHADER_EXCLUDE_DIFFUSE; - use_light_visibility = true; } if (!light->use_glossy) { shader_id |= SHADER_EXCLUDE_GLOSSY; - use_light_visibility = true; } if (!light->use_transmission) { shader_id |= SHADER_EXCLUDE_TRANSMIT; - use_light_visibility = true; } if (!light->use_scatter) { shader_id |= SHADER_EXCLUDE_SCATTER; - use_light_visibility = true; + } + if (!light->is_shadow_catcher) { + shader_id |= SHADER_EXCLUDE_SHADOW_CATCHER; } klights[light_index].type = light->light_type; - klights[light_index].samples = light->samples; klights[light_index].strength[0] = light->strength.x; klights[light_index].strength[1] = light->strength.y; klights[light_index].strength[2] = light->strength.z; @@ -836,19 +824,15 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc if (!(visibility & PATH_RAY_DIFFUSE)) { shader_id |= SHADER_EXCLUDE_DIFFUSE; - use_light_visibility = true; } if (!(visibility & PATH_RAY_GLOSSY)) { shader_id |= SHADER_EXCLUDE_GLOSSY; - use_light_visibility = true; } if (!(visibility & PATH_RAY_TRANSMIT)) { shader_id |= SHADER_EXCLUDE_TRANSMIT; - use_light_visibility = true; } if (!(visibility & PATH_RAY_VOLUME_SCATTER)) { shader_id |= SHADER_EXCLUDE_SCATTER; - use_light_visibility = true; } } else if (light->light_type == LIGHT_AREA) { @@ -998,8 +982,6 @@ void LightManager::device_update(Device *device, device_free(device, dscene, need_update_background); - use_light_visibility = false; - device_update_points(device, dscene, scene); if (progress.get_cancel()) return; @@ -1018,8 +1000,6 @@ void LightManager::device_update(Device *device, if (progress.get_cancel()) return; - scene->film->set_use_light_visibility(use_light_visibility); - update_flags = UPDATE_NONE; need_update_background = false; } |