Integer socket support in Cycles. Int values are already supported natively in OSL...
authorLukas Toenne <lukas.toenne@googlemail.com>
Sat, 20 Oct 2012 13:11:45 +0000 (13:11 +0000)
committerLukas Toenne <lukas.toenne@googlemail.com>
Sat, 20 Oct 2012 13:11:45 +0000 (13:11 +0000)
16 files changed:
intern/cycles/app/cycles_xml.cpp
intern/cycles/blender/blender_shader.cpp
intern/cycles/kernel/osl/nodes/CMakeLists.txt
intern/cycles/kernel/osl/nodes/node_convert_from_color.osl
intern/cycles/kernel/osl/nodes/node_convert_from_float.osl
intern/cycles/kernel/osl/nodes/node_convert_from_int.osl [new file with mode: 0644]
intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl
intern/cycles/kernel/osl/nodes/node_convert_from_point.osl
intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl
intern/cycles/kernel/svm/svm.h
intern/cycles/kernel/svm/svm_convert.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/graph.h
intern/cycles/render/nodes.cpp
intern/cycles/render/osl.cpp
intern/cycles/render/svm.cpp

index 87a238e508cd2f2a2000b17b745340fe26110e75..5de9d71b8cc06fe6f2b4a7c5c0aa26e89f2191b1 100644 (file)
@@ -591,6 +591,7 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
                                        if(string_iequals(in->name, attr.name())) {
                                                switch(in->type) {
                                                        case SHADER_SOCKET_FLOAT:
+                                                       case SHADER_SOCKET_INT:
                                                                xml_read_float(&in->value.x, node, attr.name());
                                                                break;
                                                        case SHADER_SOCKET_COLOR:
index 98ac8692f3611e3aa93f717f119a24f7023e299a..db34a9fe9aa86955fa0ac3b1b7a951d83bc719c9 100644 (file)
@@ -80,6 +80,8 @@ 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:
@@ -89,7 +91,6 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
        
        case BL::NodeSocket::type_BOOLEAN:
        case BL::NodeSocket::type_MESH:
-       case BL::NodeSocket::type_INT:
        default:
                return SHADER_SOCKET_FLOAT;
        }
@@ -104,6 +105,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()));
index faf7941ee5e9244a8a16fa1bae015c843821aa3d..2c459fd714bab6f851bb336727358751b9bd3507 100644 (file)
@@ -12,6 +12,7 @@ set(SRC_OSL
        node_combine_rgb.osl
        node_convert_from_color.osl
        node_convert_from_float.osl
+       node_convert_from_int.osl
        node_convert_from_normal.osl
        node_convert_from_point.osl
        node_convert_from_vector.osl
index c55b0f811ffdddb871590fbbf0d4a36f203987b9..2884c772414418edb0eb96643250d45c29448879 100644 (file)
 shader node_convert_from_color(
        color Color = color(0.0, 0.0, 0.0),
        output float Val = 0.0,
+       output int ValInt = 0,
        output vector Vector = vector(0.0, 0.0, 0.0),
        output point Point = point(0.0, 0.0, 0.0),
        output normal Normal = normal(0.0, 0.0, 0.0))
 {
        Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722;
+       ValInt = (int)(Color[0]*0.2126 + Color[1]*0.7152 + Color[2]*0.0722);
        Vector = vector(Color[0], Color[1], Color[2]);
        Point = point(Color[0], Color[1], Color[2]);
        Normal = normal(Color[0], Color[1], Color[2]);
index 00e78f3bab400252265c1d7b3a960d8e105e6bf4..4466fbae3a6ec60dc81f0e06d1ba0d2d5d193b25 100644 (file)
 
 shader node_convert_from_float(
        float Val = 0.0,
+       output int ValInt = 0,
        output color Color = color(0.0, 0.0, 0.0),
        output vector Vector = vector(0.0, 0.0, 0.0),
        output point Point = point(0.0, 0.0, 0.0),
        output normal Normal = normal(0.0, 0.0, 0.0))
 {
+       ValInt = (int)Val;
        Color = color(Val, Val, Val);
        Vector = vector(Val, Val, Val);
        Point = point(Val, Val, Val);
diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl
new file mode 100644 (file)
index 0000000..060d418
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_convert_from_int(
+       int ValInt = 0,
+       output float Val = 0.0,
+       output color Color = color(0.0, 0.0, 0.0),
+       output vector Vector = vector(0.0, 0.0, 0.0),
+       output point Point = point(0.0, 0.0, 0.0),
+       output normal Normal = normal(0.0, 0.0, 0.0))
+{
+       float f = (float)ValInt;
+       Val = f;
+       Color = color(f, f, f);
+       Vector = vector(f, f, f);
+       Point = point(f, f, f);
+       Normal = normal(f, f, f);
+}
+
index b2c6c76661cca35bde8a3e09d9b3d672afa5dcf3..419e93e1518cc94b1599026f2c2d45a5a6a908f4 100644 (file)
 shader node_convert_from_normal(
        normal Normal = normal(0.0, 0.0, 0.0),
        output float Val = 0.0,
+       output int ValInt = 0,
        output vector Vector = vector(0.0, 0.0, 0.0),
        output color Color = color(0.0, 0.0, 0.0),
        output point Point = point(0.0, 0.0, 0.0))
 {
        Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0);
+       ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0));
        Vector = vector(Normal[0], Normal[1], Normal[2]);
        Color = color(Normal[0], Normal[1], Normal[2]);
        Point = point(Normal[0], Normal[1], Normal[2]);
index ae9a17dbc807c296ce28cf642674b94f64c4a5e8..cedd200f0887be27c2d0f5483e531c5bee152285 100644 (file)
 shader node_convert_from_point(
        point Point = point(0.0, 0.0, 0.0),
        output float Val = 0.0,
+       output int ValInt = 0,
        output vector Vector = vector(0.0, 0.0, 0.0),
        output color Color = color(0.0, 0.0, 0.0),
        output normal Normal = normal(0.0, 0.0, 0.0))
 {
        Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0);
+       ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0));
        Vector = vector(Point[0], Point[1], Point[2]);
        Color = color(Point[0], Point[1], Point[2]);
        Normal = normal(Point[0], Point[1], Point[2]);
index 19ef9331c0c51d5e3e195756385d546756ce3cff..a9f43a40074e1f8fc035d886ad0508e6ed7b107c 100644 (file)
 shader node_convert_from_vector(
        vector Vector = vector(0.0, 0.0, 0.0),
        output float Val = 0.0,
+       output int ValInt = 0,
        output color Color = color(0.0, 0.0, 0.0),
        output point Point = point(0.0, 0.0, 0.0),
        output normal Normal = normal(0.0, 0.0, 0.0))
 {
        Val = (Vector[0] + Vector[1] + Vector[2]) * (1.0 / 3.0);
+       ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0));
        Color = color(Vector[0], Vector[1], Vector[2]);
        Point = point(Vector[0], Vector[1], Vector[2]);
        Normal = normal(Vector[0], Vector[1], Vector[2]);
index 421eb146f887599cdc88ce4f8a1e49fcbe6a7818..698ef5016f02630e5228bc81d7eeeaff54ec2243 100644 (file)
@@ -82,6 +82,25 @@ __device_inline void stack_store_float(float *stack, uint a, float f)
        stack[a] = f;
 }
 
+__device_inline int stack_load_int(float *stack, uint a)
+{
+       kernel_assert(a < SVM_STACK_SIZE);
+
+       return __float_as_int(stack[a]);
+}
+
+__device_inline float stack_load_int_default(float *stack, uint a, uint value)
+{
+       return (a == (uint)SVM_STACK_INVALID)? (int)value: stack_load_int(stack, a);
+}
+
+__device_inline void stack_store_int(float *stack, uint a, int i)
+{
+       kernel_assert(a < SVM_STACK_SIZE);
+
+       stack[a] = __int_as_float(i);
+}
+
 __device_inline bool stack_valid(uint a)
 {
        return a != (uint)SVM_STACK_INVALID;
index 188b0489d9e73eaa573159996642db0d94059673..f74915a4bc97493c981b7e649a322d495b41be37 100644 (file)
@@ -23,6 +23,11 @@ CCL_NAMESPACE_BEGIN
 __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to)
 {
        switch(type) {
+               case NODE_CONVERT_FI: {
+                       float f = stack_load_float(stack, from);
+                       stack_store_int(stack, to, (int)f);
+                       break;
+               }
                case NODE_CONVERT_FV: {
                        float f = stack_load_float(stack, from);
                        stack_store_float3(stack, to, make_float3(f, f, f));
@@ -34,13 +39,34 @@ __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint fro
                        stack_store_float(stack, to, g);
                        break;
                }
+               case NODE_CONVERT_CI: {
+                       float3 f = stack_load_float3(stack, from);
+                       int i = (int)linear_rgb_to_gray(f);
+                       stack_store_int(stack, to, i);
+                       break;
+               }
                case NODE_CONVERT_VF: {
                        float3 f = stack_load_float3(stack, from);
                        float g = (f.x + f.y + f.z)*(1.0f/3.0f);
                        stack_store_float(stack, to, g);
                        break;
                }
-
+               case NODE_CONVERT_VI: {
+                       float3 f = stack_load_float3(stack, from);
+                       int i = (f.x + f.y + f.z)*(1.0f/3.0f);
+                       stack_store_int(stack, to, i);
+                       break;
+               }
+               case NODE_CONVERT_IF: {
+                       float f = (float)stack_load_int(stack, from);
+                       stack_store_float(stack, to, f);
+                       break;
+               }
+               case NODE_CONVERT_IV: {
+                       float f = (float)stack_load_int(stack, from);
+                       stack_store_float3(stack, to, make_float3(f, f, f));
+                       break;
+               }
        }
 }
 
index 487876ed417806ce67f5feb50cfa1d8a595b84d5..77df373a159360b83387bd237e224a86adf9f453 100644 (file)
@@ -210,8 +210,13 @@ typedef enum NodeVectorMath {
 
 typedef enum NodeConvert {
        NODE_CONVERT_FV,
+       NODE_CONVERT_FI,
        NODE_CONVERT_CF,
-       NODE_CONVERT_VF
+       NODE_CONVERT_CI,
+       NODE_CONVERT_VF,
+       NODE_CONVERT_VI,
+       NODE_CONVERT_IF,
+       NODE_CONVERT_IV
 } NodeConvert;
 
 typedef enum NodeDistanceMetric {
index acafe1d527899feabd377a553b26262ea5a44b8a..b339c3c3847270f311820032f377713966c7cf10 100644 (file)
@@ -44,6 +44,7 @@ class OSLCompiler;
 
 enum ShaderSocketType {
        SHADER_SOCKET_FLOAT,
+       SHADER_SOCKET_INT,
        SHADER_SOCKET_COLOR,
        SHADER_SOCKET_VECTOR,
        SHADER_SOCKET_POINT,
index 73c4566543153263cfa6b92883483f5521daf1e2..76267e9d014acc9f2fae7be8dffd403941c8e506 100644 (file)
@@ -1065,6 +1065,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
 
        if(from == SHADER_SOCKET_FLOAT)
                add_input("Val", SHADER_SOCKET_FLOAT);
+       else if(from == SHADER_SOCKET_INT)
+               add_input("ValInt", SHADER_SOCKET_INT);
        else if(from == SHADER_SOCKET_COLOR)
                add_input("Color", SHADER_SOCKET_COLOR);
        else if(from == SHADER_SOCKET_VECTOR)
@@ -1078,6 +1080,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
 
        if(to == SHADER_SOCKET_FLOAT)
                add_output("Val", SHADER_SOCKET_FLOAT);
+       else if(to == SHADER_SOCKET_INT)
+               add_output("ValInt", SHADER_SOCKET_INT);
        else if(to == SHADER_SOCKET_COLOR)
                add_output("Color", SHADER_SOCKET_COLOR);
        else if(to == SHADER_SOCKET_VECTOR)
@@ -1095,10 +1099,29 @@ void ConvertNode::compile(SVMCompiler& compiler)
        ShaderInput *in = inputs[0];
        ShaderOutput *out = outputs[0];
 
-       if(to == SHADER_SOCKET_FLOAT) {
+       if(from == SHADER_SOCKET_FLOAT) {
                compiler.stack_assign(in);
                compiler.stack_assign(out);
 
+               if(to == SHADER_SOCKET_INT)
+                       /* float to int */
+                       compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, in->stack_offset, out->stack_offset);
+               else
+                       /* float to float3 */
+                       compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset);
+       }
+       else if(from == SHADER_SOCKET_INT) {
+               compiler.stack_assign(in);
+               compiler.stack_assign(out);
+
+               if(to == SHADER_SOCKET_FLOAT)
+                       /* int to float */
+                       compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, in->stack_offset, out->stack_offset);
+               else
+                       /* int to vector/point/normal */
+                       compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, in->stack_offset, out->stack_offset);
+       }
+       else if(to == SHADER_SOCKET_FLOAT) {
                if(from == SHADER_SOCKET_COLOR)
                        /* color to float */
                        compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, in->stack_offset, out->stack_offset);
@@ -1106,12 +1129,13 @@ void ConvertNode::compile(SVMCompiler& compiler)
                        /* vector/point/normal to float */
                        compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset);
        }
-       else if(from == SHADER_SOCKET_FLOAT) {
-               compiler.stack_assign(in);
-               compiler.stack_assign(out);
-
-               /* float to float3 */
-               compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset);
+       else if(to == SHADER_SOCKET_INT) {
+               if(from == SHADER_SOCKET_COLOR)
+                       /* color to int */
+                       compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, in->stack_offset, out->stack_offset);
+               else
+                       /* vector/point/normal to int */
+                       compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, in->stack_offset, out->stack_offset);
        }
        else {
                /* float3 to float3 */
@@ -1134,6 +1158,8 @@ void ConvertNode::compile(OSLCompiler& compiler)
 {
        if(from == SHADER_SOCKET_FLOAT)
                compiler.add(this, "node_convert_from_float");
+       else if(from == SHADER_SOCKET_INT)
+               compiler.add(this, "node_convert_from_int");
        else if(from == SHADER_SOCKET_COLOR)
                compiler.add(this, "node_convert_from_color");
        else if(from == SHADER_SOCKET_VECTOR)
index 7fe7001ab51fba77d60e34f5050f7de057eeb8ff..21e6c7749b8edb00ff6c6081b98f5d414d5c9552 100644 (file)
@@ -246,6 +246,9 @@ void OSLCompiler::add(ShaderNode *node, const char *name)
                                case SHADER_SOCKET_FLOAT:
                                        parameter(param_name.c_str(), input->value.x);
                                        break;
+                               case SHADER_SOCKET_INT:
+                                       parameter(param_name.c_str(), (int)input->value.x);
+                                       break;
                                case SHADER_SOCKET_CLOSURE:
                                        break;
                        }
index 844ce01569f53a4813221d8326bc34f97499dc5b..c41d503b21748660ea7bac8c3b5d63aeb5c9439c 100644 (file)
@@ -119,6 +119,8 @@ int SVMCompiler::stack_size(ShaderSocketType type)
 {
        if(type == SHADER_SOCKET_FLOAT)
                return 1;
+       else if(type == SHADER_SOCKET_INT)
+               return 1;
        else if(type == SHADER_SOCKET_COLOR)
                return 3;
        else if(type == SHADER_SOCKET_VECTOR)
@@ -212,10 +214,13 @@ void SVMCompiler::stack_assign(ShaderInput *input)
                        if(input->type == SHADER_SOCKET_FLOAT) {
                                add_node(NODE_VALUE_F, __float_as_int(input->value.x), input->stack_offset);
                        }
+                       else if(input->type == SHADER_SOCKET_INT) {
+                               add_node(NODE_VALUE_F, (int)input->value.x, input->stack_offset);
+                       }
                        else if(input->type == SHADER_SOCKET_VECTOR ||
-                               input->type == SHADER_SOCKET_NORMAL ||
-                               input->type == SHADER_SOCKET_POINT ||
-                               input->type == SHADER_SOCKET_COLOR) {
+                               input->type == SHADER_SOCKET_NORMAL ||
+                               input->type == SHADER_SOCKET_POINT ||
+                               input->type == SHADER_SOCKET_COLOR) {
 
                                add_node(NODE_VALUE_V, input->stack_offset);
                                add_node(NODE_VALUE_V, input->value);