Integer socket support in Cycles. Int values are already supported natively in OSL, but were not used as actual ints on the SVM stack. This patch implements all the necessary functionality to support reading input values from RNA properties and convert between SHADER_SOCKET_INT and other types.

This commit is contained in:
Lukas Toenne
2012-10-20 13:11:45 +00:00
parent cf7dec94fe
commit d36dc6d8de
16 changed files with 152 additions and 13 deletions

View File

@@ -591,6 +591,7 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
if(string_iequals(in->name, attr.name())) { if(string_iequals(in->name, attr.name())) {
switch(in->type) { switch(in->type) {
case SHADER_SOCKET_FLOAT: case SHADER_SOCKET_FLOAT:
case SHADER_SOCKET_INT:
xml_read_float(&in->value.x, node, attr.name()); xml_read_float(&in->value.x, node, attr.name());
break; break;
case SHADER_SOCKET_COLOR: case SHADER_SOCKET_COLOR:

View File

@@ -80,6 +80,8 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
switch (b_type) { switch (b_type) {
case BL::NodeSocket::type_VALUE: case BL::NodeSocket::type_VALUE:
return SHADER_SOCKET_FLOAT; return SHADER_SOCKET_FLOAT;
case BL::NodeSocket::type_INT:
return SHADER_SOCKET_INT;
case BL::NodeSocket::type_VECTOR: case BL::NodeSocket::type_VECTOR:
return SHADER_SOCKET_VECTOR; return SHADER_SOCKET_VECTOR;
case BL::NodeSocket::type_RGBA: 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_BOOLEAN:
case BL::NodeSocket::type_MESH: case BL::NodeSocket::type_MESH:
case BL::NodeSocket::type_INT:
default: default:
return SHADER_SOCKET_FLOAT; return SHADER_SOCKET_FLOAT;
} }
@@ -104,6 +105,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
input->set(value_sock.default_value()); input->set(value_sock.default_value());
break; break;
} }
case SHADER_SOCKET_INT: {
BL::NodeSocketIntNone value_sock(sock);
input->set((float)value_sock.default_value());
break;
}
case SHADER_SOCKET_COLOR: { case SHADER_SOCKET_COLOR: {
BL::NodeSocketRGBA rgba_sock(sock); BL::NodeSocketRGBA rgba_sock(sock);
input->set(get_float3(rgba_sock.default_value())); input->set(get_float3(rgba_sock.default_value()));

View File

@@ -12,6 +12,7 @@ set(SRC_OSL
node_combine_rgb.osl node_combine_rgb.osl
node_convert_from_color.osl node_convert_from_color.osl
node_convert_from_float.osl node_convert_from_float.osl
node_convert_from_int.osl
node_convert_from_normal.osl node_convert_from_normal.osl
node_convert_from_point.osl node_convert_from_point.osl
node_convert_from_vector.osl node_convert_from_vector.osl

View File

@@ -21,11 +21,13 @@
shader node_convert_from_color( shader node_convert_from_color(
color Color = color(0.0, 0.0, 0.0), color Color = color(0.0, 0.0, 0.0),
output float Val = 0.0, output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(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 point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(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; 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]); Vector = vector(Color[0], Color[1], Color[2]);
Point = point(Color[0], Color[1], Color[2]); Point = point(Color[0], Color[1], Color[2]);
Normal = normal(Color[0], Color[1], Color[2]); Normal = normal(Color[0], Color[1], Color[2]);

View File

@@ -20,11 +20,13 @@
shader node_convert_from_float( shader node_convert_from_float(
float Val = 0.0, float Val = 0.0,
output int ValInt = 0,
output color Color = color(0.0, 0.0, 0.0), output color Color = color(0.0, 0.0, 0.0),
output vector Vector = vector(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 point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0)) output normal Normal = normal(0.0, 0.0, 0.0))
{ {
ValInt = (int)Val;
Color = color(Val, Val, Val); Color = color(Val, Val, Val);
Vector = vector(Val, Val, Val); Vector = vector(Val, Val, Val);
Point = point(Val, Val, Val); Point = point(Val, Val, Val);

View File

@@ -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);
}

View File

@@ -21,11 +21,13 @@
shader node_convert_from_normal( shader node_convert_from_normal(
normal Normal = normal(0.0, 0.0, 0.0), normal Normal = normal(0.0, 0.0, 0.0),
output float Val = 0.0, output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0), output vector Vector = vector(0.0, 0.0, 0.0),
output color Color = color(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)) output point Point = point(0.0, 0.0, 0.0))
{ {
Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.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]); Vector = vector(Normal[0], Normal[1], Normal[2]);
Color = color(Normal[0], Normal[1], Normal[2]); Color = color(Normal[0], Normal[1], Normal[2]);
Point = point(Normal[0], Normal[1], Normal[2]); Point = point(Normal[0], Normal[1], Normal[2]);

View File

@@ -21,11 +21,13 @@
shader node_convert_from_point( shader node_convert_from_point(
point Point = point(0.0, 0.0, 0.0), point Point = point(0.0, 0.0, 0.0),
output float Val = 0.0, output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0), output vector Vector = vector(0.0, 0.0, 0.0),
output color Color = color(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)) output normal Normal = normal(0.0, 0.0, 0.0))
{ {
Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.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]); Vector = vector(Point[0], Point[1], Point[2]);
Color = color(Point[0], Point[1], Point[2]); Color = color(Point[0], Point[1], Point[2]);
Normal = normal(Point[0], Point[1], Point[2]); Normal = normal(Point[0], Point[1], Point[2]);

View File

@@ -21,11 +21,13 @@
shader node_convert_from_vector( shader node_convert_from_vector(
vector Vector = vector(0.0, 0.0, 0.0), vector Vector = vector(0.0, 0.0, 0.0),
output float Val = 0.0, output float Val = 0.0,
output int ValInt = 0,
output color Color = color(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), output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(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); 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]); Color = color(Vector[0], Vector[1], Vector[2]);
Point = point(Vector[0], Vector[1], Vector[2]); Point = point(Vector[0], Vector[1], Vector[2]);
Normal = normal(Vector[0], Vector[1], Vector[2]); Normal = normal(Vector[0], Vector[1], Vector[2]);

View File

@@ -82,6 +82,25 @@ __device_inline void stack_store_float(float *stack, uint a, float f)
stack[a] = 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) __device_inline bool stack_valid(uint a)
{ {
return a != (uint)SVM_STACK_INVALID; return a != (uint)SVM_STACK_INVALID;

View File

@@ -23,6 +23,11 @@ CCL_NAMESPACE_BEGIN
__device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to) __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to)
{ {
switch(type) { 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: { case NODE_CONVERT_FV: {
float f = stack_load_float(stack, from); float f = stack_load_float(stack, from);
stack_store_float3(stack, to, make_float3(f, f, f)); 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); stack_store_float(stack, to, g);
break; 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: { case NODE_CONVERT_VF: {
float3 f = stack_load_float3(stack, from); float3 f = stack_load_float3(stack, from);
float g = (f.x + f.y + f.z)*(1.0f/3.0f); float g = (f.x + f.y + f.z)*(1.0f/3.0f);
stack_store_float(stack, to, g); stack_store_float(stack, to, g);
break; 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;
}
} }
} }

View File

@@ -210,8 +210,13 @@ typedef enum NodeVectorMath {
typedef enum NodeConvert { typedef enum NodeConvert {
NODE_CONVERT_FV, NODE_CONVERT_FV,
NODE_CONVERT_FI,
NODE_CONVERT_CF, NODE_CONVERT_CF,
NODE_CONVERT_VF NODE_CONVERT_CI,
NODE_CONVERT_VF,
NODE_CONVERT_VI,
NODE_CONVERT_IF,
NODE_CONVERT_IV
} NodeConvert; } NodeConvert;
typedef enum NodeDistanceMetric { typedef enum NodeDistanceMetric {

View File

@@ -44,6 +44,7 @@ class OSLCompiler;
enum ShaderSocketType { enum ShaderSocketType {
SHADER_SOCKET_FLOAT, SHADER_SOCKET_FLOAT,
SHADER_SOCKET_INT,
SHADER_SOCKET_COLOR, SHADER_SOCKET_COLOR,
SHADER_SOCKET_VECTOR, SHADER_SOCKET_VECTOR,
SHADER_SOCKET_POINT, SHADER_SOCKET_POINT,

View File

@@ -1065,6 +1065,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
if(from == SHADER_SOCKET_FLOAT) if(from == SHADER_SOCKET_FLOAT)
add_input("Val", 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) else if(from == SHADER_SOCKET_COLOR)
add_input("Color", SHADER_SOCKET_COLOR); add_input("Color", SHADER_SOCKET_COLOR);
else if(from == SHADER_SOCKET_VECTOR) else if(from == SHADER_SOCKET_VECTOR)
@@ -1078,6 +1080,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
if(to == SHADER_SOCKET_FLOAT) if(to == SHADER_SOCKET_FLOAT)
add_output("Val", 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) else if(to == SHADER_SOCKET_COLOR)
add_output("Color", SHADER_SOCKET_COLOR); add_output("Color", SHADER_SOCKET_COLOR);
else if(to == SHADER_SOCKET_VECTOR) else if(to == SHADER_SOCKET_VECTOR)
@@ -1095,10 +1099,29 @@ void ConvertNode::compile(SVMCompiler& compiler)
ShaderInput *in = inputs[0]; ShaderInput *in = inputs[0];
ShaderOutput *out = outputs[0]; ShaderOutput *out = outputs[0];
if(to == SHADER_SOCKET_FLOAT) { if(from == SHADER_SOCKET_FLOAT) {
compiler.stack_assign(in); compiler.stack_assign(in);
compiler.stack_assign(out); 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) if(from == SHADER_SOCKET_COLOR)
/* color to float */ /* color to float */
compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, in->stack_offset, out->stack_offset); 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 */ /* vector/point/normal to float */
compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset); compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset);
} }
else if(from == SHADER_SOCKET_FLOAT) { else if(to == SHADER_SOCKET_INT) {
compiler.stack_assign(in); if(from == SHADER_SOCKET_COLOR)
compiler.stack_assign(out); /* color to int */
compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, in->stack_offset, out->stack_offset);
/* float to float3 */ else
compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset); /* vector/point/normal to int */
compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, in->stack_offset, out->stack_offset);
} }
else { else {
/* float3 to float3 */ /* float3 to float3 */
@@ -1134,6 +1158,8 @@ void ConvertNode::compile(OSLCompiler& compiler)
{ {
if(from == SHADER_SOCKET_FLOAT) if(from == SHADER_SOCKET_FLOAT)
compiler.add(this, "node_convert_from_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) else if(from == SHADER_SOCKET_COLOR)
compiler.add(this, "node_convert_from_color"); compiler.add(this, "node_convert_from_color");
else if(from == SHADER_SOCKET_VECTOR) else if(from == SHADER_SOCKET_VECTOR)

View File

@@ -246,6 +246,9 @@ void OSLCompiler::add(ShaderNode *node, const char *name)
case SHADER_SOCKET_FLOAT: case SHADER_SOCKET_FLOAT:
parameter(param_name.c_str(), input->value.x); parameter(param_name.c_str(), input->value.x);
break; break;
case SHADER_SOCKET_INT:
parameter(param_name.c_str(), (int)input->value.x);
break;
case SHADER_SOCKET_CLOSURE: case SHADER_SOCKET_CLOSURE:
break; break;
} }

View File

@@ -119,6 +119,8 @@ int SVMCompiler::stack_size(ShaderSocketType type)
{ {
if(type == SHADER_SOCKET_FLOAT) if(type == SHADER_SOCKET_FLOAT)
return 1; return 1;
else if(type == SHADER_SOCKET_INT)
return 1;
else if(type == SHADER_SOCKET_COLOR) else if(type == SHADER_SOCKET_COLOR)
return 3; return 3;
else if(type == SHADER_SOCKET_VECTOR) else if(type == SHADER_SOCKET_VECTOR)
@@ -212,10 +214,13 @@ void SVMCompiler::stack_assign(ShaderInput *input)
if(input->type == SHADER_SOCKET_FLOAT) { if(input->type == SHADER_SOCKET_FLOAT) {
add_node(NODE_VALUE_F, __float_as_int(input->value.x), input->stack_offset); 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 || else if(input->type == SHADER_SOCKET_VECTOR ||
input->type == SHADER_SOCKET_NORMAL || input->type == SHADER_SOCKET_NORMAL ||
input->type == SHADER_SOCKET_POINT || input->type == SHADER_SOCKET_POINT ||
input->type == SHADER_SOCKET_COLOR) { input->type == SHADER_SOCKET_COLOR) {
add_node(NODE_VALUE_V, input->stack_offset); add_node(NODE_VALUE_V, input->stack_offset);
add_node(NODE_VALUE_V, input->value); add_node(NODE_VALUE_V, input->value);