Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender/blender_shader.cpp')
-rw-r--r--intern/cycles/blender/blender_shader.cpp171
1 files changed, 156 insertions, 15 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index b6d5cc623bb..63cf719d010 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -20,6 +20,7 @@
#include "graph.h"
#include "light.h"
#include "nodes.h"
+#include "osl.h"
#include "scene.h"
#include "shader.h"
@@ -43,6 +44,7 @@ void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default
for(size_t i = 0; i < scene->shaders.size(); i++) {
if(scene->shaders[i] == shader) {
used_shaders.push_back(i);
+ scene->shaders[i]->tag_used(scene);
break;
}
}
@@ -80,22 +82,25 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
switch (b_type) {
case BL::NodeSocket::type_VALUE:
return SHADER_SOCKET_FLOAT;
+ case BL::NodeSocket::type_INT:
+ return SHADER_SOCKET_INT;
case BL::NodeSocket::type_VECTOR:
return SHADER_SOCKET_VECTOR;
case BL::NodeSocket::type_RGBA:
return SHADER_SOCKET_COLOR;
case BL::NodeSocket::type_SHADER:
return SHADER_SOCKET_CLOSURE;
+ case BL::NodeSocket::type_STRING:
+ return SHADER_SOCKET_STRING;
case BL::NodeSocket::type_BOOLEAN:
case BL::NodeSocket::type_MESH:
- case BL::NodeSocket::type_INT:
default:
return SHADER_SOCKET_FLOAT;
}
}
-static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
+static void set_default_value(ShaderInput *input, BL::NodeSocket sock, BL::BlendData b_data, BL::ID b_id)
{
/* copy values for non linked inputs */
switch(input->type) {
@@ -104,6 +109,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
input->set(value_sock.default_value());
break;
}
+ case SHADER_SOCKET_INT: {
+ BL::NodeSocketIntNone value_sock(sock);
+ input->set((float)value_sock.default_value());
+ break;
+ }
case SHADER_SOCKET_COLOR: {
BL::NodeSocketRGBA rgba_sock(sock);
input->set(get_float3(rgba_sock.default_value()));
@@ -116,6 +126,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
input->set(get_float3(vec_sock.default_value()));
break;
}
+ case SHADER_SOCKET_STRING: {
+ BL::NodeSocketStringNone string_sock(sock);
+ input->set((ustring)blender_absolute_path(b_data, b_id, string_sock.default_value()));
+ break;
+ }
case SHADER_SOCKET_CLOSURE:
break;
}
@@ -152,7 +167,7 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map
mapping->max = get_float3(b_mapping.max());
}
-static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNode b_node)
+static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::ShaderNode b_node)
{
ShaderNode *node = NULL;
@@ -165,6 +180,7 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
case BL::ShaderNode::type_OUTPUT: break;
case BL::ShaderNode::type_SQUEEZE: break;
case BL::ShaderNode::type_TEXTURE: break;
+ case BL::ShaderNode::type_FRAME: break;
/* handled outside this function */
case BL::ShaderNode::type_GROUP: break;
/* existing blender nodes */
@@ -315,6 +331,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = new HoldoutNode();
break;
}
+ case BL::ShaderNode::type_BSDF_ANISOTROPIC: {
+ node = new WardBsdfNode();
+ break;
+ }
case BL::ShaderNode::type_BSDF_DIFFUSE: {
node = new DiffuseBsdfNode();
break;
@@ -354,6 +374,23 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = glass;
break;
}
+ case BL::ShaderNode::type_BSDF_REFRACTION: {
+ BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
+ RefractionBsdfNode *refraction = new RefractionBsdfNode();
+ switch(b_refraction_node.distribution()) {
+ case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
+ refraction->distribution = ustring("Sharp");
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
+ refraction->distribution = ustring("Beckmann");
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_GGX:
+ refraction->distribution = ustring("GGX");
+ break;
+ }
+ node = refraction;
+ break;
+ }
case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
node = new TranslucentBsdfNode();
break;
@@ -370,6 +407,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = new EmissionNode();
break;
}
+ case BL::ShaderNode::type_AMBIENT_OCCLUSION: {
+ node = new AmbientOcclusionNode();
+ break;
+ }
case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
node = new IsotropicVolumeNode();
break;
@@ -398,6 +439,62 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = new ParticleInfoNode();
break;
}
+ case BL::ShaderNode::type_BUMP: {
+ node = new BumpNode();
+ break;
+ }
+ case BL::ShaderNode::type_SCRIPT: {
+#ifdef WITH_OSL
+ if(scene->params.shadingsystem != SceneParams::OSL)
+ break;
+
+ /* create script node */
+ BL::ShaderNodeScript b_script_node(b_node);
+ OSLScriptNode *script_node = new OSLScriptNode();
+
+ /* Generate inputs/outputs from node sockets
+ *
+ * Note: the node sockets are generated from OSL parameters,
+ * so the names match those of the corresponding parameters exactly.
+ *
+ * Note 2: ShaderInput/ShaderOutput store shallow string copies only!
+ * Socket names must be stored in the extra lists instead. */
+ BL::Node::inputs_iterator b_input;
+
+ for (b_script_node.inputs.begin(b_input); b_input != b_script_node.inputs.end(); ++b_input) {
+ script_node->input_names.push_back(ustring(b_input->name()));
+ ShaderInput *input = script_node->add_input(script_node->input_names.back().c_str(), convert_socket_type(b_input->type()));
+ set_default_value(input, *b_input, b_data, b_ntree);
+ }
+
+ BL::Node::outputs_iterator b_output;
+
+ for (b_script_node.outputs.begin(b_output); b_output != b_script_node.outputs.end(); ++b_output) {
+ script_node->output_names.push_back(ustring(b_output->name()));
+ script_node->add_output(script_node->output_names.back().c_str(), convert_socket_type(b_output->type()));
+ }
+
+ /* load bytecode or filepath */
+ OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager;
+ string bytecode_hash = b_script_node.bytecode_hash();
+
+ if(!bytecode_hash.empty()) {
+ /* loaded bytecode if not already done */
+ if(!manager->shader_test_loaded(bytecode_hash))
+ manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode());
+
+ script_node->bytecode_hash = bytecode_hash;
+ }
+ else {
+ /* set filepath */
+ script_node->filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath());
+ }
+
+ node = script_node;
+#endif
+
+ break;
+ }
case BL::ShaderNode::type_TEX_IMAGE: {
BL::ShaderNodeTexImage b_image_node(b_node);
BL::Image b_image(b_image_node.image());
@@ -505,6 +602,23 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = sky;
break;
}
+ case BL::ShaderNode::type_NORMAL_MAP: {
+ BL::ShaderNodeNormalMap b_normal_map_node(b_node);
+ NormalMapNode *nmap = new NormalMapNode();
+ nmap->space = NormalMapNode::space_enum[(int)b_normal_map_node.space()];
+ nmap->attribute = b_normal_map_node.uv_map();
+ node = nmap;
+ break;
+ }
+ case BL::ShaderNode::type_TANGENT: {
+ BL::ShaderNodeTangent b_tangent_node(b_node);
+ TangentNode *tangent = new TangentNode();
+ tangent->direction_type = TangentNode::direction_type_enum[(int)b_tangent_node.direction_type()];
+ tangent->axis = TangentNode::axis_enum[(int)b_tangent_node.axis()];
+ tangent->attribute = b_tangent_node.uv_map();
+ node = tangent;
+ break;
+ }
}
if(node && node != graph->output())
@@ -561,7 +675,7 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL
return SocketPair(node_map[b_node.ptr.data], name);
}
-static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
+static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
{
/* add nodes */
BL::ShaderNodeTree::nodes_iterator b_node;
@@ -569,7 +683,34 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
PtrSockMap proxy_map;
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
- if(b_node->is_a(&RNA_NodeGroup)) {
+ if(b_node->mute()) {
+ BL::Node::inputs_iterator b_input;
+ BL::Node::outputs_iterator b_output;
+ bool found_match = false;
+
+ /* this is slightly different than blender logic, we just connect a
+ * single pair for of input/output, but works ok for the node we have */
+ for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ if(b_input->is_linked()) {
+ for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ if(b_output->is_linked() && b_input->type() == b_output->type()) {
+ ProxyNode *proxy = new ProxyNode(convert_socket_type(b_input->type()), convert_socket_type(b_output->type()));
+ graph->add(proxy);
+
+ proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
+ proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
+ found_match = true;
+
+ break;
+ }
+ }
+ }
+
+ if(found_match)
+ break;
+ }
+ }
+ else if(b_node->is_a(&RNA_NodeGroup)) {
/* add proxy converter nodes for inputs and outputs */
BL::NodeGroup b_gnode(*b_node);
BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
@@ -592,7 +733,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
/* default input values of the group node */
- set_default_value(proxy->inputs[0], *b_input);
+ set_default_value(proxy->inputs[0], *b_input, b_data, b_group_ntree);
}
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
@@ -606,13 +747,13 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
/* default input values of internal, unlinked group outputs */
- set_default_value(proxy->inputs[0], b_output->group_socket());
+ set_default_value(proxy->inputs[0], b_output->group_socket(), b_data, b_group_ntree);
}
- add_nodes(b_data, b_scene, graph, b_group_ntree, group_sockmap);
+ add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_sockmap);
}
else {
- ShaderNode *node = add_node(b_data, b_scene, graph, BL::ShaderNode(*b_node));
+ ShaderNode *node = add_node(scene, b_data, b_scene, graph, b_ntree, BL::ShaderNode(*b_node));
if(node) {
BL::Node::inputs_iterator b_input;
@@ -626,7 +767,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
assert(input);
/* copy values for non linked inputs */
- set_default_value(input, *b_input);
+ set_default_value(input, *b_input, b_data, b_ntree);
}
}
}
@@ -649,7 +790,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
/* from sock */
if(b_from_node) {
- if (b_from_node.is_a(&RNA_NodeGroup))
+ if (b_from_node.mute() || b_from_node.is_a(&RNA_NodeGroup))
from_pair = proxy_map[b_from_sock.ptr.data];
else
from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
@@ -659,7 +800,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
/* to sock */
if(b_to_node) {
- if (b_to_node.is_a(&RNA_NodeGroup))
+ if (b_to_node.mute() || b_to_node.is_a(&RNA_NodeGroup))
to_pair = proxy_map[b_to_sock.ptr.data];
else
to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
@@ -702,7 +843,7 @@ void BlenderSync::sync_materials()
PtrSockMap sock_to_node;
BL::ShaderNodeTree b_ntree(b_mat->node_tree());
- add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
}
else {
ShaderNode *closure, *out;
@@ -743,7 +884,7 @@ void BlenderSync::sync_world()
PtrSockMap sock_to_node;
BL::ShaderNodeTree b_ntree(b_world.node_tree());
- add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
}
else if(b_world) {
ShaderNode *closure, *out;
@@ -802,7 +943,7 @@ void BlenderSync::sync_lamps()
PtrSockMap sock_to_node;
BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
- add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
}
else {
ShaderNode *closure, *out;