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:
-rw-r--r--intern/cycles/blender/blender_shader.cpp1
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h32
-rw-r--r--intern/cycles/kernel/svm/svm_image.h11
-rw-r--r--intern/cycles/render/nodes.cpp153
-rw-r--r--intern/cycles/render/nodes.h2
-rw-r--r--intern/cycles/render/svm.cpp24
-rw-r--r--intern/cycles/render/svm.h4
-rw-r--r--source/blender/editors/space_node/drawnode.c10
-rw-r--r--source/blender/makesdna/DNA_node_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c1
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;
}