Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/shader.cpp
| Show First 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| pass_id = 0; | pass_id = 0; | ||||
| graph = NULL; | graph = NULL; | ||||
| has_surface = false; | has_surface = false; | ||||
| has_surface_transparent = false; | has_surface_transparent = false; | ||||
| has_surface_emission = false; | has_surface_emission = false; | ||||
| has_surface_raytrace = false; | |||||
| has_surface_bssrdf = false; | has_surface_bssrdf = false; | ||||
| has_volume = false; | has_volume = false; | ||||
| has_displacement = false; | has_displacement = false; | ||||
| has_bump = false; | has_bump = false; | ||||
| has_bssrdf_bump = false; | has_bssrdf_bump = false; | ||||
| has_surface_spatial_varying = false; | has_surface_spatial_varying = false; | ||||
| has_volume_spatial_varying = false; | has_volume_spatial_varying = false; | ||||
| has_volume_attribute_dependency = false; | has_volume_attribute_dependency = false; | ||||
| ▲ Show 20 Lines • Show All 266 Lines • ▼ Show 20 Lines | void ShaderManager::device_update(Device *device, | ||||
| assert(scene->default_surface->reference_count() != 0); | assert(scene->default_surface->reference_count() != 0); | ||||
| assert(scene->default_light->reference_count() != 0); | assert(scene->default_light->reference_count() != 0); | ||||
| assert(scene->default_background->reference_count() != 0); | assert(scene->default_background->reference_count() != 0); | ||||
| assert(scene->default_empty->reference_count() != 0); | assert(scene->default_empty->reference_count() != 0); | ||||
| device_update_specific(device, dscene, scene, progress); | device_update_specific(device, dscene, scene, progress); | ||||
| } | } | ||||
| void ShaderManager::device_update_common(Device *device, | void ShaderManager::device_update_common(Device * /*device*/, | ||||
| DeviceScene *dscene, | DeviceScene *dscene, | ||||
| Scene *scene, | Scene *scene, | ||||
| Progress & /*progress*/) | Progress & /*progress*/) | ||||
| { | { | ||||
| dscene->shaders.free(); | dscene->shaders.free(); | ||||
| if (scene->shaders.size() == 0) | if (scene->shaders.size() == 0) | ||||
| return; | return; | ||||
| KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size()); | KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size()); | ||||
| bool has_volumes = false; | bool has_volumes = false; | ||||
| bool has_transparent_shadow = false; | bool has_transparent_shadow = false; | ||||
| foreach (Shader *shader, scene->shaders) { | foreach (Shader *shader, scene->shaders) { | ||||
| uint flag = 0; | uint flag = 0; | ||||
| if (shader->get_use_mis()) | if (shader->get_use_mis()) | ||||
| flag |= SD_USE_MIS; | flag |= SD_USE_MIS; | ||||
| if (shader->has_surface_emission) | if (shader->has_surface_emission) | ||||
| flag |= SD_HAS_EMISSION; | flag |= SD_HAS_EMISSION; | ||||
| if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) | if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) | ||||
| flag |= SD_HAS_TRANSPARENT_SHADOW; | flag |= SD_HAS_TRANSPARENT_SHADOW; | ||||
| if (shader->has_surface_raytrace) | |||||
| flag |= SD_HAS_RAYTRACE; | |||||
| if (shader->has_volume) { | if (shader->has_volume) { | ||||
| flag |= SD_HAS_VOLUME; | flag |= SD_HAS_VOLUME; | ||||
| has_volumes = true; | has_volumes = true; | ||||
| /* todo: this could check more fine grained, to skip useless volumes | /* todo: this could check more fine grained, to skip useless volumes | ||||
| * enclosed inside an opaque bsdf. | * enclosed inside an opaque bsdf. | ||||
| */ | */ | ||||
| flag |= SD_HAS_TRANSPARENT_SHADOW; | flag |= SD_HAS_TRANSPARENT_SHADOW; | ||||
| } | } | ||||
| /* in this case we can assume transparent surface */ | /* in this case we can assume transparent surface */ | ||||
| if (shader->has_volume_connected && !shader->has_surface) | if (shader->has_volume_connected && !shader->has_surface) | ||||
| flag |= SD_HAS_ONLY_VOLUME; | flag |= SD_HAS_ONLY_VOLUME; | ||||
| if (shader->has_volume) { | if (shader->has_volume) { | ||||
| if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) | if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) | ||||
| flag |= SD_HETEROGENEOUS_VOLUME; | flag |= SD_HETEROGENEOUS_VOLUME; | ||||
| } | } | ||||
| if (shader->has_volume_attribute_dependency) | if (shader->has_volume_attribute_dependency) | ||||
| flag |= SD_NEED_VOLUME_ATTRIBUTES; | flag |= SD_NEED_VOLUME_ATTRIBUTES; | ||||
| if (shader->has_bssrdf_bump) | if (shader->has_bssrdf_bump) | ||||
| flag |= SD_HAS_BSSRDF_BUMP; | flag |= SD_HAS_BSSRDF_BUMP; | ||||
| if (device->info.has_volume_decoupled) { | |||||
| if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR) | if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR) | ||||
| flag |= SD_VOLUME_EQUIANGULAR; | flag |= SD_VOLUME_EQUIANGULAR; | ||||
| if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) | if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) | ||||
| flag |= SD_VOLUME_MIS; | flag |= SD_VOLUME_MIS; | ||||
| } | |||||
| if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) | if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) | ||||
| flag |= SD_VOLUME_CUBIC; | flag |= SD_VOLUME_CUBIC; | ||||
| if (shader->has_bump) | if (shader->has_bump) | ||||
| flag |= SD_HAS_BUMP; | flag |= SD_HAS_BUMP; | ||||
| if (shader->get_displacement_method() != DISPLACE_BUMP) | if (shader->get_displacement_method() != DISPLACE_BUMP) | ||||
| flag |= SD_HAS_DISPLACEMENT; | flag |= SD_HAS_DISPLACEMENT; | ||||
| /* constant emission check */ | /* constant emission check */ | ||||
| ▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | /* default empty */ | ||||
| shader->name = "default_empty"; | shader->name = "default_empty"; | ||||
| shader->set_graph(graph); | shader->set_graph(graph); | ||||
| shader->reference(); | shader->reference(); | ||||
| scene->default_empty = shader; | scene->default_empty = shader; | ||||
| shader->tag_update(scene); | shader->tag_update(scene); | ||||
| } | } | ||||
| } | } | ||||
| void ShaderManager::get_requested_graph_features(ShaderGraph *graph, | uint ShaderManager::get_graph_kernel_features(ShaderGraph *graph) | ||||
| DeviceRequestedFeatures *requested_features) | |||||
| { | { | ||||
| uint kernel_features = 0; | |||||
| foreach (ShaderNode *node, graph->nodes) { | foreach (ShaderNode *node, graph->nodes) { | ||||
| requested_features->max_nodes_group = max(requested_features->max_nodes_group, | kernel_features |= node->get_feature(); | ||||
| node->get_group()); | |||||
| requested_features->nodes_features |= node->get_feature(); | |||||
| if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) { | if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) { | ||||
| BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node); | BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node); | ||||
| if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) { | if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) { | ||||
| requested_features->nodes_features |= NODE_FEATURE_VOLUME; | kernel_features |= KERNEL_FEATURE_NODE_VOLUME; | ||||
| } | } | ||||
| else if (CLOSURE_IS_PRINCIPLED(bsdf_node->get_closure_type())) { | else if (CLOSURE_IS_PRINCIPLED(bsdf_node->get_closure_type())) { | ||||
| requested_features->use_principled = true; | kernel_features |= KERNEL_FEATURE_PRINCIPLED; | ||||
| } | } | ||||
| } | } | ||||
| if (node->has_surface_bssrdf()) { | if (node->has_surface_bssrdf()) { | ||||
| requested_features->use_subsurface = true; | kernel_features |= KERNEL_FEATURE_SUBSURFACE; | ||||
| } | } | ||||
| if (node->has_surface_transparent()) { | if (node->has_surface_transparent()) { | ||||
| requested_features->use_transparent = true; | kernel_features |= KERNEL_FEATURE_TRANSPARENT; | ||||
| } | |||||
| if (node->has_raytrace()) { | |||||
| requested_features->use_shader_raytrace = true; | |||||
| } | } | ||||
| } | } | ||||
| return kernel_features; | |||||
| } | } | ||||
| void ShaderManager::get_requested_features(Scene *scene, | uint ShaderManager::get_kernel_features(Scene *scene) | ||||
| DeviceRequestedFeatures *requested_features) | |||||
| { | { | ||||
| requested_features->max_nodes_group = NODE_GROUP_LEVEL_0; | uint kernel_features = KERNEL_FEATURE_NODE_BSDF | KERNEL_FEATURE_NODE_EMISSION; | ||||
| requested_features->nodes_features = 0; | |||||
| for (int i = 0; i < scene->shaders.size(); i++) { | for (int i = 0; i < scene->shaders.size(); i++) { | ||||
| Shader *shader = scene->shaders[i]; | Shader *shader = scene->shaders[i]; | ||||
| if (!shader->reference_count()) { | if (!shader->reference_count()) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* Gather requested features from all the nodes from the graph nodes. */ | /* Gather requested features from all the nodes from the graph nodes. */ | ||||
| get_requested_graph_features(shader->graph, requested_features); | kernel_features |= get_graph_kernel_features(shader->graph); | ||||
| ShaderNode *output_node = shader->graph->output(); | ShaderNode *output_node = shader->graph->output(); | ||||
| if (output_node->input("Displacement")->link != NULL) { | if (output_node->input("Displacement")->link != NULL) { | ||||
| requested_features->nodes_features |= NODE_FEATURE_BUMP; | kernel_features |= KERNEL_FEATURE_NODE_BUMP; | ||||
| if (shader->get_displacement_method() == DISPLACE_BOTH) { | if (shader->get_displacement_method() == DISPLACE_BOTH) { | ||||
| requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE; | kernel_features |= KERNEL_FEATURE_NODE_BUMP_STATE; | ||||
| requested_features->max_nodes_group = max(requested_features->max_nodes_group, | |||||
| NODE_GROUP_LEVEL_1); | |||||
| } | } | ||||
| } | } | ||||
| /* On top of volume nodes, also check if we need volume sampling because | /* On top of volume nodes, also check if we need volume sampling because | ||||
| * e.g. an Emission node would slip through the NODE_FEATURE_VOLUME check */ | * e.g. an Emission node would slip through the KERNEL_FEATURE_NODE_VOLUME check */ | ||||
| if (shader->has_volume) | if (shader->has_volume) { | ||||
| requested_features->use_volume |= true; | kernel_features |= KERNEL_FEATURE_VOLUME; | ||||
| } | |||||
| } | } | ||||
| return kernel_features; | |||||
| } | } | ||||
| void ShaderManager::free_memory() | void ShaderManager::free_memory() | ||||
| { | { | ||||
| beckmann_table.free_memory(); | beckmann_table.free_memory(); | ||||
| #ifdef WITH_OSL | #ifdef WITH_OSL | ||||
| OSLShaderManager::free_memory(); | OSLShaderManager::free_memory(); | ||||
| ▲ Show 20 Lines • Show All 131 Lines • Show Last 20 Lines | |||||