diff options
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_montecarlo.h | 32 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_image.h | 11 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 153 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/svm.cpp | 24 | ||||
-rw-r--r-- | intern/cycles/render/svm.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 10 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 13 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_environment.c | 1 |
11 files changed, 205 insertions, 52 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 45076122467..5c26a4d2163 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -332,6 +332,7 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Shader if(b_image) env->filename = blender_absolute_path(b_data, b_image, b_image.filepath()); env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()]; + env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()]; get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping()); node = env; break; diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index 66bd0ee9998..68f007cfd97 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -224,6 +224,38 @@ __device float3 equirectangular_to_direction(float u, float v) cos(theta)); } +/* Mirror Ball <-> Cartesion direction */ + +__device float3 mirrorball_to_direction(float u, float v) +{ + /* point on sphere */ + float3 dir; + + dir.x = 2.0f*u - 1.0f; + dir.z = 2.0f*v - 1.0f; + dir.y = -sqrt(max(1.0f - dir.x*dir.x - dir.z*dir.z, 0.0f)); + + /* reflection */ + float3 I = make_float3(0.0f, -1.0f, 0.0f); + + return 2.0f*dot(dir, I)*dir - I; +} + +__device float2 direction_to_mirrorball(float3 dir) +{ + /* inverse of mirrorball_to_direction */ + dir.y -= 1.0f; + + float div = 2.0f*sqrt(max(-0.5f*dir.y, 0.0f)); + if(div > 0.0f) + dir /= div; + + float u = 0.5f*(dir.x + 1.0f); + float v = 0.5f*(dir.z + 1.0f); + + return make_float2(u, v); +} + CCL_NAMESPACE_END #endif /* __KERNEL_MONTECARLO_CL__ */ diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 3d737b483cb..eddd0f7034a 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -171,11 +171,20 @@ __device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float { uint id = node.y; uint co_offset, out_offset, alpha_offset, srgb; + uint projection = node.w; decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); float3 co = stack_load_float3(stack, co_offset); - float2 uv = direction_to_equirectangular(co); + float2 uv; + + co = normalize(co); + + if(projection == 0) + uv = direction_to_equirectangular(co); + else + uv = direction_to_mirrorball(co); + float4 f = svm_image_texture(kg, id, uv.x, uv.y); float3 r = make_float3(f.x, f.y, f.z); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 86f0f3127e9..a98352aa85a 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -146,19 +146,26 @@ void ImageTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign(alpha_out); if(slot != -1) { - int srgb = (is_float || color_space != "Color")? 0: 1; compiler.stack_assign(vector_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int srgb = (is_float || color_space != "Color")? 0: 1; + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } compiler.add_node(NODE_TEX_IMAGE, slot, compiler.encode_uchar4( - vector_in->stack_offset, + vector_offset, color_out->stack_offset, alpha_out->stack_offset, srgb)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } else { /* image not found */ @@ -183,7 +190,18 @@ void ImageTextureNode::compile(OSLCompiler& compiler) /* Environment Texture */ +static ShaderEnum projection_init() +{ + ShaderEnum enm; + + enm.insert("Equirectangular", 0); + enm.insert("Mirror Ball", 1); + + return enm; +} + ShaderEnum EnvironmentTextureNode::color_space_enum = color_space_init(); +ShaderEnum EnvironmentTextureNode::projection_enum = projection_init(); EnvironmentTextureNode::EnvironmentTextureNode() : TextureNode("environment_texture") @@ -193,6 +211,7 @@ EnvironmentTextureNode::EnvironmentTextureNode() is_float = false; filename = ""; color_space = ustring("Color"); + projection = ustring("Equirectangular"); add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION); add_output("Color", SHADER_SOCKET_COLOR); @@ -228,22 +247,29 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign(color_out); if(!alpha_out->links.empty()) compiler.stack_assign(alpha_out); - + if(slot != -1) { - int srgb = (is_float || color_space != "Color")? 0: 1; - compiler.stack_assign(vector_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int srgb = (is_float || color_space != "Color")? 0: 1; + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } compiler.add_node(NODE_TEX_ENVIRONMENT, slot, compiler.encode_uchar4( - vector_in->stack_offset, + vector_offset, color_out->stack_offset, alpha_out->stack_offset, - srgb)); + srgb), + projection_enum[projection]); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } else { /* image not found */ @@ -351,11 +377,19 @@ void SkyTextureNode::compile(SVMCompiler& compiler) if(vector_in->link) compiler.stack_assign(vector_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } compiler.stack_assign(color_out); - compiler.add_node(NODE_TEX_SKY, vector_in->stack_offset, color_out->stack_offset); + compiler.add_node(NODE_TEX_SKY, vector_offset, color_out->stack_offset); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void SkyTextureNode::compile(OSLCompiler& compiler) @@ -402,8 +436,12 @@ void GradientTextureNode::compile(SVMCompiler& compiler) if(vector_in->link) compiler.stack_assign(vector_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } if(!fac_out->links.empty()) compiler.stack_assign(fac_out); @@ -411,7 +449,10 @@ void GradientTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign(color_out); compiler.add_node(NODE_TEX_GRADIENT, - compiler.encode_uchar4(type_enum[type], vector_in->stack_offset, fac_out->stack_offset, color_out->stack_offset)); + compiler.encode_uchar4(type_enum[type], vector_offset, fac_out->stack_offset, color_out->stack_offset)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void GradientTextureNode::compile(OSLCompiler& compiler) @@ -448,8 +489,12 @@ void NoiseTextureNode::compile(SVMCompiler& compiler) if(detail_in->link) compiler.stack_assign(detail_in); if(distortion_in->link) compiler.stack_assign(distortion_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } if(!fac_out->links.empty()) compiler.stack_assign(fac_out); @@ -457,12 +502,15 @@ void NoiseTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign(color_out); compiler.add_node(NODE_TEX_NOISE, - compiler.encode_uchar4(vector_in->stack_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset), + compiler.encode_uchar4(vector_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset), compiler.encode_uchar4(color_out->stack_offset, fac_out->stack_offset)); compiler.add_node( __float_as_int(scale_in->value.x), __float_as_int(detail_in->value.x), __float_as_int(distortion_in->value.x)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void NoiseTextureNode::compile(OSLCompiler& compiler) @@ -506,16 +554,23 @@ void VoronoiTextureNode::compile(SVMCompiler& compiler) if(vector_in->link) compiler.stack_assign(vector_in); if(scale_in->link) compiler.stack_assign(scale_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } compiler.stack_assign(color_out); compiler.stack_assign(fac_out); compiler.add_node(NODE_TEX_VORONOI, coloring_enum[coloring], - compiler.encode_uchar4(scale_in->stack_offset, vector_in->stack_offset, fac_out->stack_offset, color_out->stack_offset), + compiler.encode_uchar4(scale_in->stack_offset, vector_offset, fac_out->stack_offset, color_out->stack_offset), __float_as_int(scale_in->value.x)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void VoronoiTextureNode::compile(OSLCompiler& compiler) @@ -578,8 +633,12 @@ void MusgraveTextureNode::compile(SVMCompiler& compiler) if(gain_in->link) compiler.stack_assign(gain_in); if(scale_in->link) compiler.stack_assign(scale_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } if(!fac_out->links.empty()) compiler.stack_assign(fac_out); @@ -587,7 +646,7 @@ void MusgraveTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign(color_out); compiler.add_node(NODE_TEX_MUSGRAVE, - compiler.encode_uchar4(type_enum[type], vector_in->stack_offset, color_out->stack_offset, fac_out->stack_offset), + compiler.encode_uchar4(type_enum[type], vector_offset, color_out->stack_offset, fac_out->stack_offset), compiler.encode_uchar4(dimension_in->stack_offset, lacunarity_in->stack_offset, detail_in->stack_offset, offset_in->stack_offset), compiler.encode_uchar4(gain_in->stack_offset, scale_in->stack_offset)); compiler.add_node(__float_as_int(dimension_in->value.x), @@ -596,6 +655,9 @@ void MusgraveTextureNode::compile(SVMCompiler& compiler) __float_as_int(offset_in->value.x)); compiler.add_node(__float_as_int(gain_in->value.x), __float_as_int(scale_in->value.x)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void MusgraveTextureNode::compile(OSLCompiler& compiler) @@ -650,8 +712,12 @@ void WaveTextureNode::compile(SVMCompiler& compiler) if(dscale_in->link) compiler.stack_assign(dscale_in); if(vector_in->link) compiler.stack_assign(vector_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } if(!fac_out->links.empty()) compiler.stack_assign(fac_out); @@ -660,13 +726,16 @@ void WaveTextureNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_TEX_WAVE, compiler.encode_uchar4(type_enum[type], color_out->stack_offset, fac_out->stack_offset, dscale_in->stack_offset), - compiler.encode_uchar4(vector_in->stack_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset)); + compiler.encode_uchar4(vector_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset)); compiler.add_node( __float_as_int(scale_in->value.x), __float_as_int(detail_in->value.x), __float_as_int(distortion_in->value.x), __float_as_int(dscale_in->value.x)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void WaveTextureNode::compile(OSLCompiler& compiler) @@ -703,8 +772,12 @@ void MagicTextureNode::compile(SVMCompiler& compiler) if(distortion_in->link) compiler.stack_assign(distortion_in); if(scale_in->link) compiler.stack_assign(scale_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } if(!fac_out->links.empty()) compiler.stack_assign(fac_out); @@ -713,10 +786,13 @@ void MagicTextureNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_TEX_MAGIC, compiler.encode_uchar4(depth, color_out->stack_offset, fac_out->stack_offset), - compiler.encode_uchar4(vector_in->stack_offset, scale_in->stack_offset, distortion_in->stack_offset)); + compiler.encode_uchar4(vector_offset, scale_in->stack_offset, distortion_in->stack_offset)); compiler.add_node( __float_as_int(scale_in->value.x), __float_as_int(distortion_in->value.x)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void MagicTextureNode::compile(OSLCompiler& compiler) @@ -754,8 +830,12 @@ void CheckerTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign(color2_in); if(scale_in->link) compiler.stack_assign(scale_in); - if(!tex_mapping.skip()) - tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } if(!color_out->links.empty()) compiler.stack_assign(color_out); @@ -763,9 +843,12 @@ void CheckerTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign(fac_out); compiler.add_node(NODE_TEX_CHECKER, - compiler.encode_uchar4(vector_in->stack_offset, color1_in->stack_offset, color2_in->stack_offset, scale_in->stack_offset), + compiler.encode_uchar4(vector_offset, color1_in->stack_offset, color2_in->stack_offset, scale_in->stack_offset), compiler.encode_uchar4(color_out->stack_offset, fac_out->stack_offset), __float_as_int(scale_in->value.x)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); } void CheckerTextureNode::compile(OSLCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 6c9ed422b88..e0329cb9b1d 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -82,8 +82,10 @@ public: bool is_float; string filename; ustring color_space; + ustring projection; static ShaderEnum color_space_enum; + static ShaderEnum projection_enum; }; class SkyTextureNode : public TextureNode { diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index ae666ddfe68..46c6149ab32 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -161,6 +161,14 @@ int SVMCompiler::stack_find_offset(ShaderSocketType type) return offset; } +void SVMCompiler::stack_clear_offset(ShaderSocketType type, int offset) +{ + int size = stack_size(type); + + for(int i = 0; i < size; i++) + active_stack.users[offset + i]--; +} + void SVMCompiler::stack_backup(StackBackup& backup, set<ShaderNode*>& done) { backup.done = done; @@ -261,11 +269,7 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done) all_done = false; if(all_done) { - int size = stack_size(output->type); - - for(int i = 0; i < size; i++) - active_stack.users[output->stack_offset + i]--; - + stack_clear_offset(output->type, output->stack_offset); output->stack_offset = SVM_STACK_INVALID; foreach(ShaderInput *in, output->links) @@ -279,11 +283,7 @@ void SVMCompiler::stack_clear_temporary(ShaderNode *node) { foreach(ShaderInput *input, node->inputs) { if(!input->link && input->stack_offset != SVM_STACK_INVALID) { - int size = stack_size(input->type); - - for(int i = 0; i < size; i++) - active_stack.users[input->stack_offset + i]--; - + stack_clear_offset(input->type, input->stack_offset); input->stack_offset = SVM_STACK_INVALID; } } @@ -514,14 +514,14 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don generate_multi_closure(cl1in->link->parent, done, out1_offset); if(fin) - active_stack.users[out1_offset]--; + stack_clear_offset(SHADER_SOCKET_FLOAT, out1_offset); } if(cl2in->link) { generate_multi_closure(cl2in->link->parent, done, out2_offset); if(fin) - active_stack.users[out2_offset]--; + stack_clear_offset(SHADER_SOCKET_FLOAT, out2_offset); } } else { diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index d66d3816068..d8a1b14d637 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -59,7 +59,10 @@ public: void stack_assign(ShaderOutput *output); void stack_assign(ShaderInput *input); + int stack_find_offset(ShaderSocketType type); + void stack_clear_offset(ShaderSocketType type, int offset); void stack_link(ShaderInput *input, ShaderOutput *output); + void add_node(NodeType type, int a = 0, int b = 0, int c = 0); void add_node(int a = 0, int b = 0, int c = 0, int d = 0); void add_node(NodeType type, const float3& f); @@ -115,7 +118,6 @@ protected: void stack_clear_temporary(ShaderNode *node); int stack_size(ShaderSocketType type); - int stack_find_offset(ShaderSocketType type); void stack_clear_users(ShaderNode *node, set<ShaderNode*>& done); bool node_skip_input(ShaderNode *node, ShaderInput *input); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index bc22e668b5a..64af846a79b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1093,6 +1093,14 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); } + +static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); + uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); + uiItemR(layout, ptr, "projection", 0, "", ICON_NONE); +} + static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "sun_direction", 0, "", ICON_NONE); @@ -1225,7 +1233,7 @@ static void node_shader_set_butfunc(bNodeType *ntype) ntype->uifunc= node_shader_buts_tex_image; break; case SH_NODE_TEX_ENVIRONMENT: - ntype->uifunc= node_shader_buts_tex_image; + ntype->uifunc= node_shader_buts_tex_environment; break; case SH_NODE_TEX_GRADIENT: ntype->uifunc= node_shader_buts_tex_gradient; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 0d309aad36c..dbb3f6bfc66 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -475,7 +475,7 @@ typedef struct NodeTexChecker { typedef struct NodeTexEnvironment { NodeTexBase base; - int color_space, pad; + int color_space, projection; } NodeTexEnvironment; typedef struct NodeTexGradient { @@ -585,6 +585,10 @@ typedef struct TexNodeOutput { #define SHD_COLORSPACE_NONE 0 #define SHD_COLORSPACE_COLOR 1 +/* environment texture */ +#define SHD_PROJ_EQUIRECTANGULAR 0 +#define SHD_PROJ_MIRROR_BALL 1 + /* blur node */ #define CMP_NODE_BLUR_ASPECT_NONE 0 #define CMP_NODE_BLUR_ASPECT_Y 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 2caf1f06585..d3a2e406992 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1268,6 +1268,11 @@ static void def_sh_tex_environment(StructRNA *srna) {SHD_COLORSPACE_NONE, "NONE", 0, "Non-Color Data", "Image contains non-color data, for example a displacement or normal map, and will not be converted"}, {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem prop_projection_items[] = { + {SHD_PROJ_EQUIRECTANGULAR, "EQUIRECTANGULAR", 0, "Equirectangular", "Equirectangular or latitude-longitude projection"}, + {SHD_PROJ_MIRROR_BALL, "MIRROR_BALL", 0, "Mirror Ball", "Projection from an orthographic photo of a mirror ball"}, + {0, NULL, 0, NULL, NULL}}; + PropertyRNA *prop; prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); @@ -1277,13 +1282,19 @@ static void def_sh_tex_environment(StructRNA *srna) RNA_def_property_ui_text(prop, "Image", ""); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_image_update"); - RNA_def_struct_sdna_from(srna, "NodeTexImage", "storage"); + RNA_def_struct_sdna_from(srna, "NodeTexEnvironment", "storage"); def_sh_tex(srna); prop = RNA_def_property(srna, "color_space", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_color_space_items); RNA_def_property_ui_text(prop, "Color Space", "Image file color space"); RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "projection", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_projection_items); + RNA_def_property_ui_text(prop, "Projection", "Projection of the input image"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + } static void def_sh_tex_image(StructRNA *srna) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index d6957e53f10..8ecff6e3767 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -45,6 +45,7 @@ static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode* no default_tex_mapping(&tex->base.tex_mapping); default_color_mapping(&tex->base.color_mapping); tex->color_space = SHD_COLORSPACE_COLOR; + tex->projection = SHD_PROJ_EQUIRECTANGULAR; node->storage = tex; } |