Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/nodes.cpp
| Show First 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | void TextureMapping::compile(OSLCompiler &compiler) | ||||
| if(!skip()) { | if(!skip()) { | ||||
| Transform tfm = transform_transpose(compute_transform()); | Transform tfm = transform_transpose(compute_transform()); | ||||
| compiler.parameter("mapping", tfm); | compiler.parameter("mapping", tfm); | ||||
| compiler.parameter("use_mapping", 1); | compiler.parameter("use_mapping", 1); | ||||
| } | } | ||||
| } | } | ||||
| /* UDIM Texture */ | |||||
| NODE_DEFINE(UDIMTextureNode) | |||||
| { | |||||
| NodeType* type = NodeType::add("udim_texture", create, NodeType::SHADER); | |||||
| SOCKET_STRING(filename, "Filename", ustring("")); | |||||
| static NodeEnum color_space_enum; | |||||
| color_space_enum.insert("none", NODE_COLOR_SPACE_NONE); | |||||
| color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR); | |||||
| SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR); | |||||
| SOCKET_BOOLEAN(use_alpha, "Use Alpha", true); | |||||
| static NodeEnum interpolation_enum; | |||||
| interpolation_enum.insert("closest", INTERPOLATION_CLOSEST); | |||||
| interpolation_enum.insert("linear", INTERPOLATION_LINEAR); | |||||
| interpolation_enum.insert("cubic", INTERPOLATION_CUBIC); | |||||
| interpolation_enum.insert("smart", INTERPOLATION_SMART); | |||||
| SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR); | |||||
| static NodeEnum extension_enum; | |||||
| extension_enum.insert("periodic", EXTENSION_REPEAT); | |||||
| extension_enum.insert("clamp", EXTENSION_EXTEND); | |||||
| extension_enum.insert("black", EXTENSION_CLIP); | |||||
| SOCKET_ENUM(extension, "Extension", extension_enum, EXTENSION_REPEAT); | |||||
| SOCKET_IN_STRING(uv_map, "UV Map", ustring("")); | |||||
| SOCKET_IN_INT(start_tile, "Start Tile", 1001); | |||||
| SOCKET_IN_INT(columns, "Columns", 10); | |||||
| SOCKET_OUT_COLOR(color, "Color"); | |||||
| SOCKET_OUT_FLOAT(alpha, "Alpha"); | |||||
| return type; | |||||
| } | |||||
| UDIMTextureNode::UDIMTextureNode() | |||||
| : ShaderNode(node_type) | |||||
| { | |||||
| image_manager = NULL; | |||||
| special_type = SHADER_SPECIAL_TYPE_UDIM_SLOT; | |||||
| } | |||||
| UDIMTextureNode::~UDIMTextureNode() | |||||
| { | |||||
| if(image_manager) { | |||||
| foreach(ImageTile &tile, tiles) { | |||||
| if(tile.used) { | |||||
| image_manager->remove_image(tile.filename.string(), | |||||
| NULL, | |||||
| interpolation, | |||||
| extension, | |||||
| use_alpha); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ShaderNode *UDIMTextureNode::clone() const | |||||
| { | |||||
| UDIMTextureNode *node = new UDIMTextureNode(*this); | |||||
| node->image_manager = NULL; | |||||
| node->tiles.clear(); | |||||
| return node; | |||||
| } | |||||
| void UDIMTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) | |||||
| { | |||||
| if(shader->has_surface) { | |||||
| if(!output("Color")->links.empty() || !output("Alpha")->links.empty()) { | |||||
| if(uv_map != "") | |||||
| attributes->add(uv_map); | |||||
| else | |||||
| attributes->add(ATTR_STD_UV); | |||||
| } | |||||
| } | |||||
| ShaderNode::attributes(shader, attributes); | |||||
| } | |||||
| int UDIMTextureNode::ImageTile::get_encoding(NodeImageColorSpace color_space) { | |||||
| if(!used) { | |||||
| return -1; | |||||
| } | |||||
| int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1; | |||||
| return (slot & ~(1 << 31)) | (srgb? (1 << 31) : 0); | |||||
| } | |||||
| void UDIMTextureNode::compile(SVMCompiler& compiler) | |||||
| { | |||||
| ShaderOutput *color_out = output("Color"); | |||||
| ShaderOutput *alpha_out = output("Alpha"); | |||||
| int attr; | |||||
| if(uv_map != "") | |||||
| attr = compiler.attribute(uv_map); | |||||
| else | |||||
| attr = compiler.attribute(ATTR_STD_UV); | |||||
| image_manager = compiler.image_manager; | |||||
| if(tiles.size() == 0) { | |||||
| string file = filename.string(), prefix, postfix; | |||||
| size_t split = file.find(string_printf("%d", start_tile)); | |||||
| if(split != string::npos) { | |||||
| prefix = file.substr(0, split); | |||||
| postfix = file.substr(split+4); | |||||
| } | |||||
| else { | |||||
| for(int i = 0; i+3 < file.length(); i++) { | |||||
| if(isdigit(file[i ]) && isdigit(file[i+1]) && | |||||
| isdigit(file[i+2]) && isdigit(file[i+3])) { | |||||
| prefix = file.substr(0, i); | |||||
| postfix = file.substr(i+4); | |||||
| } | |||||
| } | |||||
| } | |||||
| vector<int> used_tiles(columns); | |||||
| compiler.current_shader->get_uv_tiles(compiler.scene, uv_map, used_tiles, columns); | |||||
| for(int i = 0; i < used_tiles.size(); i++) { | |||||
| ImageTile tile; | |||||
| if(used_tiles[i] == 0) { | |||||
| tile.used = false; | |||||
| } | |||||
| else { | |||||
| tile.used = true; | |||||
| string tile_file = prefix + string_printf("%04d", start_tile + i) + postfix; | |||||
| tile.slot = image_manager->add_image(tile_file, | |||||
| NULL, | |||||
| false, | |||||
| 0, | |||||
| tile.is_float, | |||||
| tile.is_linear, | |||||
| interpolation, | |||||
| extension, | |||||
| use_alpha); | |||||
| tile.filename = ustring(tile_file); | |||||
| } | |||||
| tiles.push_back(tile); | |||||
| } | |||||
| /* Fill tiles with invalid tiles until the rectangle is complete. */ | |||||
| int rows = (tiles.size() + columns - 1)/columns; | |||||
| for(int i = tiles.size(); i < columns*rows; i++) { | |||||
| ImageTile tile; | |||||
| tile.used = false; | |||||
| tiles.push_back(tile); | |||||
| } | |||||
| } | |||||
| compiler.add_node(NODE_TEX_UDIM, | |||||
| compiler.encode_uchar4( | |||||
| compiler.stack_assign_if_linked(color_out), | |||||
| compiler.stack_assign_if_linked(alpha_out), | |||||
| columns, | |||||
| tiles.size()/columns), | |||||
| attr, | |||||
| align_up(tiles.size(), 4)/4); | |||||
| /* Encode all tiles into an integer, and ensure that they're a multiple | |||||
| * of 4 since SVM nodes are int4. */ | |||||
| vector<int> encoded(align_up(tiles.size(), 4)); | |||||
| for(int i = 0; i < tiles.size(); i++) { | |||||
| if(tiles[i].used && tiles[i].slot) { | |||||
| int srgb = (tiles[i].is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1; | |||||
| encoded[i] = (tiles[i].slot & ~(1 << 31)) | (srgb? (1 << 31) : 0); | |||||
| } | |||||
| else { | |||||
| encoded[i] = -1; | |||||
| } | |||||
| } | |||||
| for(int i = tiles.size(); i < encoded.size(); i++) { | |||||
| encoded[i] = -1; | |||||
| } | |||||
| for(int i = 0; i < encoded.size(); i += 4) { | |||||
| compiler.add_node(encoded[i], encoded[i+1], encoded[i+2], encoded[i+3]); | |||||
| } | |||||
| } | |||||
| void UDIMTextureNode::compile(OSLCompiler& compiler) | |||||
| { | |||||
| /* TODO */ | |||||
| (void)compiler; | |||||
| } | |||||
| /* Image Texture */ | /* Image Texture */ | ||||
| NODE_DEFINE(ImageTextureNode) | NODE_DEFINE(ImageTextureNode) | ||||
| { | { | ||||
| NodeType* type = NodeType::add("image_texture", create, NodeType::SHADER); | NodeType* type = NodeType::add("image_texture", create, NodeType::SHADER); | ||||
| TEXTURE_MAPPING_DEFINE(ImageTextureNode); | TEXTURE_MAPPING_DEFINE(ImageTextureNode); | ||||
| ▲ Show 20 Lines • Show All 5,233 Lines • Show Last 20 Lines | |||||