Blender V5.0
wireframe.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
2 * SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Adapted code from Open Shading Language. */
7
8#pragma once
9
11#include "kernel/geom/object.h"
13#include "kernel/svm/util.h"
15#include "util/math_base.h"
16
18
19/* Wireframe Node */
20
22 ccl_private ShaderData *sd,
23 const differential3 dP,
24 const float size,
25 const int pixel_size,
27{
28#if defined(__HAIR__) || defined(__POINTCLOUD__)
29 if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_TRIANGLE)
30#else
31 if (sd->prim != PRIM_NONE)
32#endif
33 {
34 float3 Co[3];
35 float pixelwidth = 1.0f;
36
37 /* Triangles */
38 const int np = 3;
39
40 if (sd->type & PRIMITIVE_MOTION) {
41 motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, Co);
42 }
43 else {
44 triangle_vertices(kg, sd->prim, Co);
45 }
46
47 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
48 object_position_transform(kg, sd, &Co[0]);
49 object_position_transform(kg, sd, &Co[1]);
50 object_position_transform(kg, sd, &Co[2]);
51 }
52
53 if (pixel_size) {
54 // Project the derivatives of P to the viewing plane defined
55 // by I so we have a measure of how big is a pixel at this point
56 const float pixelwidth_x = len(dP.dx - dot(dP.dx, sd->wi) * sd->wi);
57 const float pixelwidth_y = len(dP.dy - dot(dP.dy, sd->wi) * sd->wi);
58 // Take the average of both axis' length
59 pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f;
60 }
61
62 // Use half the width as the neighbor face will render the
63 // other half. And take the square for fast comparison
64 pixelwidth *= 0.5f * size;
65 pixelwidth *= pixelwidth;
66 for (int i = 0; i < np; i++) {
67 const int i2 = i ? i - 1 : np - 1;
68 const float3 dir = *P - Co[i];
69 const float3 edge = Co[i] - Co[i2];
70 const float3 crs = cross(edge, dir);
71 // At this point dot(crs, crs) / dot(edge, edge) is
72 // the square of area / length(edge) == square of the
73 // distance to the edge.
74 if (dot(crs, crs) < (dot(edge, edge) * pixelwidth)) {
75 return 1.0f;
76 }
77 }
78 }
79 return 0.0f;
80}
81
83 ccl_private ShaderData *sd,
84 ccl_private float *stack,
85 const uint4 node)
86{
87 const uint in_size = node.y;
88 const float bump_filter_width = __uint_as_float(node.z);
89 uint use_pixel_size;
90 uint bump_offset;
91 uint out_fac;
92 svm_unpack_node_uchar3(node.w, &use_pixel_size, &bump_offset, &out_fac);
93
94 /* Input Data */
95 const float size = stack_load_float(stack, in_size);
96 const int pixel_size = (int)use_pixel_size;
97
98 /* Calculate wireframe */
99 const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
100
101 float3 P = sd->P;
102 if (bump_offset == NODE_BUMP_OFFSET_DX) {
103 P += dP.dx * bump_filter_width;
104 }
105 else if (bump_offset == NODE_BUMP_OFFSET_DY) {
106 P += dP.dy * bump_filter_width;
107 }
108
109 const float f = wireframe(kg, sd, dP, size, pixel_size, &P);
110
111 if (stack_valid(out_fac)) {
112 stack_store_float(stack, out_fac, f);
113 }
114}
115
unsigned int uint
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
ccl_device_inline float stack_load_float(const ccl_private float *stack, const uint a)
ccl_device_inline void stack_store_float(ccl_private float *stack, const uint a, const float f)
ccl_device_forceinline void svm_unpack_node_uchar3(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z)
ccl_device_inline bool stack_valid(const uint a)
#define PRIM_NONE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
#define __uint_as_float(x)
ccl_device_forceinline differential3 differential_from_compact(const float3 D, const float dD)
ccl_device_inline void triangle_vertices(KernelGlobals kg, const int prim, float3 P[3])
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
ccl_device_inline void object_position_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private T *P)
@ NODE_BUMP_OFFSET_DY
@ NODE_BUMP_OFFSET_DX
@ PRIMITIVE_MOTION
@ PRIMITIVE_TRIANGLE
@ SD_OBJECT_TRANSFORM_APPLIED
ccl_device_inline void motion_triangle_vertices(KernelGlobals kg, const int object, const uint3 tri_vindex, const int numsteps, const int numverts, const int step, const float t, float3 verts[3])
uint y
Definition types_uint4.h:13
uint z
Definition types_uint4.h:13
uint w
Definition types_uint4.h:13
i
Definition text_draw.cc:230
uint len
CCL_NAMESPACE_BEGIN ccl_device_inline float wireframe(KernelGlobals kg, ccl_private ShaderData *sd, const differential3 dP, const float size, const int pixel_size, ccl_private float3 *P)
Definition wireframe.h:21
ccl_device_noinline void svm_node_wireframe(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, const uint4 node)
Definition wireframe.h:82