diff options
-rw-r--r-- | intern/cycles/kernel/shaders/node_image_texture.osl | 26 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_image.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 6 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 12 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 10 |
6 files changed, 49 insertions, 11 deletions
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl index a55640a9168..c63ad179060 100644 --- a/intern/cycles/kernel/shaders/node_image_texture.osl +++ b/intern/cycles/kernel/shaders/node_image_texture.osl @@ -17,6 +17,25 @@ #include "stdosl.h" #include "node_color.h" +point map_to_sphere(vector dir) +{ + float len = length(dir); + float v, u; + if(len > 0.0) { + if(dir[0] == 0.0 && dir[1] == 0.0) { + u = 0.0; /* othwise domain error */ + } + else { + u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0; + } + v = 1.0 - acos(dir[2] / len) / M_PI; + } + else { + v = u = 0.0; /* to avoid un-initialized variables */ + } + return point(u, v, 0.0); +} + color image_texture_lookup(string filename, string color_space, float u, float v, output float Alpha, int use_alpha, int is_float, string interpolation) { color rgb = (color)texture(filename, u, 1.0 - v, "wrap", "periodic", "interp", interpolation, "alpha", Alpha); @@ -136,5 +155,10 @@ shader node_image_texture( Alpha += weight[2] * tmp_alpha; } } + else if (projection == "Sphere") { + point projected = map_to_sphere((p - vector(0.5, 0.5, 0.5)) * 2.0); + Color = image_texture_lookup(filename, color_space, + projected[0], projected[1], + Alpha, use_alpha, is_float, interpolation); + } } - diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 9948a192117..44d15e185cb 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -363,6 +363,10 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta float3 co = stack_load_float3(stack, co_offset); uint use_alpha = stack_valid(alpha_offset); + if(node.w == NODE_IMAGE_PROJ_SPHERE) { + co = (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f; + map_to_sphere(&co.x, &co.y, co.x, co.y, co.z); + } float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha); if(stack_valid(out_offset)) @@ -463,7 +467,6 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float stack_store_float(stack, alpha_offset, f.w); } - ccl_device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint id = node.y; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index b1439aa1616..d5c3cebe1af 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -334,6 +334,12 @@ typedef enum NodeNormalMapSpace { NODE_NORMAL_MAP_BLENDER_WORLD, } NodeNormalMapSpace; +typedef enum NodeImageProjection { + NODE_IMAGE_PROJ_FLAT = 0, + NODE_IMAGE_PROJ_BOX = 1, + NODE_IMAGE_PROJ_SPHERE = 2, +} NodeImageProjection; + typedef enum ShaderType { SHADER_TYPE_SURFACE, SHADER_TYPE_VOLUME, diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 653bd5dd19c..05ead55ca2d 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -174,8 +174,9 @@ static ShaderEnum image_projection_init() { ShaderEnum enm; - enm.insert("Flat", 0); - enm.insert("Box", 1); + enm.insert("Flat", NODE_IMAGE_PROJ_FLAT); + enm.insert("Box", NODE_IMAGE_PROJ_BOX); + enm.insert("Sphere", NODE_IMAGE_PROJ_SPHERE); return enm; } @@ -266,14 +267,15 @@ void ImageTextureNode::compile(SVMCompiler& compiler) tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); } - if(projection == "Flat") { + if(projection != "Box") { compiler.add_node(NODE_TEX_IMAGE, slot, compiler.encode_uchar4( vector_offset, color_out->stack_offset, alpha_out->stack_offset, - srgb)); + srgb), + projection_enum[projection]); } else { compiler.add_node(NODE_TEX_IMAGE_BOX, @@ -285,7 +287,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler) srgb), __float_as_int(projection_blend)); } - + if(vector_offset != vector_in->stack_offset) compiler.stack_clear_offset(vector_in->type, vector_offset); } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 02c451e8549..5cd4e0d223b 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -962,6 +962,7 @@ typedef struct NodeSunBeams { /* image texture */ #define SHD_PROJ_FLAT 0 #define SHD_PROJ_BOX 1 +#define SHD_PROJ_SPHERE 2 /* image texture interpolation */ #define SHD_INTERP_LINEAR 0 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index fa8d2669161..48e56e28f52 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3431,10 +3431,12 @@ static void def_sh_tex_image(StructRNA *srna) }; static const EnumPropertyItem prop_projection_items[] = { - {SHD_PROJ_FLAT, "FLAT", 0, "Flat", - "Image is projected flat using the X and Y coordinates of the texture vector"}, - {SHD_PROJ_BOX, "BOX", 0, "Box", - "Image is projected using different components for each side of the object space bounding box"}, + {SHD_PROJ_FLAT, "FLAT", 0, "Flat", + "Image is projected flat using the X and Y coordinates of the texture vector"}, + {SHD_PROJ_BOX, "BOX", 0, "Box", + "Image is projected using different components for each side of the object space bounding box"}, + {SHD_PROJ_SPHERE, "SPHERE", 0, "Sphere", + "Image is projected spherically using the Z axis as central"}, {0, NULL, 0, NULL, NULL} }; |