[Bf-blender-cvs] [8b54b957f79] cycles_texture_cache: Cycles: ImageTexture node now has dx/dy inputs for offset texture coordinates, being filled out with a hacky shader node duplication a la bump_dx/bump_dy
Stefan Werner
noreply at git.blender.org
Mon Nov 27 20:40:19 CET 2017
Commit: 8b54b957f7921a44fea5f9f4f3a5cc1e9620ef9c
Author: Stefan Werner
Date: Mon May 8 15:12:03 2017 +0200
Branches: cycles_texture_cache
https://developer.blender.org/rB8b54b957f7921a44fea5f9f4f3a5cc1e9620ef9c
Cycles: ImageTexture node now has dx/dy inputs for offset texture coordinates, being filled out with a hacky shader node duplication a la bump_dx/bump_dy
===================================================================
M intern/cycles/graph/node_type.h
M intern/cycles/kernel/svm/svm.h
M intern/cycles/kernel/svm/svm_image.h
M intern/cycles/render/graph.cpp
M intern/cycles/render/graph.h
M intern/cycles/render/nodes.cpp
M intern/cycles/render/nodes.h
===================================================================
diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h
index 7d46e31ce24..035c41cbc2b 100644
--- a/intern/cycles/graph/node_type.h
+++ b/intern/cycles/graph/node_type.h
@@ -78,7 +78,9 @@ struct SocketType
LINK_NORMAL = (1 << 7),
LINK_POSITION = (1 << 8),
LINK_TANGENT = (1 << 9),
- DEFAULT_LINK_MASK = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)
+ LINK_TEXTURE_DX = (1 << 10),
+ LINK_TEXTURE_DY = (1 << 11),
+ DEFAULT_LINK_MASK = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11)
};
ustring name;
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 9ff02c1586b..a6516cd203b 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -272,7 +272,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */
# ifdef __TEXTURES__
case NODE_TEX_IMAGE:
- svm_node_tex_image(kg, sd, stack, node);
+ svm_node_tex_image(kg, sd, path_flag, stack, node);
break;
case NODE_TEX_IMAGE_BOX:
svm_node_tex_image_box(kg, sd, stack, node);
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 8d36d7383bb..ccc0a328f2e 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -20,17 +20,28 @@
CCL_NAMESPACE_BEGIN
-ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha)
+ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, differential ds, differential dt, uint srgb, uint use_alpha, bool fast_lookup)
{
float4 r;
# ifdef __OIIO__
if(kg->oiio && kg->oiio->tex_paths.size() > id) {
OIIO::TextureOpt options;
options.swrap = options.twrap = OIIO::TextureOpt::WrapPeriodic;
+#if 0
options.interpmode = OIIO::TextureOpt::InterpBilinear;
- options.mipmode = OIIO::TextureOpt::MipModeOneLevel;
+ options.mipmode = OIIO::TextureOpt::MipModeNoMIP;
+#else
+ if(fast_lookup) {
+ options.interpmode = OIIO::TextureOpt::InterpClosest;
+ options.mipmode = OIIO::TextureOpt::MipModeOneLevel;
+ }
+ else {
+ options.interpmode = OIIO::TextureOpt::InterpSmartBicubic;
+ options.mipmode = OIIO::TextureOpt::MipModeAniso;
+ }
+#endif
if(kg->oiio->tex_paths[id]) {
- bool success = kg->oiio->tex_sys->texture(kg->oiio->tex_paths[id], kg->oiio->tex_sys->get_perthread_info(), options, x, 1.0f - y, 0.0f, 0.0f, 0.0f, 0.0f, 3, (float*)&r);
+ bool success = kg->oiio->tex_sys->texture(kg->oiio->tex_paths[id], kg->oiio->tex_sys->get_perthread_info(), options, x, 1.0f - y, ds.dx, ds.dy, dt.dx, dt.dy, 3, (float*)&r);
if(!success) {
(void) kg->oiio->tex_sys->geterror();
}
@@ -64,28 +75,49 @@ ccl_device_inline float3 texco_remap_square(float3 co)
return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
}
-ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
+ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node)
{
uint id = node.y;
uint co_offset, out_offset, alpha_offset, srgb;
+ uint projection, dx_offset, dy_offset;
decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
+ decode_node_uchar4(node.w, &projection, &dx_offset, &dy_offset, NULL);
float3 co = stack_load_float3(stack, co_offset);
float2 tex_co;
uint use_alpha = stack_valid(alpha_offset);
- if(node.w == NODE_IMAGE_PROJ_SPHERE) {
+ if(projection == NODE_IMAGE_PROJ_SPHERE) {
co = texco_remap_square(co);
tex_co = map_to_sphere(co);
}
- else if(node.w == NODE_IMAGE_PROJ_TUBE) {
+ else if(projection == NODE_IMAGE_PROJ_TUBE) {
co = texco_remap_square(co);
tex_co = map_to_tube(co);
}
else {
tex_co = make_float2(co.x, co.y);
}
- float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha);
+
+ bool fast_lookup = path_flag & (PATH_RAY_DIFFUSE | PATH_RAY_SHADOW | PATH_RAY_DIFFUSE_ANCESTOR | PATH_RAY_VOLUME_SCATTER);
+
+ differential ds, dt;
+#ifdef __KERNEL_CPU__
+ if(stack_valid(dx_offset) && stack_valid(dy_offset)) {
+ float3 dx = stack_load_float3(stack, dx_offset);
+ float3 dy = stack_load_float3(stack, dy_offset);
+ ds.dx = fabsf(dx.x - tex_co.x);
+ ds.dy = fabsf(dy.x - tex_co.x);
+ dt.dx = fabsf(dx.y - tex_co.y);
+ dt.dy = fabsf(dy.y - tex_co.y);
+ }
+ else
+#endif
+ {
+ ds = differential_zero();
+ dt = differential_zero();
+ }
+ float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, ds, dt, srgb, use_alpha, fast_lookup);
if(stack_valid(out_offset))
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
@@ -173,20 +205,22 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
uint use_alpha = stack_valid(alpha_offset);
+ differential ds = differential_zero();
+ differential dt = differential_zero();
+
/* Map so that no textures are flipped, rotation is somewhat arbitrary. */
if(weight.x > 0.0f) {
float2 uv = make_float2((signed_N.x < 0.0f)? 1.0f - co.y: co.y, co.z);
- f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, ds, dt, srgb, use_alpha, false);
}
if(weight.y > 0.0f) {
float2 uv = make_float2((signed_N.y > 0.0f)? 1.0f - co.x: co.x, co.z);
- f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, ds, dt, srgb, use_alpha, false);
}
if(weight.z > 0.0f) {
float2 uv = make_float2((signed_N.z > 0.0f)? 1.0f - co.y: co.y, co.x);
- f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, ds, dt, srgb, use_alpha, false);
}
-
if(stack_valid(out_offset))
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
if(stack_valid(alpha_offset))
@@ -212,7 +246,7 @@ ccl_device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, floa
uv = direction_to_mirrorball(co);
uint use_alpha = stack_valid(alpha_offset);
- float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+ float4 f = svm_image_texture(kg, id, uv.x, uv.y, differential_zero(), differential_zero(), srgb, use_alpha, false);
if(stack_valid(out_offset))
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 08203163d1a..b25b26b8d91 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -304,6 +304,7 @@ void ShaderGraph::simplify(Scene *scene)
default_inputs(scene->shader_manager->use_osl());
clean(scene);
refine_bump_nodes();
+ add_differentials();
simplified = true;
}
@@ -843,6 +844,53 @@ void ShaderGraph::refine_bump_nodes()
}
}
+void ShaderGraph::add_differentials()
+{
+ /* we transverse the node graph looking for texture nodes, when we find them,
+ * we copy the sub-graph defined from "Vector"
+ * input to the inputs "Vector_dx" and "Vector_dy" */
+
+ foreach(ShaderNode *node, nodes) {
+ if(node->special_type == SHADER_SPECIAL_TYPE_IMAGE_SLOT && node->input("Vector")->link
+ && node->input("Vector_dx") && node->input("Vector_dy")) {
+ ShaderInput *vector_input = node->input("Vector");
+ ShaderNodeSet nodes_vector;
+
+ /* make 2 extra copies of the subgraph defined in Vector input */
+ ShaderNodeMap nodes_dx;
+ ShaderNodeMap nodes_dy;
+
+ /* find dependencies for the given input */
+ find_dependencies(nodes_vector, vector_input);
+
+ copy_nodes(nodes_vector, nodes_dx);
+ copy_nodes(nodes_vector, nodes_dy);
+
+ /* mark nodes to indicate they are used for differential computation, so
+ that any texture coordinates are shifted by dx/dy when sampling */
+ foreach(ShaderNode *node, nodes_vector)
+ node->bump = SHADER_BUMP_CENTER;
+ foreach(NodePair& pair, nodes_dx)
+ pair.second->bump = SHADER_BUMP_DX;
+ foreach(NodePair& pair, nodes_dy)
+ pair.second->bump = SHADER_BUMP_DY;
+
+ ShaderOutput *out = vector_input->link;
+ ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name());
+ ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name());
+
+ connect(out_dx, node->input("Vector_dx"));
+ connect(out_dy, node->input("Vector_dy"));
+
+ /* add generated nodes */
+ foreach(NodePair& pair, nodes_dx)
+ add(pair.second);
+ foreach(NodePair& pair, nodes_dy)
+ add(pair.second);
+ }
+ }
+}
+
void ShaderGraph::bump_from_displacement(bool use_object_space)
{
/* generate bump mapping automatically from displacement. bump mapping is
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 1d1701b30a2..eeb58a2721f 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -276,6 +276,7 @@ protected:
void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
void bump_from_displacement(bool use_object_space);
void refine_bump_nodes();
+ void add_differentials();
void default_inputs(bool do_osl);
void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 24096907c74..53547bbd6ce 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -240,6 +240,8 @@ NODE_DEFINE(ImageTextureNode)
SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f);
SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV);
+ SOCKET_IN_POINT(vector_dx, "Vector_dx", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_DX);
+ SOCKET_IN_POINT(vector_dy, "Vector_dy", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_DY);
SOCKET_OUT_COLOR(color, "Color");
SOCKET_OUT_FLOAT(alpha, "Alpha");
@@ -299,6 +301,8 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
ShaderInput *vector_in = input("Vector");
ShaderOutput *color_out = output("Color");
ShaderOutput *alpha_out = output("Alpha");
+ Shade
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list