Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/scene/light.cpp
| Show First 20 Lines • Show All 715 Lines • ▼ Show 20 Lines | if (!background_light || !background_light->is_enabled) { | ||||
| return; | return; | ||||
| } | } | ||||
| progress.set_status("Updating Lights", "Importance map"); | progress.set_status("Updating Lights", "Importance map"); | ||||
| int2 environment_res = make_int2(0, 0); | int2 environment_res = make_int2(0, 0); | ||||
| Shader *shader = scene->background->get_shader(scene); | Shader *shader = scene->background->get_shader(scene); | ||||
| int num_suns = 0; | int num_suns = 0; | ||||
| float sun_average_radiance = 0.0f; | |||||
| foreach (ShaderNode *node, shader->graph->nodes) { | foreach (ShaderNode *node, shader->graph->nodes) { | ||||
| if (node->type == EnvironmentTextureNode::get_node_type()) { | if (node->type == EnvironmentTextureNode::get_node_type()) { | ||||
| EnvironmentTextureNode *env = (EnvironmentTextureNode *)node; | EnvironmentTextureNode *env = (EnvironmentTextureNode *)node; | ||||
| if (!env->handle.empty()) { | if (!env->handle.empty()) { | ||||
| ImageMetaData metadata = env->handle.metadata(); | ImageMetaData metadata = env->handle.metadata(); | ||||
| environment_res.x = max(environment_res.x, (int)metadata.width); | environment_res.x = max(environment_res.x, (int)metadata.width); | ||||
| environment_res.y = max(environment_res.y, (int)metadata.height); | environment_res.y = max(environment_res.y, (int)metadata.height); | ||||
| } | } | ||||
| Show All 25 Lines | if (node->type == SkyTextureNode::get_node_type()) { | ||||
| /* Pack sun direction and size. */ | /* Pack sun direction and size. */ | ||||
| float half_angle = sky->get_sun_size() * 0.5f; | float half_angle = sky->get_sun_size() * 0.5f; | ||||
| kbackground->sun = make_float4( | kbackground->sun = make_float4( | ||||
| sun_direction.x, sun_direction.y, sun_direction.z, half_angle); | sun_direction.x, sun_direction.y, sun_direction.z, half_angle); | ||||
| /* empirical value */ | /* empirical value */ | ||||
| kbackground->sun_weight = 4.0f; | kbackground->sun_weight = 4.0f; | ||||
| sun_average_radiance = sky->get_sun_average_radiance(); | |||||
| environment_res.x = max(environment_res.x, 512); | environment_res.x = max(environment_res.x, 512); | ||||
| environment_res.y = max(environment_res.y, 256); | environment_res.y = max(environment_res.y, 256); | ||||
| num_suns++; | num_suns++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* If there's more than one sun, fall back to map sampling instead. */ | /* If there's more than one sun, fall back to map sampling instead. */ | ||||
| ▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | void LightManager::device_update_background(Device *device, | ||||
| for (int i = 1; i < res.y; i++) { | for (int i = 1; i < res.y; i++) { | ||||
| marg_cdf[i].x = cond_cdf[i * cdf_width + res.x].x; | 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; | marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res.y; | ||||
| } | } | ||||
| float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y; | float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y; | ||||
| marg_cdf[res.y].x = cdf_total; | marg_cdf[res.y].x = cdf_total; | ||||
| background_light->set_average_radiance(cdf_total * M_PI_2_F); | float map_average_radiance = cdf_total * M_PI_2_F; | ||||
| if (sun_average_radiance > 0.0f) { | |||||
| /* The weighting here is just a heuristic that was empirically determined. | |||||
| * The sun's average radiance is much higher than the map's average radiance, | |||||
| * but we don't want to weight the background light too much becaused | |||||
| * visibility is not accounted for anyways. */ | |||||
| background_light->set_average_radiance(0.8f * map_average_radiance + | |||||
| 0.2f * sun_average_radiance); | |||||
| } | |||||
| else { | |||||
| background_light->set_average_radiance(map_average_radiance); | |||||
| } | |||||
| if (cdf_total > 0.0f) | if (cdf_total > 0.0f) | ||||
| for (int i = 1; i < res.y; i++) | for (int i = 1; i < res.y; i++) | ||||
| marg_cdf[i].y /= cdf_total; | marg_cdf[i].y /= cdf_total; | ||||
| marg_cdf[res.y].y = 1.0f; | marg_cdf[res.y].y = 1.0f; | ||||
| VLOG_WORK << "Background MIS build time " << time_dt() - time_start << "\n"; | VLOG_WORK << "Background MIS build time " << time_dt() - time_start << "\n"; | ||||
| Show All 17 Lines | if (light->is_enabled) { | ||||
| num_lights++; | num_lights++; | ||||
| if (light->light_type == LIGHT_DISTANT) { | if (light->light_type == LIGHT_DISTANT) { | ||||
| num_distant_lights++; | num_distant_lights++; | ||||
| } | } | ||||
| else if (light->light_type == LIGHT_POINT || light->light_type == LIGHT_SPOT) { | else if (light->light_type == LIGHT_POINT || light->light_type == LIGHT_SPOT) { | ||||
| use_light_mis |= (light->size > 0.0f && light->use_mis); | use_light_mis |= (light->size > 0.0f && light->use_mis); | ||||
| } | } | ||||
| else if (light->light_type == LIGHT_AREA) { | else if (light->light_type == LIGHT_AREA) { | ||||
weizhen: If using `ShaderEval::eval()` instead we won't depend on the render kernel's logic anymore. | |||||
| use_light_mis |= light->use_mis; | use_light_mis |= light->use_mis; | ||||
| } | } | ||||
| else if (light->light_type == LIGHT_BACKGROUND) { | else if (light->light_type == LIGHT_BACKGROUND) { | ||||
| num_distant_lights++; | num_distant_lights++; | ||||
| num_background_lights++; | num_background_lights++; | ||||
| } | } | ||||
| } | } | ||||
| if (light->is_portal) { | if (light->is_portal) { | ||||
| num_portals++; | num_portals++; | ||||
| } | } | ||||
| } | } | ||||
| /* Update integrator settings. */ | /* Update integrator settings. */ | ||||
| KernelIntegrator *kintegrator = &dscene->data.integrator; | KernelIntegrator *kintegrator = &dscene->data.integrator; | ||||
Done Inline ActionsJust considering the area of the sun might not be ideal as the part that's below the horizon is invisible, could end up overestimating the contribution. weizhen: Just considering the area of the sun might not be ideal as the part that's below the horizon is… | |||||
| kintegrator->use_light_tree = scene->integrator->get_use_light_tree() && | kintegrator->use_light_tree = scene->integrator->get_use_light_tree() && | ||||
| device->info.has_light_tree; | device->info.has_light_tree; | ||||
| kintegrator->num_lights = num_lights; | kintegrator->num_lights = num_lights; | ||||
| kintegrator->num_distant_lights = num_distant_lights; | kintegrator->num_distant_lights = num_distant_lights; | ||||
| kintegrator->num_background_lights = num_background_lights; | kintegrator->num_background_lights = num_background_lights; | ||||
| kintegrator->use_light_mis = use_light_mis; | kintegrator->use_light_mis = use_light_mis; | ||||
| kintegrator->num_portals = num_portals; | kintegrator->num_portals = num_portals; | ||||
| ▲ Show 20 Lines • Show All 415 Lines • Show Last 20 Lines | |||||
If using ShaderEval::eval() instead we won't depend on the render kernel's logic anymore.