diff options
-rw-r--r-- | intern/cycles/kernel/shaders/node_wireframe.osl | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_wireframe.h | 55 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 24 |
5 files changed, 80 insertions, 18 deletions
diff --git a/intern/cycles/kernel/shaders/node_wireframe.osl b/intern/cycles/kernel/shaders/node_wireframe.osl index 936e9bb5754..1ab0a6536eb 100644 --- a/intern/cycles/kernel/shaders/node_wireframe.osl +++ b/intern/cycles/kernel/shaders/node_wireframe.osl @@ -18,10 +18,21 @@ #include "oslutil.h" shader node_wireframe( + string bump_offset = "center", int use_pixel_size = 0, float Size = 0.01, output float Fac = 0.0) { Fac = wireframe("triangles", Size, use_pixel_size); + if (bump_offset == "dx") { + point dx = Dx(P); + P -= dx; + Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dx); + } + else if (bump_offset == "dy") { + point dy = Dy(P); + P -= dy; + Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dy); + } } diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 6a673d318f3..d59c9b9e61c 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -361,7 +361,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade break; #ifdef __EXTRA_NODES__ case NODE_WIREFRAME: - svm_node_wireframe(kg, sd, stack, node.y, node.z, node.w); + svm_node_wireframe(kg, sd, stack, node); break; case NODE_WAVELENGTH: svm_node_wavelength(sd, stack, node.y, node.z); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index a8d0da6ff39..7130b14a426 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -341,6 +341,12 @@ typedef enum NodeImageProjection { NODE_IMAGE_PROJ_TUBE = 3, } NodeImageProjection; +typedef enum NodeBumpOffset { + NODE_BUMP_OFFSET_CENTER, + NODE_BUMP_OFFSET_DX, + NODE_BUMP_OFFSET_DY, +} NodeBumpOffset; + typedef enum ShaderType { SHADER_TYPE_SURFACE, SHADER_TYPE_VOLUME, diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h index 660e6e2ca47..42fe3e8e429 100644 --- a/intern/cycles/kernel/svm/svm_wireframe.h +++ b/intern/cycles/kernel/svm/svm_wireframe.h @@ -34,16 +34,12 @@ CCL_NAMESPACE_BEGIN /* Wireframe Node */ -ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_size, uint out_fac, uint use_pixel_size) +ccl_device float wireframe(KernelGlobals *kg, + ShaderData *sd, + float size, + int pixel_size, + float3 *P) { - /* Input Data */ - float size = stack_load_float(stack, in_size); - int pixel_size = (int)use_pixel_size; - - /* Output */ - float f = 0.0f; - - /* Calculate wireframe */ #ifdef __HAIR__ if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE) #else @@ -55,7 +51,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta /* Triangles */ int np = 3; - + if(sd->type & PRIMITIVE_TRIANGLE) triangle_vertices(kg, sd->prim, Co); else @@ -66,7 +62,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta object_position_transform(kg, sd, &Co[1]); object_position_transform(kg, sd, &Co[2]); } - + if(pixel_size) { // Project the derivatives of P to the viewing plane defined // by I so we have a measure of how big is a pixel at this point @@ -75,24 +71,53 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta // Take the average of both axis' length pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f; } - + // Use half the width as the neighbor face will render the // other half. And take the square for fast comparison pixelwidth *= 0.5f * size; pixelwidth *= pixelwidth; for (int i = 0; i < np; i++) { int i2 = i ? i - 1 : np - 1; - float3 dir = sd->P - Co[i]; + float3 dir = *P - Co[i]; float3 edge = Co[i] - Co[i2]; float3 crs = cross(edge, dir); // At this point dot(crs, crs) / dot(edge, edge) is // the square of area / length(edge) == square of the // distance to the edge. if (dot(crs, crs) < (dot(edge, edge) * pixelwidth)) - f = 1.0f; + return 1.0f; } } - + return 0.0f; +} + +ccl_device void svm_node_wireframe(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint4 node) +{ + uint in_size = node.y; + uint out_fac = node.z; + uint use_pixel_size, bump_offset; + decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, NULL, NULL); + + /* Input Data */ + float size = stack_load_float(stack, in_size); + int pixel_size = (int)use_pixel_size; + + /* Calculate wireframe */ + float f = wireframe(kg, sd, size, pixel_size, &sd->P); + + /* TODO(sergey): Think of faster way to calculate derivatives. */ + if(bump_offset == NODE_BUMP_OFFSET_DX) { + float3 Px = sd->P - sd->dP.dx; + f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx); + } + else if (bump_offset == NODE_BUMP_OFFSET_DY) { + float3 Py = sd->P - sd->dP.dy; + f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy); + } + if (stack_valid(out_fac)) stack_store_float(stack, out_fac, f); } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index fa6ffffd9b4..7a39811cacd 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3577,14 +3577,34 @@ void WireframeNode::compile(SVMCompiler& compiler) { ShaderInput *size_in = input("Size"); ShaderOutput *fac_out = output("Fac"); - + NodeBumpOffset bump_offset = NODE_BUMP_OFFSET_CENTER; + if(bump == SHADER_BUMP_DX) { + bump_offset = NODE_BUMP_OFFSET_DX; + } + else if(bump == SHADER_BUMP_DY) { + bump_offset = NODE_BUMP_OFFSET_DY; + } compiler.stack_assign(size_in); compiler.stack_assign(fac_out); - compiler.add_node(NODE_WIREFRAME, size_in->stack_offset, fac_out->stack_offset, use_pixel_size); + compiler.add_node(NODE_WIREFRAME, + size_in->stack_offset, + fac_out->stack_offset, + compiler.encode_uchar4(use_pixel_size, + bump_offset, + 0, 0)); } void WireframeNode::compile(OSLCompiler& compiler) { + if(bump == SHADER_BUMP_DX) { + compiler.parameter("bump_offset", "dx"); + } + else if(bump == SHADER_BUMP_DY) { + compiler.parameter("bump_offset", "dy"); + } + else { + compiler.parameter("bump_offset", "center"); + } compiler.parameter("use_pixel_size", use_pixel_size); compiler.add(this, "node_wireframe"); } |