Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/nodes.cpp
| Show First 20 Lines • Show All 287 Lines • ▼ Show 20 Lines | void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) | ||||
| /* Box projection computes its own UVs that always lie in the | /* Box projection computes its own UVs that always lie in the | ||||
| * 1001 tile, so there's no point in loading any others. */ | * 1001 tile, so there's no point in loading any others. */ | ||||
| if (projection == NODE_IMAGE_PROJ_BOX) { | if (projection == NODE_IMAGE_PROJ_BOX) { | ||||
| tiles.clear(); | tiles.clear(); | ||||
| tiles.push_back_slow(1001); | tiles.push_back_slow(1001); | ||||
| return; | return; | ||||
| } | } | ||||
| if (!scene->params.background) { | if (!scene->get_params().background) { | ||||
| /* During interactive renders, all tiles are loaded. | /* During interactive renders, all tiles are loaded. | ||||
| * While we could support updating this when UVs change, that could lead | * While we could support updating this when UVs change, that could lead | ||||
| * to annoying interruptions when loading images while editing UVs. */ | * to annoying interruptions when loading images while editing UVs. */ | ||||
| return; | return; | ||||
| } | } | ||||
| /* Only check UVs for tile culling if there are multiple tiles. */ | /* Only check UVs for tile culling if there are multiple tiles. */ | ||||
| if (tiles.size() < 2) { | if (tiles.size() < 2) { | ||||
| return; | return; | ||||
| } | } | ||||
| ShaderInput *vector_in = input("Vector"); | ShaderInput *vector_in = input("Vector"); | ||||
| ustring attribute; | ustring attribute; | ||||
| if (vector_in->link) { | if (vector_in->get_link()) { | ||||
| ShaderNode *node = vector_in->link->parent; | ShaderNode *node = vector_in->get_link()->get_parent(); | ||||
| if (node->type == UVMapNode::node_type) { | if (node->get_type() == UVMapNode::node_type) { | ||||
| UVMapNode *uvmap = (UVMapNode *)node; | UVMapNode *uvmap = (UVMapNode *)node; | ||||
| attribute = uvmap->get_attribute(); | attribute = uvmap->get_attribute(); | ||||
| } | } | ||||
| else if (node->type == TextureCoordinateNode::node_type) { | else if (node->get_type() == TextureCoordinateNode::node_type) { | ||||
| if (vector_in->link != node->output("UV")) { | if (vector_in->get_link() != node->output("UV")) { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| unordered_set<int> used_tiles; | unordered_set<int> used_tiles; | ||||
| /* TODO(lukas): This is quite inefficient. A fairly simple improvement would | /* TODO(lukas): This is quite inefficient. A fairly simple improvement would | ||||
| * be to have a cache in each mesh that is indexed by attribute. | * be to have a cache in each mesh that is indexed by attribute. | ||||
| * Additionally, building a graph-to-meshes list once could help. */ | * Additionally, building a graph-to-meshes list once could help. */ | ||||
| foreach (Geometry *geom, scene->geometry) { | foreach (Geometry *geom, scene->get_geometry()) { | ||||
| foreach (Node *node, geom->get_used_shaders()) { | foreach (Node *node, geom->get_used_shaders()) { | ||||
| Shader *shader = static_cast<Shader *>(node); | Shader *shader = static_cast<Shader *>(node); | ||||
| if (shader->graph == graph) { | if (shader->get_graph() == graph) { | ||||
| geom->get_uv_tiles(attribute, used_tiles); | geom->get_uv_tiles(attribute, used_tiles); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| array<int> new_tiles; | array<int> new_tiles; | ||||
| foreach (int tile, tiles) { | foreach (int tile, tiles) { | ||||
| if (used_tiles.count(tile)) { | if (used_tiles.count(tile)) { | ||||
| new_tiles.push_back_slow(tile); | new_tiles.push_back_slow(tile); | ||||
| } | } | ||||
| } | } | ||||
| tiles.steal_data(new_tiles); | tiles.steal_data(new_tiles); | ||||
| } | } | ||||
| void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| #ifdef WITH_PTEX | #ifdef WITH_PTEX | ||||
| /* todo: avoid loading other texture coordinates when using ptex, | /* todo: avoid loading other texture coordinates when using ptex, | ||||
| * and hide texture coordinate socket in the UI */ | * and hide texture coordinate socket in the UI */ | ||||
| if (shader->has_surface && string_endswith(filename, ".ptx")) { | if (shader->get_has_surface() && string_endswith(filename, ".ptx")) { | ||||
| /* ptex */ | /* ptex */ | ||||
| attributes->add(ATTR_STD_PTEX_FACE_ID); | attributes->add(ATTR_STD_PTEX_FACE_ID); | ||||
| attributes->add(ATTR_STD_PTEX_UV); | attributes->add(ATTR_STD_PTEX_UV); | ||||
| } | } | ||||
| #endif | #endif | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void ImageTextureNode::compile(SVMCompiler &compiler) | void ImageTextureNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *vector_in = input("Vector"); | ShaderInput *vector_in = input("Vector"); | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| ShaderOutput *alpha_out = output("Alpha"); | ShaderOutput *alpha_out = output("Alpha"); | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| cull_tiles(compiler.scene, compiler.current_graph); | cull_tiles(compiler.scene, compiler.current_graph); | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| handle = image_manager->add_image(filename.string(), image_params(), tiles); | handle = image_manager->add_image(filename.string(), image_params(), tiles); | ||||
| } | } | ||||
| /* All tiles have the same metadata. */ | /* All tiles have the same metadata. */ | ||||
| const ImageMetaData metadata = handle.metadata(); | const ImageMetaData metadata = handle.metadata(); | ||||
| const bool compress_as_srgb = metadata.compress_as_srgb; | const bool compress_as_srgb = metadata.compress_as_srgb; | ||||
| const ustring known_colorspace = metadata.colorspace; | const ustring known_colorspace = metadata.colorspace; | ||||
| int vector_offset = tex_mapping.compile_begin(compiler, vector_in); | int vector_offset = tex_mapping.compile_begin(compiler, vector_in); | ||||
| uint flags = 0; | uint flags = 0; | ||||
| if (compress_as_srgb) { | if (compress_as_srgb) { | ||||
| flags |= NODE_IMAGE_COMPRESS_AS_SRGB; | flags |= NODE_IMAGE_COMPRESS_AS_SRGB; | ||||
| } | } | ||||
| if (!alpha_out->links.empty()) { | if (alpha_out->is_linked()) { | ||||
| const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) || | const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) || | ||||
| alpha_type == IMAGE_ALPHA_CHANNEL_PACKED || | alpha_type == IMAGE_ALPHA_CHANNEL_PACKED || | ||||
| alpha_type == IMAGE_ALPHA_IGNORE); | alpha_type == IMAGE_ALPHA_IGNORE); | ||||
| if (unassociate_alpha) { | if (unassociate_alpha) { | ||||
| flags |= NODE_IMAGE_ALPHA_UNASSOCIATE; | flags |= NODE_IMAGE_ALPHA_UNASSOCIATE; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
| void ImageTextureNode::compile(OSLCompiler &compiler) | void ImageTextureNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *alpha_out = output("Alpha"); | ShaderOutput *alpha_out = output("Alpha"); | ||||
| tex_mapping.compile(compiler); | tex_mapping.compile(compiler); | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| handle = image_manager->add_image(filename.string(), image_params()); | handle = image_manager->add_image(filename.string(), image_params()); | ||||
| } | } | ||||
| const ImageMetaData metadata = handle.metadata(); | const ImageMetaData metadata = handle.metadata(); | ||||
| const bool is_float = metadata.is_float(); | const bool is_float = metadata.is_float(); | ||||
| const bool compress_as_srgb = metadata.compress_as_srgb; | const bool compress_as_srgb = metadata.compress_as_srgb; | ||||
| const ustring known_colorspace = metadata.colorspace; | const ustring known_colorspace = metadata.colorspace; | ||||
| Show All 9 Lines | const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) || | ||||
| alpha_type == IMAGE_ALPHA_CHANNEL_PACKED || | alpha_type == IMAGE_ALPHA_CHANNEL_PACKED || | ||||
| alpha_type == IMAGE_ALPHA_IGNORE); | alpha_type == IMAGE_ALPHA_IGNORE); | ||||
| const bool is_tiled = (filename.find("<UDIM>") != string::npos); | const bool is_tiled = (filename.find("<UDIM>") != string::npos); | ||||
| compiler.parameter(this, "projection"); | compiler.parameter(this, "projection"); | ||||
| compiler.parameter(this, "projection_blend"); | compiler.parameter(this, "projection_blend"); | ||||
| compiler.parameter("compress_as_srgb", compress_as_srgb); | compiler.parameter("compress_as_srgb", compress_as_srgb); | ||||
| compiler.parameter("ignore_alpha", alpha_type == IMAGE_ALPHA_IGNORE); | compiler.parameter("ignore_alpha", alpha_type == IMAGE_ALPHA_IGNORE); | ||||
| compiler.parameter("unassociate_alpha", !alpha_out->links.empty() && unassociate_alpha); | compiler.parameter("unassociate_alpha", alpha_out->is_linked() && unassociate_alpha); | ||||
| compiler.parameter("is_float", is_float); | compiler.parameter("is_float", is_float); | ||||
| compiler.parameter("is_tiled", is_tiled); | compiler.parameter("is_tiled", is_tiled); | ||||
| compiler.parameter(this, "interpolation"); | compiler.parameter(this, "interpolation"); | ||||
| compiler.parameter(this, "extension"); | compiler.parameter(this, "extension"); | ||||
| compiler.add(this, "node_image_texture"); | compiler.add(this, "node_image_texture"); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | ImageParams EnvironmentTextureNode::image_params() const | ||||
| params.alpha_type = alpha_type; | params.alpha_type = alpha_type; | ||||
| params.colorspace = colorspace; | params.colorspace = colorspace; | ||||
| return params; | return params; | ||||
| } | } | ||||
| void EnvironmentTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void EnvironmentTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| #ifdef WITH_PTEX | #ifdef WITH_PTEX | ||||
| if (shader->has_surface && string_endswith(filename, ".ptx")) { | if (shader->get_has_surface() && string_endswith(filename, ".ptx")) { | ||||
| /* ptex */ | /* ptex */ | ||||
| attributes->add(ATTR_STD_PTEX_FACE_ID); | attributes->add(ATTR_STD_PTEX_FACE_ID); | ||||
| attributes->add(ATTR_STD_PTEX_UV); | attributes->add(ATTR_STD_PTEX_UV); | ||||
| } | } | ||||
| #endif | #endif | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void EnvironmentTextureNode::compile(SVMCompiler &compiler) | void EnvironmentTextureNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *vector_in = input("Vector"); | ShaderInput *vector_in = input("Vector"); | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| ShaderOutput *alpha_out = output("Alpha"); | ShaderOutput *alpha_out = output("Alpha"); | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| handle = image_manager->add_image(filename.string(), image_params()); | handle = image_manager->add_image(filename.string(), image_params()); | ||||
| } | } | ||||
| const ImageMetaData metadata = handle.metadata(); | const ImageMetaData metadata = handle.metadata(); | ||||
| const bool compress_as_srgb = metadata.compress_as_srgb; | const bool compress_as_srgb = metadata.compress_as_srgb; | ||||
| const ustring known_colorspace = metadata.colorspace; | const ustring known_colorspace = metadata.colorspace; | ||||
| int vector_offset = tex_mapping.compile_begin(compiler, vector_in); | int vector_offset = tex_mapping.compile_begin(compiler, vector_in); | ||||
| Show All 12 Lines | compiler.add_node(NODE_TEX_ENVIRONMENT, | ||||
| projection); | projection); | ||||
| tex_mapping.compile_end(compiler, vector_in, vector_offset); | tex_mapping.compile_end(compiler, vector_in, vector_offset); | ||||
| } | } | ||||
| void EnvironmentTextureNode::compile(OSLCompiler &compiler) | void EnvironmentTextureNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| handle = image_manager->add_image(filename.string(), image_params()); | handle = image_manager->add_image(filename.string(), image_params()); | ||||
| } | } | ||||
| tex_mapping.compile(compiler); | tex_mapping.compile(compiler); | ||||
| const ImageMetaData metadata = handle.metadata(); | const ImageMetaData metadata = handle.metadata(); | ||||
| const bool is_float = metadata.is_float(); | const bool is_float = metadata.is_float(); | ||||
| const bool compress_as_srgb = metadata.compress_as_srgb; | const bool compress_as_srgb = metadata.compress_as_srgb; | ||||
| ▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | sky_texture_precompute_nishita(&sunsky, | ||||
| get_sun_size(), | get_sun_size(), | ||||
| sun_intensity, | sun_intensity, | ||||
| sun_elevation, | sun_elevation, | ||||
| sun_rotation, | sun_rotation, | ||||
| clamped_altitude, | clamped_altitude, | ||||
| air_density, | air_density, | ||||
| dust_density); | dust_density); | ||||
| /* precomputed texture image parameters */ | /* precomputed texture image parameters */ | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| ImageParams impar; | ImageParams impar; | ||||
| impar.interpolation = INTERPOLATION_LINEAR; | impar.interpolation = INTERPOLATION_LINEAR; | ||||
| impar.extension = EXTENSION_EXTEND; | impar.extension = EXTENSION_EXTEND; | ||||
| /* precompute sky texture */ | /* precompute sky texture */ | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| SkyLoader *loader = new SkyLoader( | SkyLoader *loader = new SkyLoader( | ||||
| sun_elevation, clamped_altitude, air_density, dust_density, ozone_density); | sun_elevation, clamped_altitude, air_density, dust_density, ozone_density); | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | sky_texture_precompute_nishita(&sunsky, | ||||
| get_sun_size(), | get_sun_size(), | ||||
| sun_intensity, | sun_intensity, | ||||
| sun_elevation, | sun_elevation, | ||||
| sun_rotation, | sun_rotation, | ||||
| clamped_altitude, | clamped_altitude, | ||||
| air_density, | air_density, | ||||
| dust_density); | dust_density); | ||||
| /* precomputed texture image parameters */ | /* precomputed texture image parameters */ | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| ImageParams impar; | ImageParams impar; | ||||
| impar.interpolation = INTERPOLATION_LINEAR; | impar.interpolation = INTERPOLATION_LINEAR; | ||||
| impar.extension = EXTENSION_EXTEND; | impar.extension = EXTENSION_EXTEND; | ||||
| /* precompute sky texture */ | /* precompute sky texture */ | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| SkyLoader *loader = new SkyLoader( | SkyLoader *loader = new SkyLoader( | ||||
| sun_elevation, clamped_altitude, air_density, dust_density, ozone_density); | sun_elevation, clamped_altitude, air_density, dust_density, ozone_density); | ||||
| ▲ Show 20 Lines • Show All 312 Lines • ▼ Show 20 Lines | if (slot == -1) { | ||||
| else { | else { | ||||
| slot = light_manager->add_ies(ies.string()); | slot = light_manager->add_ies(ies.string()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void IESLightNode::compile(SVMCompiler &compiler) | void IESLightNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| light_manager = compiler.scene->light_manager; | light_manager = compiler.scene->get_light_manager(); | ||||
| get_slot(); | get_slot(); | ||||
| ShaderInput *strength_in = input("Strength"); | ShaderInput *strength_in = input("Strength"); | ||||
| ShaderInput *vector_in = input("Vector"); | ShaderInput *vector_in = input("Vector"); | ||||
| ShaderOutput *fac_out = output("Fac"); | ShaderOutput *fac_out = output("Fac"); | ||||
| int vector_offset = tex_mapping.compile_begin(compiler, vector_in); | int vector_offset = tex_mapping.compile_begin(compiler, vector_in); | ||||
| compiler.add_node(NODE_IES, | compiler.add_node(NODE_IES, | ||||
| compiler.encode_uchar4(compiler.stack_assign_if_linked(strength_in), | compiler.encode_uchar4(compiler.stack_assign_if_linked(strength_in), | ||||
| vector_offset, | vector_offset, | ||||
| compiler.stack_assign(fac_out), | compiler.stack_assign(fac_out), | ||||
| 0), | 0), | ||||
| slot, | slot, | ||||
| __float_as_int(strength)); | __float_as_int(strength)); | ||||
| tex_mapping.compile_end(compiler, vector_in, vector_offset); | tex_mapping.compile_end(compiler, vector_in, vector_offset); | ||||
| } | } | ||||
| void IESLightNode::compile(OSLCompiler &compiler) | void IESLightNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| light_manager = compiler.scene->light_manager; | light_manager = compiler.scene->get_light_manager(); | ||||
| get_slot(); | get_slot(); | ||||
| tex_mapping.compile(compiler); | tex_mapping.compile(compiler); | ||||
| compiler.parameter_texture_ies("filename", slot); | compiler.parameter_texture_ies("filename", slot); | ||||
| compiler.add(this, "node_ies_light"); | compiler.add(this, "node_ies_light"); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 488 Lines • ▼ Show 20 Lines | ShaderNode *PointDensityTextureNode::clone(ShaderGraph *graph) const | ||||
| * side. A better solution should be found to avoid this. */ | * side. A better solution should be found to avoid this. */ | ||||
| PointDensityTextureNode *node = graph->create_node<PointDensityTextureNode>(*this); | PointDensityTextureNode *node = graph->create_node<PointDensityTextureNode>(*this); | ||||
| node->handle = handle; /* TODO: not needed? */ | node->handle = handle; /* TODO: not needed? */ | ||||
| return node; | return node; | ||||
| } | } | ||||
| void PointDensityTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void PointDensityTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_volume) | if (shader->get_has_volume()) | ||||
| attributes->add(ATTR_STD_GENERATED_TRANSFORM); | attributes->add(ATTR_STD_GENERATED_TRANSFORM); | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| ImageParams PointDensityTextureNode::image_params() const | ImageParams PointDensityTextureNode::image_params() const | ||||
| { | { | ||||
| ImageParams params; | ImageParams params; | ||||
| params.interpolation = interpolation; | params.interpolation = interpolation; | ||||
| return params; | return params; | ||||
| } | } | ||||
| void PointDensityTextureNode::compile(SVMCompiler &compiler) | void PointDensityTextureNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *vector_in = input("Vector"); | ShaderInput *vector_in = input("Vector"); | ||||
| ShaderOutput *density_out = output("Density"); | ShaderOutput *density_out = output("Density"); | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| const bool use_density = !density_out->links.empty(); | const bool use_density = density_out->is_linked(); | ||||
| const bool use_color = !color_out->links.empty(); | const bool use_color = color_out->is_linked(); | ||||
| if (use_density || use_color) { | if (use_density || use_color) { | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| handle = image_manager->add_image(filename.string(), image_params()); | handle = image_manager->add_image(filename.string(), image_params()); | ||||
| } | } | ||||
| const int slot = handle.svm_slot(); | const int slot = handle.svm_slot(); | ||||
| if (slot != -1) { | if (slot != -1) { | ||||
| compiler.stack_assign(vector_in); | compiler.stack_assign(vector_in); | ||||
| compiler.add_node(NODE_TEX_VOXEL, | compiler.add_node(NODE_TEX_VOXEL, | ||||
| slot, | slot, | ||||
| Show All 21 Lines | void PointDensityTextureNode::compile(SVMCompiler &compiler) | ||||
| } | } | ||||
| } | } | ||||
| void PointDensityTextureNode::compile(OSLCompiler &compiler) | void PointDensityTextureNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *density_out = output("Density"); | ShaderOutput *density_out = output("Density"); | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| const bool use_density = !density_out->links.empty(); | const bool use_density = density_out->is_linked(); | ||||
| const bool use_color = !color_out->links.empty(); | const bool use_color = color_out->is_linked(); | ||||
| if (use_density || use_color) { | if (use_density || use_color) { | ||||
| if (handle.empty()) { | if (handle.empty()) { | ||||
| ImageManager *image_manager = compiler.scene->image_manager; | ImageManager *image_manager = compiler.scene->get_image_manager(); | ||||
| handle = image_manager->add_image(filename.string(), image_params()); | handle = image_manager->add_image(filename.string(), image_params()); | ||||
| } | } | ||||
| compiler.parameter_texture("filename", handle.svm_slot()); | compiler.parameter_texture("filename", handle.svm_slot()); | ||||
| if (space == NODE_TEX_VOXEL_SPACE_WORLD) { | if (space == NODE_TEX_VOXEL_SPACE_WORLD) { | ||||
| compiler.parameter("mapping", tfm); | compiler.parameter("mapping", tfm); | ||||
| compiler.parameter("use_mapping", 1); | compiler.parameter("use_mapping", 1); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | |||||
| RGBToBWNode::RGBToBWNode() : ShaderNode(node_type) | RGBToBWNode::RGBToBWNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void RGBToBWNode::constant_fold(const ConstantFolder &folder) | void RGBToBWNode::constant_fold(const ConstantFolder &folder) | ||||
| { | { | ||||
| if (folder.all_inputs_constant()) { | if (folder.all_inputs_constant()) { | ||||
| float val = folder.scene->shader_manager->linear_rgb_to_gray(color); | float val = folder.scene->get_shader_manager()->linear_rgb_to_gray(color); | ||||
| folder.make_constant(val); | folder.make_constant(val); | ||||
| } | } | ||||
| } | } | ||||
| void RGBToBWNode::compile(SVMCompiler &compiler) | void RGBToBWNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| compiler.add_node(NODE_CONVERT, | compiler.add_node(NODE_CONVERT, | ||||
| NODE_CONVERT_CF, | NODE_CONVERT_CF, | ||||
| compiler.stack_assign(inputs[0]), | compiler.stack_assign(inputs[0]), | ||||
| compiler.stack_assign(outputs[0])); | compiler.stack_assign(outputs[0])); | ||||
| } | } | ||||
| void RGBToBWNode::compile(OSLCompiler &compiler) | void RGBToBWNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.add(this, "node_rgb_to_bw"); | compiler.add(this, "node_rgb_to_bw"); | ||||
| } | } | ||||
| /* Convert */ | /* Convert */ | ||||
| const NodeType *ConvertNode::node_types[ConvertNode::MAX_TYPE][ConvertNode::MAX_TYPE]; | const NodeType *ConvertNode::node_types[ConvertNode::MAX_TYPE][ConvertNode::MAX_TYPE]; | ||||
| bool ConvertNode::initialized = ConvertNode::register_types(); | bool ConvertNode::initialized = ConvertNode::register_types(); | ||||
| Node *ConvertNode::create(const NodeType *type) | Node *ConvertNode::create(const NodeType *type) | ||||
| { | { | ||||
| return new ConvertNode(type->inputs[0].type, type->outputs[0].type); | return new ConvertNode(type->get_inputs()[0].get_type(), type->get_outputs()[0].get_type()); | ||||
| } | } | ||||
| bool ConvertNode::register_types() | bool ConvertNode::register_types() | ||||
| { | { | ||||
| const int num_types = 8; | const int num_types = 8; | ||||
| SocketType::Type types[num_types] = {SocketType::FLOAT, | SocketType::Type types[num_types] = {SocketType::FLOAT, | ||||
| SocketType::INT, | SocketType::INT, | ||||
| SocketType::COLOR, | SocketType::COLOR, | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | if (from == SocketType::FLOAT) { | ||||
| if (SocketType::is_float3(to)) { | if (SocketType::is_float3(to)) { | ||||
| folder.make_constant(make_float3(value_float, value_float, value_float)); | folder.make_constant(make_float3(value_float, value_float, value_float)); | ||||
| } | } | ||||
| } | } | ||||
| else if (SocketType::is_float3(from)) { | else if (SocketType::is_float3(from)) { | ||||
| if (to == SocketType::FLOAT) { | if (to == SocketType::FLOAT) { | ||||
| if (from == SocketType::COLOR) { | if (from == SocketType::COLOR) { | ||||
| /* color to float */ | /* color to float */ | ||||
| float val = folder.scene->shader_manager->linear_rgb_to_gray(value_color); | float val = folder.scene->get_shader_manager()->linear_rgb_to_gray(value_color); | ||||
| folder.make_constant(val); | folder.make_constant(val); | ||||
| } | } | ||||
| else { | else { | ||||
| /* vector/point/normal to float */ | /* vector/point/normal to float */ | ||||
| folder.make_constant(average(value_vector)); | folder.make_constant(average(value_vector)); | ||||
| } | } | ||||
| } | } | ||||
| else if (SocketType::is_float3(to)) { | else if (SocketType::is_float3(to)) { | ||||
| folder.make_constant(value_color); | folder.make_constant(value_color); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| ShaderInput *in = inputs[0]; | ShaderInput *in = inputs[0]; | ||||
| ShaderNode *prev = in->link->parent; | ShaderNode *prev = in->get_link()->get_parent(); | ||||
| /* no-op conversion of A to B to A */ | /* no-op conversion of A to B to A */ | ||||
| if (prev->type == node_types[to][from]) { | if (prev->get_type() == node_types[to][from]) { | ||||
| ShaderInput *prev_in = prev->inputs[0]; | ShaderInput *prev_in = prev->get_inputs()[0]; | ||||
| if (SocketType::is_float3(from) && (to == SocketType::FLOAT || SocketType::is_float3(to)) && | if (SocketType::is_float3(from) && (to == SocketType::FLOAT || SocketType::is_float3(to)) && | ||||
| prev_in->link) { | prev_in->get_link()) { | ||||
| folder.bypass(prev_in->link); | folder.bypass(prev_in->get_link()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void ConvertNode::compile(SVMCompiler &compiler) | void ConvertNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| /* proxy nodes should have been removed at this point */ | /* proxy nodes should have been removed at this point */ | ||||
| Show All 39 Lines | if (from == SocketType::COLOR) | ||||
| NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out)); | NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out)); | ||||
| else | else | ||||
| /* vector/point/normal to int */ | /* vector/point/normal to int */ | ||||
| compiler.add_node( | compiler.add_node( | ||||
| NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out)); | NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out)); | ||||
| } | } | ||||
| else { | else { | ||||
| /* float3 to float3 */ | /* float3 to float3 */ | ||||
| if (in->link) { | if (in->get_link()) { | ||||
| /* no op in SVM */ | /* no op in SVM */ | ||||
| compiler.stack_link(in, out); | compiler.stack_link(in, out); | ||||
| } | } | ||||
| else { | else { | ||||
| /* set 0,0,0 value */ | /* set 0,0,0 value */ | ||||
| compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out)); | compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out)); | ||||
| compiler.add_node(NODE_VALUE_V, value_color); | compiler.add_node(NODE_VALUE_V, value_color); | ||||
| } | } | ||||
| Show All 27 Lines | |||||
| { | { | ||||
| special_type = SHADER_SPECIAL_TYPE_CLOSURE; | special_type = SHADER_SPECIAL_TYPE_CLOSURE; | ||||
| } | } | ||||
| bool BsdfBaseNode::has_bump() | bool BsdfBaseNode::has_bump() | ||||
| { | { | ||||
| /* detect if anything is plugged into the normal input besides the default */ | /* detect if anything is plugged into the normal input besides the default */ | ||||
| ShaderInput *normal_in = input("Normal"); | ShaderInput *normal_in = input("Normal"); | ||||
| return (normal_in && normal_in->link && | return (normal_in && normal_in->get_link() && | ||||
| normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY); | normal_in->get_link()->get_parent()->get_special_type() != SHADER_SPECIAL_TYPE_GEOMETRY); | ||||
| } | } | ||||
| /* BSDF Closure */ | /* BSDF Closure */ | ||||
| BsdfNode::BsdfNode(const NodeType *node_type) : BsdfBaseNode(node_type) | BsdfNode::BsdfNode(const NodeType *node_type) : BsdfBaseNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void BsdfNode::compile(SVMCompiler &compiler, | void BsdfNode::compile(SVMCompiler &compiler, | ||||
| ShaderInput *param1, | ShaderInput *param1, | ||||
| ShaderInput *param2, | ShaderInput *param2, | ||||
| ShaderInput *param3, | ShaderInput *param3, | ||||
| ShaderInput *param4) | ShaderInput *param4) | ||||
| { | { | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ShaderInput *normal_in = input("Normal"); | ShaderInput *normal_in = input("Normal"); | ||||
| ShaderInput *tangent_in = input("Tangent"); | ShaderInput *tangent_in = input("Tangent"); | ||||
| if (color_in->link) | if (color_in->get_link()) | ||||
| compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); | compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); | ||||
| else | else | ||||
| compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color); | compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color); | ||||
| int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID; | int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID; | ||||
| int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) : | int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) : | ||||
| SVM_STACK_INVALID; | SVM_STACK_INVALID; | ||||
| int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID; | int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID; | ||||
| int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID; | int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID; | ||||
| compiler.add_node( | compiler.add_node( | ||||
| NODE_CLOSURE_BSDF, | NODE_CLOSURE_BSDF, | ||||
| compiler.encode_uchar4(closure, | compiler.encode_uchar4(closure, | ||||
| (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID, | (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID, | ||||
| (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID, | (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID, | ||||
| compiler.closure_mix_weight_offset()), | compiler.closure_mix_weight_offset()), | ||||
| __float_as_int((param1) ? get_float(param1->socket_type) : 0.0f), | __float_as_int((param1) ? get_float(param1->get_socket_type()) : 0.0f), | ||||
| __float_as_int((param2) ? get_float(param2->socket_type) : 0.0f)); | __float_as_int((param2) ? get_float(param2->get_socket_type()) : 0.0f)); | ||||
| compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset); | compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset); | ||||
| } | } | ||||
| void BsdfNode::compile(SVMCompiler &compiler) | void BsdfNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| compile(compiler, NULL, NULL); | compile(compiler, NULL, NULL); | ||||
| } | } | ||||
| Show All 33 Lines | |||||
| AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(node_type) | AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(node_type) | ||||
| { | { | ||||
| closure = CLOSURE_BSDF_MICROFACET_GGX_ID; | closure = CLOSURE_BSDF_MICROFACET_GGX_ID; | ||||
| } | } | ||||
| void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface) { | if (shader->get_has_surface()) { | ||||
| ShaderInput *tangent_in = input("Tangent"); | ShaderInput *tangent_in = input("Tangent"); | ||||
| if (!tangent_in->link) | if (!tangent_in->get_link()) | ||||
| attributes->add(ATTR_STD_GENERATED); | attributes->add(ATTR_STD_GENERATED); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void AnisotropicBsdfNode::compile(SVMCompiler &compiler) | void AnisotropicBsdfNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | void GlossyBsdfNode::simplify_settings(Scene *scene) | ||||
| } | } | ||||
| else { | else { | ||||
| /* By default we use original values, so we don't worry about restoring | /* By default we use original values, so we don't worry about restoring | ||||
| * defaults later one and can only do override when needed. | * defaults later one and can only do override when needed. | ||||
| */ | */ | ||||
| roughness = roughness_orig; | roughness = roughness_orig; | ||||
| distribution = distribution_orig; | distribution = distribution_orig; | ||||
| } | } | ||||
| Integrator *integrator = scene->integrator; | Integrator *integrator = scene->get_integrator(); | ||||
| ShaderInput *roughness_input = input("Roughness"); | ShaderInput *roughness_input = input("Roughness"); | ||||
| if (integrator->get_filter_glossy() == 0.0f) { | if (integrator->get_filter_glossy() == 0.0f) { | ||||
| /* Fallback to Sharp closure for Roughness close to 0. | /* Fallback to Sharp closure for Roughness close to 0. | ||||
| * Note: Keep the epsilon in sync with kernel! | * Note: Keep the epsilon in sync with kernel! | ||||
| */ | */ | ||||
| if (!roughness_input->link && roughness <= 1e-4f) { | if (!roughness_input->get_link() && roughness <= 1e-4f) { | ||||
| VLOG(1) << "Using sharp glossy BSDF."; | VLOG(1) << "Using sharp glossy BSDF."; | ||||
| distribution = CLOSURE_BSDF_REFLECTION_ID; | distribution = CLOSURE_BSDF_REFLECTION_ID; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* If filter glossy is used we replace Sharp glossy with GGX so we can | /* If filter glossy is used we replace Sharp glossy with GGX so we can | ||||
| * benefit from closure blur to remove unwanted noise. | * benefit from closure blur to remove unwanted noise. | ||||
| */ | */ | ||||
| if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFLECTION_ID) { | if (roughness_input->get_link() == NULL && distribution == CLOSURE_BSDF_REFLECTION_ID) { | ||||
| VLOG(1) << "Using GGX glossy with filter glossy."; | VLOG(1) << "Using GGX glossy with filter glossy."; | ||||
| distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; | distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; | ||||
| roughness = 0.0f; | roughness = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| closure = distribution; | closure = distribution; | ||||
| } | } | ||||
| bool GlossyBsdfNode::has_integrator_dependency() | bool GlossyBsdfNode::has_integrator_dependency() | ||||
| { | { | ||||
| ShaderInput *roughness_input = input("Roughness"); | ShaderInput *roughness_input = input("Roughness"); | ||||
| return !roughness_input->link && | return !roughness_input->get_link() && | ||||
| (distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f); | (distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f); | ||||
| } | } | ||||
| void GlossyBsdfNode::compile(SVMCompiler &compiler) | void GlossyBsdfNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| closure = distribution; | closure = distribution; | ||||
| if (closure == CLOSURE_BSDF_REFLECTION_ID) | if (closure == CLOSURE_BSDF_REFLECTION_ID) | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | void GlassBsdfNode::simplify_settings(Scene *scene) | ||||
| } | } | ||||
| else { | else { | ||||
| /* By default we use original values, so we don't worry about restoring | /* By default we use original values, so we don't worry about restoring | ||||
| * defaults later one and can only do override when needed. | * defaults later one and can only do override when needed. | ||||
| */ | */ | ||||
| roughness = roughness_orig; | roughness = roughness_orig; | ||||
| distribution = distribution_orig; | distribution = distribution_orig; | ||||
| } | } | ||||
| Integrator *integrator = scene->integrator; | Integrator *integrator = scene->get_integrator(); | ||||
| ShaderInput *roughness_input = input("Roughness"); | ShaderInput *roughness_input = input("Roughness"); | ||||
| if (integrator->get_filter_glossy() == 0.0f) { | if (integrator->get_filter_glossy() == 0.0f) { | ||||
| /* Fallback to Sharp closure for Roughness close to 0. | /* Fallback to Sharp closure for Roughness close to 0. | ||||
| * Note: Keep the epsilon in sync with kernel! | * Note: Keep the epsilon in sync with kernel! | ||||
| */ | */ | ||||
| if (!roughness_input->link && roughness <= 1e-4f) { | if (!roughness_input->get_link() && roughness <= 1e-4f) { | ||||
| VLOG(1) << "Using sharp glass BSDF."; | VLOG(1) << "Using sharp glass BSDF."; | ||||
| distribution = CLOSURE_BSDF_SHARP_GLASS_ID; | distribution = CLOSURE_BSDF_SHARP_GLASS_ID; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* If filter glossy is used we replace Sharp glossy with GGX so we can | /* If filter glossy is used we replace Sharp glossy with GGX so we can | ||||
| * benefit from closure blur to remove unwanted noise. | * benefit from closure blur to remove unwanted noise. | ||||
| */ | */ | ||||
| if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_SHARP_GLASS_ID) { | if (roughness_input->get_link() == NULL && distribution == CLOSURE_BSDF_SHARP_GLASS_ID) { | ||||
| VLOG(1) << "Using GGX glass with filter glossy."; | VLOG(1) << "Using GGX glass with filter glossy."; | ||||
| distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; | distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; | ||||
| roughness = 0.0f; | roughness = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| closure = distribution; | closure = distribution; | ||||
| } | } | ||||
| bool GlassBsdfNode::has_integrator_dependency() | bool GlassBsdfNode::has_integrator_dependency() | ||||
| { | { | ||||
| ShaderInput *roughness_input = input("Roughness"); | ShaderInput *roughness_input = input("Roughness"); | ||||
| return !roughness_input->link && | return !roughness_input->get_link() && | ||||
| (distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f); | (distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f); | ||||
| } | } | ||||
| void GlassBsdfNode::compile(SVMCompiler &compiler) | void GlassBsdfNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| closure = distribution; | closure = distribution; | ||||
| if (closure == CLOSURE_BSDF_SHARP_GLASS_ID) | if (closure == CLOSURE_BSDF_SHARP_GLASS_ID) | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | void RefractionBsdfNode::simplify_settings(Scene *scene) | ||||
| } | } | ||||
| else { | else { | ||||
| /* By default we use original values, so we don't worry about restoring | /* By default we use original values, so we don't worry about restoring | ||||
| * defaults later one and can only do override when needed. | * defaults later one and can only do override when needed. | ||||
| */ | */ | ||||
| roughness = roughness_orig; | roughness = roughness_orig; | ||||
| distribution = distribution_orig; | distribution = distribution_orig; | ||||
| } | } | ||||
| Integrator *integrator = scene->integrator; | Integrator *integrator = scene->get_integrator(); | ||||
| ShaderInput *roughness_input = input("Roughness"); | ShaderInput *roughness_input = input("Roughness"); | ||||
| if (integrator->get_filter_glossy() == 0.0f) { | if (integrator->get_filter_glossy() == 0.0f) { | ||||
| /* Fallback to Sharp closure for Roughness close to 0. | /* Fallback to Sharp closure for Roughness close to 0. | ||||
| * Note: Keep the epsilon in sync with kernel! | * Note: Keep the epsilon in sync with kernel! | ||||
| */ | */ | ||||
| if (!roughness_input->link && roughness <= 1e-4f) { | if (!roughness_input->get_link() && roughness <= 1e-4f) { | ||||
| VLOG(1) << "Using sharp refraction BSDF."; | VLOG(1) << "Using sharp refraction BSDF."; | ||||
| distribution = CLOSURE_BSDF_REFRACTION_ID; | distribution = CLOSURE_BSDF_REFRACTION_ID; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* If filter glossy is used we replace Sharp glossy with GGX so we can | /* If filter glossy is used we replace Sharp glossy with GGX so we can | ||||
| * benefit from closure blur to remove unwanted noise. | * benefit from closure blur to remove unwanted noise. | ||||
| */ | */ | ||||
| if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFRACTION_ID) { | if (roughness_input->get_link() == NULL && distribution == CLOSURE_BSDF_REFRACTION_ID) { | ||||
| VLOG(1) << "Using GGX refraction with filter glossy."; | VLOG(1) << "Using GGX refraction with filter glossy."; | ||||
| distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; | distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; | ||||
| roughness = 0.0f; | roughness = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| closure = distribution; | closure = distribution; | ||||
| } | } | ||||
| bool RefractionBsdfNode::has_integrator_dependency() | bool RefractionBsdfNode::has_integrator_dependency() | ||||
| { | { | ||||
| ShaderInput *roughness_input = input("Roughness"); | ShaderInput *roughness_input = input("Roughness"); | ||||
| return !roughness_input->link && | return !roughness_input->get_link() && | ||||
| (distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f); | (distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f); | ||||
| } | } | ||||
| void RefractionBsdfNode::compile(SVMCompiler &compiler) | void RefractionBsdfNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| closure = distribution; | closure = distribution; | ||||
| if (closure == CLOSURE_BSDF_REFRACTION_ID) | if (closure == CLOSURE_BSDF_REFRACTION_ID) | ||||
| ▲ Show 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| void PrincipledBsdfNode::expand(ShaderGraph *graph) | void PrincipledBsdfNode::expand(ShaderGraph *graph) | ||||
| { | { | ||||
| ShaderOutput *principled_out = output("BSDF"); | ShaderOutput *principled_out = output("BSDF"); | ||||
| ShaderInput *emission_in = input("Emission"); | ShaderInput *emission_in = input("Emission"); | ||||
| ShaderInput *emission_strength_in = input("Emission Strength"); | ShaderInput *emission_strength_in = input("Emission Strength"); | ||||
| if ((emission_in->link || emission != make_float3(0.0f, 0.0f, 0.0f)) && | if ((emission_in->get_link() || emission != make_float3(0.0f, 0.0f, 0.0f)) && | ||||
| (emission_strength_in->link || emission_strength != 0.0f)) { | (emission_strength_in->get_link() || emission_strength != 0.0f)) { | ||||
| /* Create add closure and emission, and relink inputs. */ | /* Create add closure and emission, and relink inputs. */ | ||||
| AddClosureNode *add = graph->create_node<AddClosureNode>(); | AddClosureNode *add = graph->create_node<AddClosureNode>(); | ||||
| EmissionNode *emission_node = graph->create_node<EmissionNode>(); | EmissionNode *emission_node = graph->create_node<EmissionNode>(); | ||||
| ShaderOutput *new_out = add->output("Closure"); | ShaderOutput *new_out = add->output("Closure"); | ||||
| graph->add(add); | graph->add(add); | ||||
| graph->add(emission_node); | graph->add(emission_node); | ||||
| graph->relink(emission_strength_in, emission_node->input("Strength")); | graph->relink(emission_strength_in, emission_node->input("Strength")); | ||||
| graph->relink(emission_in, emission_node->input("Color")); | graph->relink(emission_in, emission_node->input("Color")); | ||||
| graph->relink(principled_out, new_out); | graph->relink(principled_out, new_out); | ||||
| graph->connect(emission_node->output("Emission"), add->input("Closure1")); | graph->connect(emission_node->output("Emission"), add->input("Closure1")); | ||||
| graph->connect(principled_out, add->input("Closure2")); | graph->connect(principled_out, add->input("Closure2")); | ||||
| principled_out = new_out; | principled_out = new_out; | ||||
| } | } | ||||
| else { | else { | ||||
| /* Disconnect unused links if the other value is zero, required before | /* Disconnect unused links if the other value is zero, required before | ||||
| * we remove the input from the node entirely. */ | * we remove the input from the node entirely. */ | ||||
| if (emission_in->link) { | if (emission_in->get_link()) { | ||||
| emission_in->disconnect(); | emission_in->disconnect(); | ||||
| } | } | ||||
| if (emission_strength_in->link) { | if (emission_strength_in->get_link()) { | ||||
| emission_strength_in->disconnect(); | emission_strength_in->disconnect(); | ||||
| } | } | ||||
| } | } | ||||
| ShaderInput *alpha_in = input("Alpha"); | ShaderInput *alpha_in = input("Alpha"); | ||||
| if (alpha_in->link || alpha != 1.0f) { | if (alpha_in->get_link() || alpha != 1.0f) { | ||||
| /* Create mix and transparent BSDF for alpha transparency. */ | /* Create mix and transparent BSDF for alpha transparency. */ | ||||
| MixClosureNode *mix = graph->create_node<MixClosureNode>(); | MixClosureNode *mix = graph->create_node<MixClosureNode>(); | ||||
| TransparentBsdfNode *transparent = graph->create_node<TransparentBsdfNode>(); | TransparentBsdfNode *transparent = graph->create_node<TransparentBsdfNode>(); | ||||
| graph->add(mix); | graph->add(mix); | ||||
| graph->add(transparent); | graph->add(transparent); | ||||
| graph->relink(alpha_in, mix->input("Fac")); | graph->relink(alpha_in, mix->input("Fac")); | ||||
| graph->relink(principled_out, mix->output("Closure")); | graph->relink(principled_out, mix->output("Closure")); | ||||
| graph->connect(transparent->output("BSDF"), mix->input("Closure1")); | graph->connect(transparent->output("BSDF"), mix->input("Closure1")); | ||||
| graph->connect(principled_out, mix->input("Closure2")); | graph->connect(principled_out, mix->input("Closure2")); | ||||
| } | } | ||||
| remove_input(emission_in); | remove_input(emission_in); | ||||
| remove_input(emission_strength_in); | remove_input(emission_strength_in); | ||||
| remove_input(alpha_in); | remove_input(alpha_in); | ||||
| } | } | ||||
| bool PrincipledBsdfNode::has_surface_bssrdf() | bool PrincipledBsdfNode::has_surface_bssrdf() | ||||
| { | { | ||||
| ShaderInput *subsurface_in = input("Subsurface"); | ShaderInput *subsurface_in = input("Subsurface"); | ||||
| return (subsurface_in->link != NULL || subsurface > CLOSURE_WEIGHT_CUTOFF); | return (subsurface_in->get_link() != NULL || subsurface > CLOSURE_WEIGHT_CUTOFF); | ||||
| } | } | ||||
| void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface) { | if (shader->get_has_surface()) { | ||||
| ShaderInput *tangent_in = input("Tangent"); | ShaderInput *tangent_in = input("Tangent"); | ||||
| if (!tangent_in->link) | if (!tangent_in->get_link()) | ||||
| attributes->add(ATTR_STD_GENERATED); | attributes->add(ATTR_STD_GENERATED); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void PrincipledBsdfNode::compile(SVMCompiler &compiler, | void PrincipledBsdfNode::compile(SVMCompiler &compiler, | ||||
| ShaderInput *p_metallic, | ShaderInput *p_metallic, | ||||
| Show All 34 Lines | void PrincipledBsdfNode::compile(SVMCompiler &compiler, | ||||
| int clearcoat_offset = compiler.stack_assign(p_clearcoat); | int clearcoat_offset = compiler.stack_assign(p_clearcoat); | ||||
| int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness); | int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness); | ||||
| int ior_offset = compiler.stack_assign(p_ior); | int ior_offset = compiler.stack_assign(p_ior); | ||||
| int transmission_offset = compiler.stack_assign(p_transmission); | int transmission_offset = compiler.stack_assign(p_transmission); | ||||
| int transmission_roughness_offset = compiler.stack_assign(p_transmission_roughness); | int transmission_roughness_offset = compiler.stack_assign(p_transmission_roughness); | ||||
| int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation); | int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation); | ||||
| int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius); | int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius); | ||||
| compiler.add_node(NODE_CLOSURE_BSDF, | compiler.add_node( | ||||
| NODE_CLOSURE_BSDF, | |||||
| compiler.encode_uchar4(closure, | compiler.encode_uchar4(closure, | ||||
| compiler.stack_assign(p_metallic), | compiler.stack_assign(p_metallic), | ||||
| compiler.stack_assign(p_subsurface), | compiler.stack_assign(p_subsurface), | ||||
| compiler.closure_mix_weight_offset()), | compiler.closure_mix_weight_offset()), | ||||
| __float_as_int((p_metallic) ? get_float(p_metallic->socket_type) : 0.0f), | __float_as_int((p_metallic) ? get_float(p_metallic->get_socket_type()) : 0.0f), | ||||
| __float_as_int((p_subsurface) ? get_float(p_subsurface->socket_type) : 0.0f)); | __float_as_int((p_subsurface) ? get_float(p_subsurface->get_socket_type()) : 0.0f)); | ||||
| compiler.add_node( | compiler.add_node( | ||||
| normal_offset, | normal_offset, | ||||
| tangent_offset, | tangent_offset, | ||||
| compiler.encode_uchar4( | compiler.encode_uchar4( | ||||
| specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset), | specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset), | ||||
| compiler.encode_uchar4( | compiler.encode_uchar4( | ||||
| sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset)); | sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset)); | ||||
| compiler.add_node(compiler.encode_uchar4(ior_offset, | compiler.add_node(compiler.encode_uchar4(ior_offset, | ||||
| transmission_offset, | transmission_offset, | ||||
| anisotropic_rotation_offset, | anisotropic_rotation_offset, | ||||
| transmission_roughness_offset), | transmission_roughness_offset), | ||||
| distribution, | distribution, | ||||
| subsurface_method, | subsurface_method, | ||||
| SVM_STACK_INVALID); | SVM_STACK_INVALID); | ||||
| float3 bc_default = get_float3(base_color_in->socket_type); | float3 bc_default = get_float3(base_color_in->get_socket_type()); | ||||
| compiler.add_node( | compiler.add_node( | ||||
| ((base_color_in->link) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID), | ((base_color_in->get_link()) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID), | ||||
| __float_as_int(bc_default.x), | __float_as_int(bc_default.x), | ||||
| __float_as_int(bc_default.y), | __float_as_int(bc_default.y), | ||||
| __float_as_int(bc_default.z)); | __float_as_int(bc_default.z)); | ||||
| compiler.add_node( | compiler.add_node( | ||||
| clearcoat_normal_offset, subsurface_radius_offset, SVM_STACK_INVALID, SVM_STACK_INVALID); | clearcoat_normal_offset, subsurface_radius_offset, SVM_STACK_INVALID, SVM_STACK_INVALID); | ||||
| float3 ss_default = get_float3(subsurface_color_in->socket_type); | float3 ss_default = get_float3(subsurface_color_in->get_socket_type()); | ||||
| compiler.add_node(((subsurface_color_in->link) ? compiler.stack_assign(subsurface_color_in) : | compiler.add_node(((subsurface_color_in->get_link()) ? | ||||
| compiler.stack_assign(subsurface_color_in) : | |||||
| SVM_STACK_INVALID), | SVM_STACK_INVALID), | ||||
| __float_as_int(ss_default.x), | __float_as_int(ss_default.x), | ||||
| __float_as_int(ss_default.y), | __float_as_int(ss_default.y), | ||||
| __float_as_int(ss_default.z)); | __float_as_int(ss_default.z)); | ||||
| } | } | ||||
| bool PrincipledBsdfNode::has_integrator_dependency() | bool PrincipledBsdfNode::has_integrator_dependency() | ||||
| { | { | ||||
| ShaderInput *roughness_input = input("Roughness"); | ShaderInput *roughness_input = input("Roughness"); | ||||
| return !roughness_input->link && roughness <= 1e-4f; | return !roughness_input->get_link() && roughness <= 1e-4f; | ||||
| } | } | ||||
| void PrincipledBsdfNode::compile(SVMCompiler &compiler) | void PrincipledBsdfNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| compile(compiler, | compile(compiler, | ||||
| input("Metallic"), | input("Metallic"), | ||||
| input("Subsurface"), | input("Subsurface"), | ||||
| input("Subsurface Radius"), | input("Subsurface Radius"), | ||||
| ▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | void SubsurfaceScatteringNode::compile(OSLCompiler &compiler) | ||||
| compiler.parameter(this, "falloff"); | compiler.parameter(this, "falloff"); | ||||
| compiler.add(this, "node_subsurface_scattering"); | compiler.add(this, "node_subsurface_scattering"); | ||||
| } | } | ||||
| bool SubsurfaceScatteringNode::has_bssrdf_bump() | bool SubsurfaceScatteringNode::has_bssrdf_bump() | ||||
| { | { | ||||
| /* detect if anything is plugged into the normal input besides the default */ | /* detect if anything is plugged into the normal input besides the default */ | ||||
| ShaderInput *normal_in = input("Normal"); | ShaderInput *normal_in = input("Normal"); | ||||
| return (normal_in->link && | return (normal_in->get_link() && | ||||
| normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY); | normal_in->get_link()->get_parent()->get_special_type() != SHADER_SPECIAL_TYPE_GEOMETRY); | ||||
| } | } | ||||
| /* Emissive Closure */ | /* Emissive Closure */ | ||||
| NODE_DEFINE(EmissionNode) | NODE_DEFINE(EmissionNode) | ||||
| { | { | ||||
| NodeType *type = NodeType::add("emission", create, NodeType::SHADER); | NodeType *type = NodeType::add("emission", create, NodeType::SHADER); | ||||
| Show All 10 Lines | |||||
| { | { | ||||
| } | } | ||||
| void EmissionNode::compile(SVMCompiler &compiler) | void EmissionNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ShaderInput *strength_in = input("Strength"); | ShaderInput *strength_in = input("Strength"); | ||||
| if (color_in->link || strength_in->link) { | if (color_in->get_link() || strength_in->get_link()) { | ||||
| compiler.add_node( | compiler.add_node( | ||||
| NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in)); | NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in)); | ||||
| } | } | ||||
| else | else | ||||
| compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength); | compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength); | ||||
| compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset()); | compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset()); | ||||
| } | } | ||||
| void EmissionNode::compile(OSLCompiler &compiler) | void EmissionNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.add(this, "node_emission"); | compiler.add(this, "node_emission"); | ||||
| } | } | ||||
| void EmissionNode::constant_fold(const ConstantFolder &folder) | void EmissionNode::constant_fold(const ConstantFolder &folder) | ||||
| { | { | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ShaderInput *strength_in = input("Strength"); | ShaderInput *strength_in = input("Strength"); | ||||
| if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) || | if ((!color_in->get_link() && color == make_float3(0.0f, 0.0f, 0.0f)) || | ||||
| (!strength_in->link && strength == 0.0f)) { | (!strength_in->get_link() && strength == 0.0f)) { | ||||
| folder.discard(); | folder.discard(); | ||||
| } | } | ||||
| } | } | ||||
| /* Background Closure */ | /* Background Closure */ | ||||
| NODE_DEFINE(BackgroundNode) | NODE_DEFINE(BackgroundNode) | ||||
| { | { | ||||
| Show All 12 Lines | |||||
| { | { | ||||
| } | } | ||||
| void BackgroundNode::compile(SVMCompiler &compiler) | void BackgroundNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ShaderInput *strength_in = input("Strength"); | ShaderInput *strength_in = input("Strength"); | ||||
| if (color_in->link || strength_in->link) { | if (color_in->get_link() || strength_in->get_link()) { | ||||
| compiler.add_node( | compiler.add_node( | ||||
| NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in)); | NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in)); | ||||
| } | } | ||||
| else | else | ||||
| compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength); | compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength); | ||||
| compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset()); | compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset()); | ||||
| } | } | ||||
| void BackgroundNode::compile(OSLCompiler &compiler) | void BackgroundNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.add(this, "node_background"); | compiler.add(this, "node_background"); | ||||
| } | } | ||||
| void BackgroundNode::constant_fold(const ConstantFolder &folder) | void BackgroundNode::constant_fold(const ConstantFolder &folder) | ||||
| { | { | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ShaderInput *strength_in = input("Strength"); | ShaderInput *strength_in = input("Strength"); | ||||
| if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) || | if ((!color_in->get_link() && color == make_float3(0.0f, 0.0f, 0.0f)) || | ||||
| (!strength_in->link && strength == 0.0f)) { | (!strength_in->get_link() && strength == 0.0f)) { | ||||
| folder.discard(); | folder.discard(); | ||||
| } | } | ||||
| } | } | ||||
| /* Holdout Closure */ | /* Holdout Closure */ | ||||
| NODE_DEFINE(HoldoutNode) | NODE_DEFINE(HoldoutNode) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | void AmbientOcclusionNode::compile(SVMCompiler &compiler) | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ShaderInput *distance_in = input("Distance"); | ShaderInput *distance_in = input("Distance"); | ||||
| ShaderInput *normal_in = input("Normal"); | ShaderInput *normal_in = input("Normal"); | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| ShaderOutput *ao_out = output("AO"); | ShaderOutput *ao_out = output("AO"); | ||||
| int flags = (inside ? NODE_AO_INSIDE : 0) | (only_local ? NODE_AO_ONLY_LOCAL : 0); | int flags = (inside ? NODE_AO_INSIDE : 0) | (only_local ? NODE_AO_ONLY_LOCAL : 0); | ||||
| if (!distance_in->link && distance == 0.0f) { | if (!distance_in->get_link() && distance == 0.0f) { | ||||
| flags |= NODE_AO_GLOBAL_RADIUS; | flags |= NODE_AO_GLOBAL_RADIUS; | ||||
| } | } | ||||
| compiler.add_node(NODE_AMBIENT_OCCLUSION, | compiler.add_node(NODE_AMBIENT_OCCLUSION, | ||||
| compiler.encode_uchar4(flags, | compiler.encode_uchar4(flags, | ||||
| compiler.stack_assign_if_linked(distance_in), | compiler.stack_assign_if_linked(distance_in), | ||||
| compiler.stack_assign_if_linked(normal_in), | compiler.stack_assign_if_linked(normal_in), | ||||
| compiler.stack_assign(ao_out)), | compiler.stack_assign(ao_out)), | ||||
| Show All 17 Lines | |||||
| { | { | ||||
| closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID; | closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID; | ||||
| } | } | ||||
| void VolumeNode::compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2) | void VolumeNode::compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2) | ||||
| { | { | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| if (color_in->link) | if (color_in->get_link()) | ||||
| compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); | compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); | ||||
| else | else | ||||
| compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color); | compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color); | ||||
| compiler.add_node( | compiler.add_node( | ||||
| NODE_CLOSURE_VOLUME, | NODE_CLOSURE_VOLUME, | ||||
| compiler.encode_uchar4(closure, | compiler.encode_uchar4(closure, | ||||
| (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID, | (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID, | ||||
| (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID, | (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID, | ||||
| compiler.closure_mix_weight_offset()), | compiler.closure_mix_weight_offset()), | ||||
| __float_as_int((param1) ? get_float(param1->socket_type) : 0.0f), | __float_as_int((param1) ? get_float(param1->get_socket_type()) : 0.0f), | ||||
| __float_as_int((param2) ? get_float(param2->socket_type) : 0.0f)); | __float_as_int((param2) ? get_float(param2->get_socket_type()) : 0.0f)); | ||||
| } | } | ||||
| void VolumeNode::compile(SVMCompiler &compiler) | void VolumeNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| compile(compiler, NULL, NULL); | compile(compiler, NULL, NULL); | ||||
| } | } | ||||
| void VolumeNode::compile(OSLCompiler & /*compiler*/) | void VolumeNode::compile(OSLCompiler & /*compiler*/) | ||||
| ▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID; | closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID; | ||||
| density_attribute = ustring("density"); | density_attribute = ustring("density"); | ||||
| temperature_attribute = ustring("temperature"); | temperature_attribute = ustring("temperature"); | ||||
| } | } | ||||
| void PrincipledVolumeNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void PrincipledVolumeNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_volume) { | if (shader->get_has_volume()) { | ||||
| ShaderInput *density_in = input("Density"); | ShaderInput *density_in = input("Density"); | ||||
| ShaderInput *blackbody_in = input("Blackbody Intensity"); | ShaderInput *blackbody_in = input("Blackbody Intensity"); | ||||
| if (density_in->link || density > 0.0f) { | if (density_in->get_link() || density > 0.0f) { | ||||
| attributes->add_standard(density_attribute); | attributes->add_standard(density_attribute); | ||||
| attributes->add_standard(color_attribute); | attributes->add_standard(color_attribute); | ||||
| } | } | ||||
| if (blackbody_in->link || blackbody_intensity > 0.0f) { | if (blackbody_in->get_link() || blackbody_intensity > 0.0f) { | ||||
| attributes->add_standard(temperature_attribute); | attributes->add_standard(temperature_attribute); | ||||
| } | } | ||||
| attributes->add(ATTR_STD_GENERATED_TRANSFORM); | attributes->add(ATTR_STD_GENERATED_TRANSFORM); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void PrincipledVolumeNode::compile(SVMCompiler &compiler) | void PrincipledVolumeNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ShaderInput *density_in = input("Density"); | ShaderInput *density_in = input("Density"); | ||||
| ShaderInput *anisotropy_in = input("Anisotropy"); | ShaderInput *anisotropy_in = input("Anisotropy"); | ||||
| ShaderInput *absorption_color_in = input("Absorption Color"); | ShaderInput *absorption_color_in = input("Absorption Color"); | ||||
| ShaderInput *emission_in = input("Emission Strength"); | ShaderInput *emission_in = input("Emission Strength"); | ||||
| ShaderInput *emission_color_in = input("Emission Color"); | ShaderInput *emission_color_in = input("Emission Color"); | ||||
| ShaderInput *blackbody_in = input("Blackbody Intensity"); | ShaderInput *blackbody_in = input("Blackbody Intensity"); | ||||
| ShaderInput *blackbody_tint_in = input("Blackbody Tint"); | ShaderInput *blackbody_tint_in = input("Blackbody Tint"); | ||||
| ShaderInput *temperature_in = input("Temperature"); | ShaderInput *temperature_in = input("Temperature"); | ||||
| if (color_in->link) | if (color_in->get_link()) | ||||
| compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); | compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); | ||||
| else | else | ||||
| compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color); | compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color); | ||||
| compiler.add_node(NODE_PRINCIPLED_VOLUME, | compiler.add_node(NODE_PRINCIPLED_VOLUME, | ||||
| compiler.encode_uchar4(compiler.stack_assign_if_linked(density_in), | compiler.encode_uchar4(compiler.stack_assign_if_linked(density_in), | ||||
| compiler.stack_assign_if_linked(anisotropy_in), | compiler.stack_assign_if_linked(anisotropy_in), | ||||
| compiler.stack_assign(absorption_color_in), | compiler.stack_assign(absorption_color_in), | ||||
| ▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | |||||
| PrincipledHairBsdfNode::PrincipledHairBsdfNode() : BsdfBaseNode(node_type) | PrincipledHairBsdfNode::PrincipledHairBsdfNode() : BsdfBaseNode(node_type) | ||||
| { | { | ||||
| closure = CLOSURE_BSDF_HAIR_PRINCIPLED_ID; | closure = CLOSURE_BSDF_HAIR_PRINCIPLED_ID; | ||||
| } | } | ||||
| /* Enable retrieving Hair Info -> Random if Random isn't linked. */ | /* Enable retrieving Hair Info -> Random if Random isn't linked. */ | ||||
| void PrincipledHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void PrincipledHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (!input("Random")->link) { | if (!input("Random")->get_link()) { | ||||
| attributes->add(ATTR_STD_CURVE_RANDOM); | attributes->add(ATTR_STD_CURVE_RANDOM); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| /* Prepares the input data for the SVM shader. */ | /* Prepares the input data for the SVM shader. */ | ||||
| void PrincipledHairBsdfNode::compile(SVMCompiler &compiler) | void PrincipledHairBsdfNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| Show All 9 Lines | void PrincipledHairBsdfNode::compile(SVMCompiler &compiler) | ||||
| ShaderInput *melanin_redness_in = input("Melanin Redness"); | ShaderInput *melanin_redness_in = input("Melanin Redness"); | ||||
| ShaderInput *random_color_in = input("Random Color"); | ShaderInput *random_color_in = input("Random Color"); | ||||
| int color_ofs = compiler.stack_assign(input("Color")); | int color_ofs = compiler.stack_assign(input("Color")); | ||||
| int tint_ofs = compiler.stack_assign(input("Tint")); | int tint_ofs = compiler.stack_assign(input("Tint")); | ||||
| int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient")); | int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient")); | ||||
| ShaderInput *random_in = input("Random"); | ShaderInput *random_in = input("Random"); | ||||
| int attr_random = random_in->link ? SVM_STACK_INVALID : | int attr_random = random_in->get_link() ? SVM_STACK_INVALID : | ||||
| compiler.attribute(ATTR_STD_CURVE_RANDOM); | compiler.attribute(ATTR_STD_CURVE_RANDOM); | ||||
| /* Encode all parameters into data nodes. */ | /* Encode all parameters into data nodes. */ | ||||
| compiler.add_node(NODE_CLOSURE_BSDF, | compiler.add_node(NODE_CLOSURE_BSDF, | ||||
| /* Socket IDs can be packed 4 at a time into a single data packet */ | /* Socket IDs can be packed 4 at a time into a single data packet */ | ||||
| compiler.encode_uchar4(closure, | compiler.encode_uchar4(closure, | ||||
| compiler.stack_assign_if_linked(roughness_in), | compiler.stack_assign_if_linked(roughness_in), | ||||
| compiler.stack_assign_if_linked(radial_roughness_in), | compiler.stack_assign_if_linked(radial_roughness_in), | ||||
| compiler.closure_mix_weight_offset()), | compiler.closure_mix_weight_offset()), | ||||
| ▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | |||||
| GeometryNode::GeometryNode() : ShaderNode(node_type) | GeometryNode::GeometryNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| special_type = SHADER_SPECIAL_TYPE_GEOMETRY; | special_type = SHADER_SPECIAL_TYPE_GEOMETRY; | ||||
| } | } | ||||
| void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface) { | if (shader->get_has_surface()) { | ||||
| if (!output("Tangent")->links.empty()) { | if (output("Tangent")->is_linked()) { | ||||
| attributes->add(ATTR_STD_GENERATED); | attributes->add(ATTR_STD_GENERATED); | ||||
| } | } | ||||
| if (!output("Pointiness")->links.empty()) { | if (output("Pointiness")->is_linked()) { | ||||
| attributes->add(ATTR_STD_POINTINESS); | attributes->add(ATTR_STD_POINTINESS); | ||||
| } | } | ||||
| if (!output("Random Per Island")->links.empty()) { | if (output("Random Per Island")->is_linked()) { | ||||
| attributes->add(ATTR_STD_RANDOM_PER_ISLAND); | attributes->add(ATTR_STD_RANDOM_PER_ISLAND); | ||||
| } | } | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void GeometryNode::compile(SVMCompiler &compiler) | void GeometryNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *out; | ShaderOutput *out; | ||||
| ShaderNodeType geom_node = NODE_GEOMETRY; | ShaderNodeType geom_node = NODE_GEOMETRY; | ||||
| ShaderNodeType attr_node = NODE_ATTR; | ShaderNodeType attr_node = NODE_ATTR; | ||||
| if (bump == SHADER_BUMP_DX) { | if (bump == SHADER_BUMP_DX) { | ||||
| geom_node = NODE_GEOMETRY_BUMP_DX; | geom_node = NODE_GEOMETRY_BUMP_DX; | ||||
| attr_node = NODE_ATTR_BUMP_DX; | attr_node = NODE_ATTR_BUMP_DX; | ||||
| } | } | ||||
| else if (bump == SHADER_BUMP_DY) { | else if (bump == SHADER_BUMP_DY) { | ||||
| geom_node = NODE_GEOMETRY_BUMP_DY; | geom_node = NODE_GEOMETRY_BUMP_DY; | ||||
| attr_node = NODE_ATTR_BUMP_DY; | attr_node = NODE_ATTR_BUMP_DY; | ||||
| } | } | ||||
| out = output("Position"); | out = output("Position"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Normal"); | out = output("Normal"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_N, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_N, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Tangent"); | out = output("Tangent"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_T, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_T, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("True Normal"); | out = output("True Normal"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_Ng, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_Ng, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Incoming"); | out = output("Incoming"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Parametric"); | out = output("Parametric"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_uv, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_uv, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Backfacing"); | out = output("Backfacing"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Pointiness"); | out = output("Pointiness"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| if (compiler.output_type() != SHADER_TYPE_VOLUME) { | if (compiler.output_type() != SHADER_TYPE_VOLUME) { | ||||
| compiler.add_node( | compiler.add_node( | ||||
| attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); | attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); | ||||
| } | } | ||||
| else { | else { | ||||
| compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out)); | compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out)); | ||||
| } | } | ||||
| } | } | ||||
| out = output("Random Per Island"); | out = output("Random Per Island"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| if (compiler.output_type() != SHADER_TYPE_VOLUME) { | if (compiler.output_type() != SHADER_TYPE_VOLUME) { | ||||
| compiler.add_node(attr_node, | compiler.add_node(attr_node, | ||||
| ATTR_STD_RANDOM_PER_ISLAND, | ATTR_STD_RANDOM_PER_ISLAND, | ||||
| compiler.stack_assign(out), | compiler.stack_assign(out), | ||||
| NODE_ATTR_OUTPUT_FLOAT); | NODE_ATTR_OUTPUT_FLOAT); | ||||
| } | } | ||||
| else { | else { | ||||
| compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out)); | compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out)); | ||||
| Show All 15 Lines | |||||
| int GeometryNode::get_group() | int GeometryNode::get_group() | ||||
| { | { | ||||
| ShaderOutput *out; | ShaderOutput *out; | ||||
| int result = ShaderNode::get_group(); | int result = ShaderNode::get_group(); | ||||
| /* Backfacing uses NODE_LIGHT_PATH */ | /* Backfacing uses NODE_LIGHT_PATH */ | ||||
| out = output("Backfacing"); | out = output("Backfacing"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| result = max(result, NODE_GROUP_LEVEL_1); | result = max(result, NODE_GROUP_LEVEL_1); | ||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| /* TextureCoordinate */ | /* TextureCoordinate */ | ||||
| Show All 22 Lines | |||||
| } | } | ||||
| TextureCoordinateNode::TextureCoordinateNode() : ShaderNode(node_type) | TextureCoordinateNode::TextureCoordinateNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface) { | if (shader->get_has_surface()) { | ||||
| if (!from_dupli) { | if (!from_dupli) { | ||||
| if (!output("Generated")->links.empty()) | if (output("Generated")->is_linked()) | ||||
| attributes->add(ATTR_STD_GENERATED); | attributes->add(ATTR_STD_GENERATED); | ||||
| if (!output("UV")->links.empty()) | if (output("UV")->is_linked()) | ||||
| attributes->add(ATTR_STD_UV); | attributes->add(ATTR_STD_UV); | ||||
| } | } | ||||
| } | } | ||||
| if (shader->has_volume) { | if (shader->get_has_volume()) { | ||||
| if (!from_dupli) { | if (!from_dupli) { | ||||
| if (!output("Generated")->links.empty()) { | if (output("Generated")->is_linked()) { | ||||
| attributes->add(ATTR_STD_GENERATED_TRANSFORM); | attributes->add(ATTR_STD_GENERATED_TRANSFORM); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| Show All 11 Lines | void TextureCoordinateNode::compile(SVMCompiler &compiler) | ||||
| } | } | ||||
| else if (bump == SHADER_BUMP_DY) { | else if (bump == SHADER_BUMP_DY) { | ||||
| texco_node = NODE_TEX_COORD_BUMP_DY; | texco_node = NODE_TEX_COORD_BUMP_DY; | ||||
| attr_node = NODE_ATTR_BUMP_DY; | attr_node = NODE_ATTR_BUMP_DY; | ||||
| geom_node = NODE_GEOMETRY_BUMP_DY; | geom_node = NODE_GEOMETRY_BUMP_DY; | ||||
| } | } | ||||
| out = output("Generated"); | out = output("Generated"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| if (compiler.background) { | if (compiler.background) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out)); | ||||
| } | } | ||||
| else { | else { | ||||
| if (from_dupli) { | if (from_dupli) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, compiler.stack_assign(out)); | ||||
| } | } | ||||
| else if (compiler.output_type() == SHADER_TYPE_VOLUME) { | else if (compiler.output_type() == SHADER_TYPE_VOLUME) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, compiler.stack_assign(out)); | ||||
| } | } | ||||
| else { | else { | ||||
| int attr = compiler.attribute(ATTR_STD_GENERATED); | int attr = compiler.attribute(ATTR_STD_GENERATED); | ||||
| compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3); | compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| out = output("Normal"); | out = output("Normal"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_NORMAL, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_NORMAL, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("UV"); | out = output("UV"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| if (from_dupli) { | if (from_dupli) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out)); | ||||
| } | } | ||||
| else { | else { | ||||
| int attr = compiler.attribute(ATTR_STD_UV); | int attr = compiler.attribute(ATTR_STD_UV); | ||||
| compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3); | compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3); | ||||
| } | } | ||||
| } | } | ||||
| out = output("Object"); | out = output("Object"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_OBJECT, compiler.stack_assign(out), use_transform); | compiler.add_node(texco_node, NODE_TEXCO_OBJECT, compiler.stack_assign(out), use_transform); | ||||
| if (use_transform) { | if (use_transform) { | ||||
| Transform ob_itfm = transform_inverse(ob_tfm); | Transform ob_itfm = transform_inverse(ob_tfm); | ||||
| compiler.add_node(ob_itfm.x); | compiler.add_node(ob_itfm.x); | ||||
| compiler.add_node(ob_itfm.y); | compiler.add_node(ob_itfm.y); | ||||
| compiler.add_node(ob_itfm.z); | compiler.add_node(ob_itfm.z); | ||||
| } | } | ||||
| } | } | ||||
| out = output("Camera"); | out = output("Camera"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_CAMERA, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_CAMERA, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Window"); | out = output("Window"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_WINDOW, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_WINDOW, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Reflection"); | out = output("Reflection"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| if (compiler.background) { | if (compiler.background) { | ||||
| compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out)); | compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out)); | ||||
| } | } | ||||
| else { | else { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, compiler.stack_assign(out)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Show All 35 Lines | |||||
| } | } | ||||
| UVMapNode::UVMapNode() : ShaderNode(node_type) | UVMapNode::UVMapNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void UVMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void UVMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface) { | if (shader->get_has_surface()) { | ||||
| if (!from_dupli) { | if (!from_dupli) { | ||||
| if (!output("UV")->links.empty()) { | if (output("UV")->is_linked()) { | ||||
| if (attribute != "") | if (attribute != "") | ||||
| attributes->add(attribute); | attributes->add(attribute); | ||||
| else | else | ||||
| attributes->add(ATTR_STD_UV); | attributes->add(ATTR_STD_UV); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Show All 11 Lines | if (bump == SHADER_BUMP_DX) { | ||||
| texco_node = NODE_TEX_COORD_BUMP_DX; | texco_node = NODE_TEX_COORD_BUMP_DX; | ||||
| attr_node = NODE_ATTR_BUMP_DX; | attr_node = NODE_ATTR_BUMP_DX; | ||||
| } | } | ||||
| else if (bump == SHADER_BUMP_DY) { | else if (bump == SHADER_BUMP_DY) { | ||||
| texco_node = NODE_TEX_COORD_BUMP_DY; | texco_node = NODE_TEX_COORD_BUMP_DY; | ||||
| attr_node = NODE_ATTR_BUMP_DY; | attr_node = NODE_ATTR_BUMP_DY; | ||||
| } | } | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| if (from_dupli) { | if (from_dupli) { | ||||
| compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out)); | compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out)); | ||||
| } | } | ||||
| else { | else { | ||||
| if (attribute != "") | if (attribute != "") | ||||
| attr = compiler.attribute(attribute); | attr = compiler.attribute(attribute); | ||||
| else | else | ||||
| attr = compiler.attribute(ATTR_STD_UV); | attr = compiler.attribute(ATTR_STD_UV); | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| } | } | ||||
| void LightPathNode::compile(SVMCompiler &compiler) | void LightPathNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *out; | ShaderOutput *out; | ||||
| out = output("Is Camera Ray"); | out = output("Is Camera Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Is Shadow Ray"); | out = output("Is Shadow Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Is Diffuse Ray"); | out = output("Is Diffuse Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Is Glossy Ray"); | out = output("Is Glossy Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Is Singular Ray"); | out = output("Is Singular Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Is Reflection Ray"); | out = output("Is Reflection Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Is Transmission Ray"); | out = output("Is Transmission Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Is Volume Scatter Ray"); | out = output("Is Volume Scatter Ray"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Ray Length"); | out = output("Ray Length"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Ray Depth"); | out = output("Ray Depth"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Diffuse Depth"); | out = output("Diffuse Depth"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_diffuse, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_diffuse, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Glossy Depth"); | out = output("Glossy Depth"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_glossy, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_glossy, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Transparent Depth"); | out = output("Transparent Depth"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Transmission Depth"); | out = output("Transmission Depth"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transmission, compiler.stack_assign(out)); | compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transmission, compiler.stack_assign(out)); | ||||
| } | } | ||||
| } | } | ||||
| void LightPathNode::compile(OSLCompiler &compiler) | void LightPathNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.add(this, "node_light_path"); | compiler.add(this, "node_light_path"); | ||||
| } | } | ||||
| Show All 19 Lines | |||||
| } | } | ||||
| void LightFalloffNode::compile(SVMCompiler &compiler) | void LightFalloffNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *strength_in = input("Strength"); | ShaderInput *strength_in = input("Strength"); | ||||
| ShaderInput *smooth_in = input("Smooth"); | ShaderInput *smooth_in = input("Smooth"); | ||||
| ShaderOutput *out = output("Quadratic"); | ShaderOutput *out = output("Quadratic"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_FALLOFF, | compiler.add_node(NODE_LIGHT_FALLOFF, | ||||
| NODE_LIGHT_FALLOFF_QUADRATIC, | NODE_LIGHT_FALLOFF_QUADRATIC, | ||||
| compiler.encode_uchar4(compiler.stack_assign(strength_in), | compiler.encode_uchar4(compiler.stack_assign(strength_in), | ||||
| compiler.stack_assign(smooth_in), | compiler.stack_assign(smooth_in), | ||||
| compiler.stack_assign(out))); | compiler.stack_assign(out))); | ||||
| } | } | ||||
| out = output("Linear"); | out = output("Linear"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_FALLOFF, | compiler.add_node(NODE_LIGHT_FALLOFF, | ||||
| NODE_LIGHT_FALLOFF_LINEAR, | NODE_LIGHT_FALLOFF_LINEAR, | ||||
| compiler.encode_uchar4(compiler.stack_assign(strength_in), | compiler.encode_uchar4(compiler.stack_assign(strength_in), | ||||
| compiler.stack_assign(smooth_in), | compiler.stack_assign(smooth_in), | ||||
| compiler.stack_assign(out))); | compiler.stack_assign(out))); | ||||
| } | } | ||||
| out = output("Constant"); | out = output("Constant"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_LIGHT_FALLOFF, | compiler.add_node(NODE_LIGHT_FALLOFF, | ||||
| NODE_LIGHT_FALLOFF_CONSTANT, | NODE_LIGHT_FALLOFF_CONSTANT, | ||||
| compiler.encode_uchar4(compiler.stack_assign(strength_in), | compiler.encode_uchar4(compiler.stack_assign(strength_in), | ||||
| compiler.stack_assign(smooth_in), | compiler.stack_assign(smooth_in), | ||||
| compiler.stack_assign(out))); | compiler.stack_assign(out))); | ||||
| } | } | ||||
| } | } | ||||
| Show All 19 Lines | |||||
| ObjectInfoNode::ObjectInfoNode() : ShaderNode(node_type) | ObjectInfoNode::ObjectInfoNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void ObjectInfoNode::compile(SVMCompiler &compiler) | void ObjectInfoNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *out = output("Location"); | ShaderOutput *out = output("Location"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out)); | compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Color"); | out = output("Color"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_COLOR, compiler.stack_assign(out)); | compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_COLOR, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Object Index"); | out = output("Object Index"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out)); | compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Material Index"); | out = output("Material Index"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, compiler.stack_assign(out)); | compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Random"); | out = output("Random"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, compiler.stack_assign(out)); | compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, compiler.stack_assign(out)); | ||||
| } | } | ||||
| } | } | ||||
| void ObjectInfoNode::compile(OSLCompiler &compiler) | void ObjectInfoNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.add(this, "node_object_info"); | compiler.add(this, "node_object_info"); | ||||
| } | } | ||||
| Show All 20 Lines | |||||
| } | } | ||||
| ParticleInfoNode::ParticleInfoNode() : ShaderNode(node_type) | ParticleInfoNode::ParticleInfoNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (!output("Index")->links.empty()) | if (output("Index")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| if (!output("Random")->links.empty()) | if (output("Random")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| if (!output("Age")->links.empty()) | if (output("Age")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| if (!output("Lifetime")->links.empty()) | if (output("Lifetime")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| if (!output("Location")->links.empty()) | if (output("Location")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| #if 0 /* not yet supported */ | #if 0 /* not yet supported */ | ||||
| if (!output("Rotation")->links.empty()) | if (output("Rotation")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| #endif | #endif | ||||
| if (!output("Size")->links.empty()) | if (output("Size")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| if (!output("Velocity")->links.empty()) | if (output("Velocity")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| if (!output("Angular Velocity")->links.empty()) | if (output("Angular Velocity")->is_linked()) | ||||
| attributes->add(ATTR_STD_PARTICLE); | attributes->add(ATTR_STD_PARTICLE); | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void ParticleInfoNode::compile(SVMCompiler &compiler) | void ParticleInfoNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *out; | ShaderOutput *out; | ||||
| out = output("Index"); | out = output("Index"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Random"); | out = output("Random"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Age"); | out = output("Age"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Lifetime"); | out = output("Lifetime"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Location"); | out = output("Location"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, compiler.stack_assign(out)); | ||||
| } | } | ||||
| /* quaternion data is not yet supported by Cycles */ | /* quaternion data is not yet supported by Cycles */ | ||||
| #if 0 | #if 0 | ||||
| out = output("Rotation"); | out = output("Rotation"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, compiler.stack_assign(out)); | ||||
| } | } | ||||
| #endif | #endif | ||||
| out = output("Size"); | out = output("Size"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Velocity"); | out = output("Velocity"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, compiler.stack_assign(out)); | compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Angular Velocity"); | out = output("Angular Velocity"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node( | compiler.add_node( | ||||
| NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, compiler.stack_assign(out)); | NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, compiler.stack_assign(out)); | ||||
| } | } | ||||
| } | } | ||||
| void ParticleInfoNode::compile(OSLCompiler &compiler) | void ParticleInfoNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.add(this, "node_particle_info"); | compiler.add(this, "node_particle_info"); | ||||
| Show All 18 Lines | |||||
| } | } | ||||
| HairInfoNode::HairInfoNode() : ShaderNode(node_type) | HairInfoNode::HairInfoNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface) { | if (shader->get_has_surface()) { | ||||
| ShaderOutput *intercept_out = output("Intercept"); | ShaderOutput *intercept_out = output("Intercept"); | ||||
| if (!intercept_out->links.empty()) | if (intercept_out->is_linked()) | ||||
| attributes->add(ATTR_STD_CURVE_INTERCEPT); | attributes->add(ATTR_STD_CURVE_INTERCEPT); | ||||
| if (!output("Random")->links.empty()) | if (output("Random")->is_linked()) | ||||
| attributes->add(ATTR_STD_CURVE_RANDOM); | attributes->add(ATTR_STD_CURVE_RANDOM); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void HairInfoNode::compile(SVMCompiler &compiler) | void HairInfoNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *out; | ShaderOutput *out; | ||||
| out = output("Is Strand"); | out = output("Is Strand"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, compiler.stack_assign(out)); | compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Intercept"); | out = output("Intercept"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT); | int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT); | ||||
| compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); | compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); | ||||
| } | } | ||||
| out = output("Thickness"); | out = output("Thickness"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, compiler.stack_assign(out)); | compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, compiler.stack_assign(out)); | ||||
| } | } | ||||
| out = output("Tangent Normal"); | out = output("Tangent Normal"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out)); | compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out)); | ||||
| } | } | ||||
| /*out = output("Fade"); | /*out = output("Fade"); | ||||
| if(!out->links.empty()) { | if(out->is_linked()) { | ||||
| compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out)); | compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out)); | ||||
| }*/ | }*/ | ||||
| out = output("Random"); | out = output("Random"); | ||||
| if (!out->links.empty()) { | if (out->is_linked()) { | ||||
| int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM); | int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM); | ||||
| compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); | compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); | ||||
| } | } | ||||
| } | } | ||||
| void HairInfoNode::compile(OSLCompiler &compiler) | void HairInfoNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.add(this, "node_hair_info"); | compiler.add(this, "node_hair_info"); | ||||
| Show All 17 Lines | |||||
| { | { | ||||
| } | } | ||||
| /* The requested attributes are not updated after node expansion. | /* The requested attributes are not updated after node expansion. | ||||
| * So we explicitly request the required attributes. | * So we explicitly request the required attributes. | ||||
| */ | */ | ||||
| void VolumeInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void VolumeInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_volume) { | if (shader->get_has_volume()) { | ||||
| if (!output("Color")->links.empty()) { | if (output("Color")->is_linked()) { | ||||
| attributes->add(ATTR_STD_VOLUME_COLOR); | attributes->add(ATTR_STD_VOLUME_COLOR); | ||||
| } | } | ||||
| if (!output("Density")->links.empty()) { | if (output("Density")->is_linked()) { | ||||
| attributes->add(ATTR_STD_VOLUME_DENSITY); | attributes->add(ATTR_STD_VOLUME_DENSITY); | ||||
| } | } | ||||
| if (!output("Flame")->links.empty()) { | if (output("Flame")->is_linked()) { | ||||
| attributes->add(ATTR_STD_VOLUME_FLAME); | attributes->add(ATTR_STD_VOLUME_FLAME); | ||||
| } | } | ||||
| if (!output("Temperature")->links.empty()) { | if (output("Temperature")->is_linked()) { | ||||
| attributes->add(ATTR_STD_VOLUME_TEMPERATURE); | attributes->add(ATTR_STD_VOLUME_TEMPERATURE); | ||||
| } | } | ||||
| attributes->add(ATTR_STD_GENERATED_TRANSFORM); | attributes->add(ATTR_STD_GENERATED_TRANSFORM); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void VolumeInfoNode::expand(ShaderGraph *graph) | void VolumeInfoNode::expand(ShaderGraph *graph) | ||||
| { | { | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| if (!color_out->links.empty()) { | if (color_out->is_linked()) { | ||||
| AttributeNode *attr = graph->create_node<AttributeNode>(); | AttributeNode *attr = graph->create_node<AttributeNode>(); | ||||
| attr->set_attribute(ustring("color")); | attr->set_attribute(ustring("color")); | ||||
| graph->add(attr); | graph->add(attr); | ||||
| graph->relink(color_out, attr->output("Color")); | graph->relink(color_out, attr->output("Color")); | ||||
| } | } | ||||
| ShaderOutput *density_out = output("Density"); | ShaderOutput *density_out = output("Density"); | ||||
| if (!density_out->links.empty()) { | if (density_out->is_linked()) { | ||||
| AttributeNode *attr = graph->create_node<AttributeNode>(); | AttributeNode *attr = graph->create_node<AttributeNode>(); | ||||
| attr->set_attribute(ustring("density")); | attr->set_attribute(ustring("density")); | ||||
| graph->add(attr); | graph->add(attr); | ||||
| graph->relink(density_out, attr->output("Fac")); | graph->relink(density_out, attr->output("Fac")); | ||||
| } | } | ||||
| ShaderOutput *flame_out = output("Flame"); | ShaderOutput *flame_out = output("Flame"); | ||||
| if (!flame_out->links.empty()) { | if (flame_out->is_linked()) { | ||||
| AttributeNode *attr = graph->create_node<AttributeNode>(); | AttributeNode *attr = graph->create_node<AttributeNode>(); | ||||
| attr->set_attribute(ustring("flame")); | attr->set_attribute(ustring("flame")); | ||||
| graph->add(attr); | graph->add(attr); | ||||
| graph->relink(flame_out, attr->output("Fac")); | graph->relink(flame_out, attr->output("Fac")); | ||||
| } | } | ||||
| ShaderOutput *temperature_out = output("Temperature"); | ShaderOutput *temperature_out = output("Temperature"); | ||||
| if (!temperature_out->links.empty()) { | if (temperature_out->is_linked()) { | ||||
| AttributeNode *attr = graph->create_node<AttributeNode>(); | AttributeNode *attr = graph->create_node<AttributeNode>(); | ||||
| attr->set_attribute(ustring("temperature")); | attr->set_attribute(ustring("temperature")); | ||||
| graph->add(attr); | graph->add(attr); | ||||
| graph->relink(temperature_out, attr->output("Fac")); | graph->relink(temperature_out, attr->output("Fac")); | ||||
| } | } | ||||
| } | } | ||||
| void VolumeInfoNode::compile(SVMCompiler &) | void VolumeInfoNode::compile(SVMCompiler &) | ||||
| Show All 16 Lines | |||||
| } | } | ||||
| VertexColorNode::VertexColorNode() : ShaderNode(node_type) | VertexColorNode::VertexColorNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void VertexColorNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void VertexColorNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (!(output("Color")->links.empty() && output("Alpha")->links.empty())) { | if (output("Color")->is_linked() || output("Alpha")->is_linked()) { | ||||
| if (layer_name != "") | if (layer_name != "") | ||||
| attributes->add_standard(layer_name); | attributes->add_standard(layer_name); | ||||
| else | else | ||||
| attributes->add(ATTR_STD_VERTEX_COLOR); | attributes->add(ATTR_STD_VERTEX_COLOR); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| folder.make_constant(value); | folder.make_constant(value); | ||||
| } | } | ||||
| void ColorNode::compile(SVMCompiler &compiler) | void ColorNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| if (!color_out->links.empty()) { | if (color_out->is_linked()) { | ||||
| compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out)); | compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out)); | ||||
| compiler.add_node(NODE_VALUE_V, value); | compiler.add_node(NODE_VALUE_V, value); | ||||
| } | } | ||||
| } | } | ||||
| void ColorNode::compile(OSLCompiler &compiler) | void ColorNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| compiler.parameter_color("color_value", value); | compiler.parameter_color("color_value", value); | ||||
| Show All 30 Lines | |||||
| } | } | ||||
| void AddClosureNode::constant_fold(const ConstantFolder &folder) | void AddClosureNode::constant_fold(const ConstantFolder &folder) | ||||
| { | { | ||||
| ShaderInput *closure1_in = input("Closure1"); | ShaderInput *closure1_in = input("Closure1"); | ||||
| ShaderInput *closure2_in = input("Closure2"); | ShaderInput *closure2_in = input("Closure2"); | ||||
| /* remove useless add closures nodes */ | /* remove useless add closures nodes */ | ||||
| if (!closure1_in->link) { | if (!closure1_in->get_link()) { | ||||
| folder.bypass_or_discard(closure2_in); | folder.bypass_or_discard(closure2_in); | ||||
| } | } | ||||
| else if (!closure2_in->link) { | else if (!closure2_in->get_link()) { | ||||
| folder.bypass_or_discard(closure1_in); | folder.bypass_or_discard(closure1_in); | ||||
| } | } | ||||
| } | } | ||||
| /* Mix Closure */ | /* Mix Closure */ | ||||
| NODE_DEFINE(MixClosureNode) | NODE_DEFINE(MixClosureNode) | ||||
| { | { | ||||
| Show All 25 Lines | |||||
| void MixClosureNode::constant_fold(const ConstantFolder &folder) | void MixClosureNode::constant_fold(const ConstantFolder &folder) | ||||
| { | { | ||||
| ShaderInput *fac_in = input("Fac"); | ShaderInput *fac_in = input("Fac"); | ||||
| ShaderInput *closure1_in = input("Closure1"); | ShaderInput *closure1_in = input("Closure1"); | ||||
| ShaderInput *closure2_in = input("Closure2"); | ShaderInput *closure2_in = input("Closure2"); | ||||
| /* remove useless mix closures nodes */ | /* remove useless mix closures nodes */ | ||||
| if (closure1_in->link == closure2_in->link) { | if (closure1_in->get_link() == closure2_in->get_link()) { | ||||
| folder.bypass_or_discard(closure1_in); | folder.bypass_or_discard(closure1_in); | ||||
| } | } | ||||
| /* remove unused mix closure input when factor is 0.0 or 1.0 | /* remove unused mix closure input when factor is 0.0 or 1.0 | ||||
| * check for closure links and make sure factor link is disconnected */ | * check for closure links and make sure factor link is disconnected */ | ||||
| else if (!fac_in->link) { | else if (!fac_in->get_link()) { | ||||
| /* factor 0.0 */ | /* factor 0.0 */ | ||||
| if (fac <= 0.0f) { | if (fac <= 0.0f) { | ||||
| folder.bypass_or_discard(closure1_in); | folder.bypass_or_discard(closure1_in); | ||||
| } | } | ||||
| /* factor 1.0 */ | /* factor 1.0 */ | ||||
| else if (fac >= 1.0f) { | else if (fac >= 1.0f) { | ||||
| folder.bypass_or_discard(closure2_in); | folder.bypass_or_discard(closure2_in); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| } | } | ||||
| void InvertNode::constant_fold(const ConstantFolder &folder) | void InvertNode::constant_fold(const ConstantFolder &folder) | ||||
| { | { | ||||
| ShaderInput *fac_in = input("Fac"); | ShaderInput *fac_in = input("Fac"); | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| if (!fac_in->link) { | if (!fac_in->get_link()) { | ||||
| /* evaluate fully constant node */ | /* evaluate fully constant node */ | ||||
| if (!color_in->link) { | if (!color_in->get_link()) { | ||||
| folder.make_constant(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac)); | folder.make_constant(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac)); | ||||
| } | } | ||||
| /* remove no-op node */ | /* remove no-op node */ | ||||
| else if (fac == 0.0f) { | else if (fac == 0.0f) { | ||||
| folder.bypass(color_in->link); | folder.bypass(color_in->get_link()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void InvertNode::compile(SVMCompiler &compiler) | void InvertNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *fac_in = input("Fac"); | ShaderInput *fac_in = input("Fac"); | ||||
| ShaderInput *color_in = input("Color"); | ShaderInput *color_in = input("Color"); | ||||
| ▲ Show 20 Lines • Show All 552 Lines • ▼ Show 20 Lines | |||||
| void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| ShaderOutput *vector_out = output("Vector"); | ShaderOutput *vector_out = output("Vector"); | ||||
| ShaderOutput *fac_out = output("Fac"); | ShaderOutput *fac_out = output("Fac"); | ||||
| ShaderOutput *alpha_out = output("Alpha"); | ShaderOutput *alpha_out = output("Alpha"); | ||||
| if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty() || | if (color_out->is_linked() || vector_out->is_linked() || fac_out->is_linked() || | ||||
| !alpha_out->links.empty()) { | alpha_out->is_linked()) { | ||||
| attributes->add_standard(attribute); | attributes->add_standard(attribute); | ||||
| } | } | ||||
| if (shader->has_volume) { | if (shader->get_has_volume()) { | ||||
| attributes->add(ATTR_STD_GENERATED_TRANSFORM); | attributes->add(ATTR_STD_GENERATED_TRANSFORM); | ||||
| } | } | ||||
| ShaderNode::attributes(shader, attributes); | ShaderNode::attributes(shader, attributes); | ||||
| } | } | ||||
| void AttributeNode::compile(SVMCompiler &compiler) | void AttributeNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderOutput *color_out = output("Color"); | ShaderOutput *color_out = output("Color"); | ||||
| ShaderOutput *vector_out = output("Vector"); | ShaderOutput *vector_out = output("Vector"); | ||||
| ShaderOutput *fac_out = output("Fac"); | ShaderOutput *fac_out = output("Fac"); | ||||
| ShaderOutput *alpha_out = output("Alpha"); | ShaderOutput *alpha_out = output("Alpha"); | ||||
| ShaderNodeType attr_node = NODE_ATTR; | ShaderNodeType attr_node = NODE_ATTR; | ||||
| int attr = compiler.attribute_standard(attribute); | int attr = compiler.attribute_standard(attribute); | ||||
| if (bump == SHADER_BUMP_DX) | if (bump == SHADER_BUMP_DX) | ||||
| attr_node = NODE_ATTR_BUMP_DX; | attr_node = NODE_ATTR_BUMP_DX; | ||||
| else if (bump == SHADER_BUMP_DY) | else if (bump == SHADER_BUMP_DY) | ||||
| attr_node = NODE_ATTR_BUMP_DY; | attr_node = NODE_ATTR_BUMP_DY; | ||||
| if (!color_out->links.empty() || !vector_out->links.empty()) { | if (color_out->is_linked() || vector_out->is_linked()) { | ||||
| if (!color_out->links.empty()) { | if (color_out->is_linked()) { | ||||
| compiler.add_node( | compiler.add_node( | ||||
| attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_OUTPUT_FLOAT3); | attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_OUTPUT_FLOAT3); | ||||
| } | } | ||||
| if (!vector_out->links.empty()) { | if (vector_out->is_linked()) { | ||||
| compiler.add_node( | compiler.add_node( | ||||
| attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_OUTPUT_FLOAT3); | attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_OUTPUT_FLOAT3); | ||||
| } | } | ||||
| } | } | ||||
| if (!fac_out->links.empty()) { | if (fac_out->is_linked()) { | ||||
| compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_OUTPUT_FLOAT); | compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_OUTPUT_FLOAT); | ||||
| } | } | ||||
| if (!alpha_out->links.empty()) { | if (alpha_out->is_linked()) { | ||||
| compiler.add_node( | compiler.add_node( | ||||
| attr_node, attr, compiler.stack_assign(alpha_out), NODE_ATTR_OUTPUT_FLOAT_ALPHA); | attr_node, attr, compiler.stack_assign(alpha_out), NODE_ATTR_OUTPUT_FLOAT_ALPHA); | ||||
| } | } | ||||
| } | } | ||||
| void AttributeNode::compile(OSLCompiler &compiler) | void AttributeNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| if (bump == SHADER_BUMP_DX) | if (bump == SHADER_BUMP_DX) | ||||
| ▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | |||||
| void LayerWeightNode::compile(SVMCompiler &compiler) | void LayerWeightNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| ShaderInput *normal_in = input("Normal"); | ShaderInput *normal_in = input("Normal"); | ||||
| ShaderInput *blend_in = input("Blend"); | ShaderInput *blend_in = input("Blend"); | ||||
| ShaderOutput *fresnel_out = output("Fresnel"); | ShaderOutput *fresnel_out = output("Fresnel"); | ||||
| ShaderOutput *facing_out = output("Facing"); | ShaderOutput *facing_out = output("Facing"); | ||||
| if (!fresnel_out->links.empty()) { | if (fresnel_out->is_linked()) { | ||||
| compiler.add_node(NODE_LAYER_WEIGHT, | compiler.add_node(NODE_LAYER_WEIGHT, | ||||
| compiler.stack_assign_if_linked(blend_in), | compiler.stack_assign_if_linked(blend_in), | ||||
| __float_as_int(blend), | __float_as_int(blend), | ||||
| compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL, | compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL, | ||||
| compiler.stack_assign_if_linked(normal_in), | compiler.stack_assign_if_linked(normal_in), | ||||
| compiler.stack_assign(fresnel_out))); | compiler.stack_assign(fresnel_out))); | ||||
| } | } | ||||
| if (!facing_out->links.empty()) { | if (facing_out->is_linked()) { | ||||
| compiler.add_node(NODE_LAYER_WEIGHT, | compiler.add_node(NODE_LAYER_WEIGHT, | ||||
| compiler.stack_assign_if_linked(blend_in), | compiler.stack_assign_if_linked(blend_in), | ||||
| __float_as_int(blend), | __float_as_int(blend), | ||||
| compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING, | compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING, | ||||
| compiler.stack_assign_if_linked(normal_in), | compiler.stack_assign_if_linked(normal_in), | ||||
| compiler.stack_assign(facing_out))); | compiler.stack_assign(facing_out))); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | OutputNode::OutputNode() : ShaderNode(node_type) | ||||
| special_type = SHADER_SPECIAL_TYPE_OUTPUT; | special_type = SHADER_SPECIAL_TYPE_OUTPUT; | ||||
| } | } | ||||
| void OutputNode::compile(SVMCompiler &compiler) | void OutputNode::compile(SVMCompiler &compiler) | ||||
| { | { | ||||
| if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT) { | if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT) { | ||||
| ShaderInput *displacement_in = input("Displacement"); | ShaderInput *displacement_in = input("Displacement"); | ||||
| if (displacement_in->link) { | if (displacement_in->get_link()) { | ||||
| compiler.add_node(NODE_SET_DISPLACEMENT, compiler.stack_assign(displacement_in)); | compiler.add_node(NODE_SET_DISPLACEMENT, compiler.stack_assign(displacement_in)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void OutputNode::compile(OSLCompiler &compiler) | void OutputNode::compile(OSLCompiler &compiler) | ||||
| { | { | ||||
| if (compiler.output_type() == SHADER_TYPE_SURFACE) | if (compiler.output_type() == SHADER_TYPE_SURFACE) | ||||
| Show All 33 Lines | |||||
| MapRangeNode::MapRangeNode() : ShaderNode(node_type) | MapRangeNode::MapRangeNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void MapRangeNode::expand(ShaderGraph *graph) | void MapRangeNode::expand(ShaderGraph *graph) | ||||
| { | { | ||||
| if (clamp) { | if (clamp) { | ||||
| ShaderOutput *result_out = output("Result"); | ShaderOutput *result_out = output("Result"); | ||||
| if (!result_out->links.empty()) { | if (result_out->is_linked()) { | ||||
| ClampNode *clamp_node = graph->create_node<ClampNode>(); | ClampNode *clamp_node = graph->create_node<ClampNode>(); | ||||
| clamp_node->set_clamp_type(NODE_CLAMP_RANGE); | clamp_node->set_clamp_type(NODE_CLAMP_RANGE); | ||||
| graph->add(clamp_node); | graph->add(clamp_node); | ||||
| graph->relink(result_out, clamp_node->output("Result")); | graph->relink(result_out, clamp_node->output("Result")); | ||||
| graph->connect(result_out, clamp_node->input("Value")); | graph->connect(result_out, clamp_node->input("Value")); | ||||
| if (input("To Min")->link) { | if (input("To Min")->get_link()) { | ||||
| graph->connect(input("To Min")->link, clamp_node->input("Min")); | graph->connect(input("To Min")->get_link(), clamp_node->input("Min")); | ||||
| } | } | ||||
| else { | else { | ||||
| clamp_node->set_min(to_min); | clamp_node->set_min(to_min); | ||||
| } | } | ||||
| if (input("To Max")->link) { | if (input("To Max")->get_link()) { | ||||
| graph->connect(input("To Max")->link, clamp_node->input("Max")); | graph->connect(input("To Max")->get_link(), clamp_node->input("Max")); | ||||
| } | } | ||||
| else { | else { | ||||
| clamp_node->set_max(to_max); | clamp_node->set_max(to_max); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | |||||
| OutputAOVNode::OutputAOVNode() : ShaderNode(node_type) | OutputAOVNode::OutputAOVNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| special_type = SHADER_SPECIAL_TYPE_OUTPUT_AOV; | special_type = SHADER_SPECIAL_TYPE_OUTPUT_AOV; | ||||
| slot = -1; | slot = -1; | ||||
| } | } | ||||
| void OutputAOVNode::simplify_settings(Scene *scene) | void OutputAOVNode::simplify_settings(Scene *scene) | ||||
| { | { | ||||
| slot = scene->film->get_aov_offset(scene, name.string(), is_color); | slot = scene->get_film()->get_aov_offset(scene, name.string(), is_color); | ||||
| if (slot == -1) { | if (slot == -1) { | ||||
| slot = scene->film->get_aov_offset(scene, name.string(), is_color); | slot = scene->get_film()->get_aov_offset(scene, name.string(), is_color); | ||||
| } | } | ||||
| if (slot == -1 || is_color) { | if (slot == -1 || is_color) { | ||||
| input("Value")->disconnect(); | input("Value")->disconnect(); | ||||
| } | } | ||||
| if (slot == -1 || !is_color) { | if (slot == -1 || !is_color) { | ||||
| input("Color")->disconnect(); | input("Color")->disconnect(); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | |||||
| MathNode::MathNode() : ShaderNode(node_type) | MathNode::MathNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void MathNode::expand(ShaderGraph *graph) | void MathNode::expand(ShaderGraph *graph) | ||||
| { | { | ||||
| if (use_clamp) { | if (use_clamp) { | ||||
| ShaderOutput *result_out = output("Value"); | ShaderOutput *result_out = output("Value"); | ||||
| if (!result_out->links.empty()) { | if (result_out->is_linked()) { | ||||
| ClampNode *clamp_node = graph->create_node<ClampNode>(); | ClampNode *clamp_node = graph->create_node<ClampNode>(); | ||||
| clamp_node->set_clamp_type(NODE_CLAMP_MINMAX); | clamp_node->set_clamp_type(NODE_CLAMP_MINMAX); | ||||
| clamp_node->set_min(0.0f); | clamp_node->set_min(0.0f); | ||||
| clamp_node->set_max(1.0f); | clamp_node->set_max(1.0f); | ||||
| graph->add(clamp_node); | graph->add(clamp_node); | ||||
| graph->relink(result_out, clamp_node->output("Result")); | graph->relink(result_out, clamp_node->output("Result")); | ||||
| graph->connect(result_out, clamp_node->input("Value")); | graph->connect(result_out, clamp_node->input("Value")); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 311 Lines • ▼ Show 20 Lines | void BumpNode::compile(OSLCompiler &compiler) | ||||
| compiler.add(this, "node_bump"); | compiler.add(this, "node_bump"); | ||||
| } | } | ||||
| void BumpNode::constant_fold(const ConstantFolder &folder) | void BumpNode::constant_fold(const ConstantFolder &folder) | ||||
| { | { | ||||
| ShaderInput *height_in = input("Height"); | ShaderInput *height_in = input("Height"); | ||||
| ShaderInput *normal_in = input("Normal"); | ShaderInput *normal_in = input("Normal"); | ||||
| if (height_in->link == NULL) { | if (height_in->get_link() == NULL) { | ||||
| if (normal_in->link == NULL) { | if (normal_in->get_link() == NULL) { | ||||
| GeometryNode *geom = folder.graph->create_node<GeometryNode>(); | GeometryNode *geom = folder.graph->create_node<GeometryNode>(); | ||||
| folder.graph->add(geom); | folder.graph->add(geom); | ||||
| folder.bypass(geom->output("Normal")); | folder.bypass(geom->output("Normal")); | ||||
| } | } | ||||
| else { | else { | ||||
| folder.bypass(normal_in->link); | folder.bypass(normal_in->get_link()); | ||||
| } | } | ||||
| } | } | ||||
| /* TODO(sergey): Ignore bump with zero strength. */ | /* TODO(sergey): Ignore bump with zero strength. */ | ||||
| } | } | ||||
| /* Curve node */ | /* Curve node */ | ||||
| Show All 16 Lines | if (folder.all_inputs_constant()) { | ||||
| result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, true, curves.size()).x; | result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, true, curves.size()).x; | ||||
| result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, true, curves.size()).y; | result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, true, curves.size()).y; | ||||
| result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, true, curves.size()).z; | result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, true, curves.size()).z; | ||||
| folder.make_constant(interp(value, result, fac)); | folder.make_constant(interp(value, result, fac)); | ||||
| } | } | ||||
| /* remove no-op node */ | /* remove no-op node */ | ||||
| else if (!fac_in->link && fac == 0.0f) { | else if (!fac_in->get_link() && fac == 0.0f) { | ||||
| /* link is not null because otherwise all inputs are constant */ | /* link is not null because otherwise all inputs are constant */ | ||||
| folder.bypass(value_in->link); | folder.bypass(value_in->get_link()); | ||||
| } | } | ||||
| } | } | ||||
| void CurvesNode::compile(SVMCompiler &compiler, | void CurvesNode::compile(SVMCompiler &compiler, | ||||
| int type, | int type, | ||||
| ShaderInput *value_in, | ShaderInput *value_in, | ||||
| ShaderOutput *value_out) | ShaderOutput *value_out) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 260 Lines • ▼ Show 20 Lines | else { | ||||
| node->set_owner(from->owner); | node->set_owner(from->owner); | ||||
| return node; | return node; | ||||
| } | } | ||||
| } | } | ||||
| char *OSLNode::input_default_value() | char *OSLNode::input_default_value() | ||||
| { | { | ||||
| /* pointer to default value storage, which is the same as our actual value */ | /* pointer to default value storage, which is the same as our actual value */ | ||||
| size_t num_inputs = type->inputs.size(); | size_t num_inputs = type->get_inputs().size(); | ||||
| size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs; | size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs; | ||||
| return (char *)this + align_up(sizeof(OSLNode), 16) + inputs_size; | return (char *)this + align_up(sizeof(OSLNode), 16) + inputs_size; | ||||
| } | } | ||||
| void OSLNode::add_input(ustring name, SocketType::Type socket_type) | void OSLNode::add_input(ustring name, SocketType::Type socket_type) | ||||
| { | { | ||||
| char *memory = input_default_value(); | char *memory = input_default_value(); | ||||
| size_t offset = memory - (char *)this; | size_t offset = memory - (char *)this; | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| NormalMapNode::NormalMapNode() : ShaderNode(node_type) | NormalMapNode::NormalMapNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) { | if (shader->get_has_surface() && space == NODE_NORMAL_MAP_TANGENT) { | ||||
| if (attribute.empty()) { | if (attribute.empty()) { | ||||
| attributes->add(ATTR_STD_UV_TANGENT); | attributes->add(ATTR_STD_UV_TANGENT); | ||||
| attributes->add(ATTR_STD_UV_TANGENT_SIGN); | attributes->add(ATTR_STD_UV_TANGENT_SIGN); | ||||
| } | } | ||||
| else { | else { | ||||
| attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); | attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); | ||||
| attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str())); | attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str())); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| TangentNode::TangentNode() : ShaderNode(node_type) | TangentNode::TangentNode() : ShaderNode(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface) { | if (shader->get_has_surface()) { | ||||
| if (direction_type == NODE_TANGENT_UVMAP) { | if (direction_type == NODE_TANGENT_UVMAP) { | ||||
| if (attribute.empty()) | if (attribute.empty()) | ||||
| attributes->add(ATTR_STD_UV_TANGENT); | attributes->add(ATTR_STD_UV_TANGENT); | ||||
| else | else | ||||
| attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); | attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); | ||||
| } | } | ||||
| else | else | ||||
| attributes->add(ATTR_STD_GENERATED); | attributes->add(ATTR_STD_GENERATED); | ||||
| ▲ Show 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | if (folder.all_inputs_constant()) { | ||||
| if ((vector == make_float3(0.0f, 0.0f, 0.0f) && midlevel == 0.0f) || (scale == 0.0f)) { | if ((vector == make_float3(0.0f, 0.0f, 0.0f) && midlevel == 0.0f) || (scale == 0.0f)) { | ||||
| folder.make_zero(); | folder.make_zero(); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void VectorDisplacementNode::attributes(Shader *shader, AttributeRequestSet *attributes) | void VectorDisplacementNode::attributes(Shader *shader, AttributeRequestSet *attributes) | ||||
| { | { | ||||
| if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) { | if (shader->get_has_surface() && space == NODE_NORMAL_MAP_TANGENT) { | ||||
| if (attribute.empty()) { | if (attribute.empty()) { | ||||
| attributes->add(ATTR_STD_UV_TANGENT); | attributes->add(ATTR_STD_UV_TANGENT); | ||||
| attributes->add(ATTR_STD_UV_TANGENT_SIGN); | attributes->add(ATTR_STD_UV_TANGENT_SIGN); | ||||
| } | } | ||||
| else { | else { | ||||
| attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); | attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); | ||||
| attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str())); | attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str())); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines | |||||