@ti.func
def normal(sdf_func: ti.template(), obj: SDFObject, p: vec3) -> vec3:
pos, scale = calc_pos_scale(obj, p)
n, h = vec3(0), 0.5773 * 0.005
# from https://iquilezles.org/articles/normalsSDF/
for i in ti.static(range(4)):
e = 2.0*vec3((((i+3) >> 1) & 1), ((i >> 1) & 1), (i & 1))-1.0
n += e*sdf_func(pos+e*h, scale)
return normalize(n)
@ti.func
def calc_normal_1(obj: SDFObject, p: vec3) -> vec3:
n = vec3(0)
if obj.type == SHAPE.SPHERE:
n = normal(SHAPE_FUNC[SHAPE.SPHERE], obj, p)
elif obj.type == SHAPE.CYLINDER:
n = normal(SHAPE_FUNC[SHAPE.CYLINDER], obj, p)
elif obj.type == SHAPE.BOX:
n = normal(SHAPE_FUNC[SHAPE.BOX], obj, p)
elif obj.type == SHAPE.CYLINDER:
n = normal(SHAPE_FUNC[SHAPE.CYLINDER], obj, p)
# n = normal(SHAPE_FUNC[obj.type], obj, p)
return n
@ti.func
def calc_normal_2(obj: SDFObject, p: vec3) -> vec3:
n = vec3(0)
for shape in ti.static(SHAPES):
if obj.type == shape:
n = normal(SHAPE_FUNC[shape], obj, p)
# break
return n
### 要是有优雅的解决方案就好了