-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSignedDistanceOperations.hlsl
138 lines (123 loc) · 3.4 KB
/
SignedDistanceOperations.hlsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifndef SIGNED_DISTANCE_OPERATIONS
#define SIGNED_DISTANCE_OPERATIONS
// References:
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
// http://mercury.sexy/hg_sdf/
// GLSL mod(x, y) -> x - y * floor(x / y)
// HLSL fmod(x, y) -> x - y * trunc(x / y)
// In GLSL the output sign depends on the sign of y, in HLSL the sign depends on x.
float mod( float x, float y )
{
return x - y * floor(x / y);
}
// Round a shape.
// Subtracts some distance (jumping to a different isosurface).
// If you want to preserve the overal volume of the shape, shrink the source primitive by the same amount you are rounding it.
// r: Radius.
float opRound( float d, float r )
{
return d - r;
}
// Carve the interior or give thickness to primitive.
// Use it multiple times to create concentric layers.
// t: Thickness.
float opOnion( float d, float t )
{
return abs(d) - t;
}
// Twist the point across the x axis.
// k: Twist factor.
float3 opTwistX( float3 p, float k )
{
float c = cos(k * p.x);
float s = sin(k * p.x);
float3x3 m = float3x3(1, 0, 0, 0, c, -s, 0, s, c);
float3 q = mul(m, p);
return q;
}
// Twist the point across the y axis.
// k: Twist factor.
float3 opTwistY( float3 p, float k )
{
float c = cos(k * p.y);
float s = sin(k * p.y);
float3x3 m = float3x3(c, 0, s, 0, 1, 0, -s, 0, c);
float3 q = mul(m, p);
return q;
}
// Twist the point across the z axis.
// k: Twist factor.
float3 opTwistZ( float3 p, float k )
{
float c = cos(k * p.z);
float s = sin(k * p.z);
float3x3 m = float3x3(c, -s, 0, s, c, 0, 0, 0, 1);
float3 q = mul(m, p);
return q;
}
// Repeat space along one axis and returns the cell (optional).
// float c = pMod1(p.x, 1);
// c: Cell.
float opMod1( inout float p, float size )
{
float halfsize = size * 0.5;
float c = floor((p + halfsize) / size);
p = fmod(p + halfsize, size) - halfsize;
p = fmod(-p + halfsize, size) - halfsize;
return c;
}
// Repeat space along one positive axis and returns the cell (optional).
// float c = pModPositive1(p.x, 1);
// c: Cell.
float opModPositive1( inout float p, float size )
{
float halfsize = size * 0.5;
float c = floor((p + halfsize) / size);
if( p >= 0 )
{
p = mod(p + halfsize, size) - halfsize;
}
return c;
}
// Repeat space along one axis from start to end cells and returns the cell (optional).
// float c = pModInterval1(p.x, 1, 0, 10);
// c: Cell.
float opModInterval1( inout float p, float size, int start, int end )
{
float halfsize = size * 0.5;
float c = floor((p + halfsize) / size);
p = mod(p + halfsize, size) - halfsize;
if( c > end )
{
p += size * (c - end);
c = end;
}
if( c < start )
{
p += size * (c - start);
c = start;
}
return c;
}
// Repeat space along two axes and returns the cell (optional).
// float2 c = pMod2(p.x, p.y, 1);
// c: Cell.
float2 opMod2( inout float p1, inout float p2, float2 size )
{
float2 c = floor((float2(p1, p2) + size * 0.5) / size);
p1 = mod(p1 + size.x * 0.5, size.x) - size.x * 0.5;
p2 = mod(p2 + size.y * 0.5, size.y) - size.y * 0.5;
return c;
}
// Repeat space along three axes and returns the cell (optional).
// float3 c = pMod3(p.x, p.y, p.z, 1);
// c: Cell.
float3 opMod3( inout float p1, inout float p2, inout float p3, float3 size )
{
float3 c = floor((float3(p1, p2, p3) + size * 0.5) / size);
p1 = mod(p1 + size.x * 0.5, size.x) - size.x * 0.5;
p2 = mod(p2 + size.y * 0.5, size.y) - size.y * 0.5;
p3 = mod(p3 + size.z * 0.5, size.z) - size.z * 0.5;
return c;
}
#endif