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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#ifndef __CUSTOM30_INC
#define __CUSTOM30_INC
#include "globals.cginc"
#include "quilez.cginc"
#include "interpolators.cginc"
#if defined(_CUSTOM30)
#define CUSTOM30_MAX_STEPS 30
struct Custom30Output {
float3 objPos;
float3 normal;
float depth;
};
float3 GetFragToOrigin(v2f i) {
// Vector from fragment to origin
return float3(-1, 1, 1) * (i.color * 2.0f - 1.0f) / i.color.a;
}
float cut_with_box(float3 p, float d, float3 box_size) {
float2 pp_xy = p.xy;
float2 pp_xz = p.xz;
float2 pp_yz = p.yz;
// Rotate by 45 degrees
float c = 0.70710678;
float s = 0.70710678;
pp_xy = float2(c * p.x - s * p.y, s * p.x + c * p.y);
d = max(d, distance_from_box(float3(pp_xy, p.z), box_size));
pp_xz = float2(c * p.x - s * p.z, s * p.x + c * p.z);
d = max(d, distance_from_box(float3(pp_xz, p.y), box_size));
pp_yz = float2(c * p.y - s * p.z, s * p.y + c * p.z);
d = max(d, distance_from_box(float3(pp_yz, p.x), box_size));
return d;
}
#if defined(_CUSTOM30_BASICCUBE)
float BasicCube_map(float3 p) {
float box_d = distance_from_box_frame(p, .995, .15);
float core_d = distance_from_box(p, 0.95);
float d = min(box_d, core_d);
d = cut_with_box(p, d, 1.3);
return d;
}
float3 BasicCube_normal(float3 p) {
float epsilon = 1E-3;
float center_d = BasicCube_map(p);
float3 n = float3(
BasicCube_map(p + float3(epsilon, 0, 0)) - center_d,
BasicCube_map(p + float3(0, epsilon, 0)) - center_d,
BasicCube_map(p + float3(0, 0, epsilon)) - center_d);
return normalize(n);
}
Custom30Output BasicCube(v2f i) {
float3 objSpaceCameraPos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1.0));
float3 frag_to_origin = GetFragToOrigin(i);
float3 ro = -frag_to_origin;
float3 rd = normalize(i.objPos - objSpaceCameraPos);
float d;
float d_acc = 0;
float epsilon = 5E-3;
// 1.73... = sqrt(3)
// our cube has an edge length of 2, so mult by 2
float max_d = 1.73205081f * 2.0f;
[loop]
for (uint ii = 0; ii < CUSTOM30_MAX_STEPS; ++ii) {
float3 p = ro + rd * d_acc;
d = BasicCube_map(p);
d_acc += d;
if (d < epsilon) break;
if (d_acc > max_d) break;
}
Custom30Output o;
clip(epsilon - d);
float3 objPos = ro + rd * d_acc;
o.objPos = objPos;
// Transform from SDF space back to object space
float3 objSpacePos = objPos + (i.objPos + frag_to_origin);
float4 clipPos = UnityObjectToClipPos(objSpacePos);
o.depth = clipPos.z / clipPos.w;
o.normal = BasicCube_normal(objPos);
return o;
}
#endif
#if defined(_CUSTOM30_BASICWEDGE)
float BasicWedge_map(float3 p) {
float box_d = distance_from_box(p, float3(1, 1, 1));
float cut_plane_d = distance_from_plane(p - float3(0, 0, 0), -normalize(float3(1, 0, 1)), 0);
float d = op_sub(box_d, cut_plane_d);
//d = cut_with_box(p, d, 1.3);
return d;
}
float3 BasicWedge_normal(float3 p) {
float epsilon = 1E-3;
float center_d = BasicWedge_map(p);
float3 n = float3(
BasicWedge_map(p + float3(epsilon, 0, 0)) - center_d,
BasicWedge_map(p + float3(0, epsilon, 0)) - center_d,
BasicWedge_map(p + float3(0, 0, epsilon)) - center_d);
return normalize(n);
}
Custom30Output BasicWedge(v2f i) {
float3 objSpaceCameraPos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1.0));
float3 frag_to_origin = GetFragToOrigin(i);
float3 ro = -frag_to_origin;
float3 rd = normalize(i.objPos - objSpaceCameraPos);
float d;
float d_acc = 0;
float epsilon = 5E-3;
// 1.73... = sqrt(3)
// our cube has an edge length of 2, so mult by 2
float max_d = 1.73205081f * 2.0f;
[loop]
for (uint ii = 0; ii < CUSTOM30_MAX_STEPS; ++ii) {
float3 p = ro + rd * d_acc;
d = BasicWedge_map(p);
d_acc += d;
if (d < epsilon) break;
if (d_acc > max_d) break;
}
Custom30Output o;
clip(epsilon - d);
float3 objPos = ro + rd * d_acc;
o.objPos = objPos;
// Transform from SDF space back to object space
float3 objSpacePos = objPos + (i.objPos + frag_to_origin);
float4 clipPos = UnityObjectToClipPos(objSpacePos);
o.depth = clipPos.z / clipPos.w;
o.normal = BasicWedge_normal(objPos);
return o;
}
#endif
#endif // _CUSTOM30
#endif // __CUSTOM30_INC
|