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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-03-08 23:52:58 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-03-08 23:52:58 +0400
commit9b8dae71a5e0f5cccb4031dbe5f07aae01744c82 (patch)
tree8a575ab4a9e6835eef2175209ee323df883fd0ac /intern
parent0f3e1821eae40c7cebfcf199b58370971b57fa35 (diff)
Cycles: support for environment texture "Mirror Ball" projection mode, next to
existing "Equirectangular". This projection is useful to create light probes from a chrome ball placed in a real scene. It expects as input a photograph of the chrome ball, cropped so the ball just fits inside the image boundaries. Example setup with panorama camera and mixing two (poor quality) photographs from different viewpoints to avoid stretching and hide the photographer: http://www.pasteall.org/pic/28036
Diffstat (limited to 'intern')
-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
7 files changed, 178 insertions, 49 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);