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/kernel/shaders/node_wireframe.osl11
-rw-r--r--intern/cycles/kernel/svm/svm.h2
-rw-r--r--intern/cycles/kernel/svm/svm_types.h6
-rw-r--r--intern/cycles/kernel/svm/svm_wireframe.h55
-rw-r--r--intern/cycles/render/nodes.cpp24
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");
}