generated from taichi-dev/voxel-challenge
-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.py
91 lines (71 loc) · 3.01 KB
/
main.py
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
from scene import Scene
import taichi as ti
from taichi.math import *
scene = Scene(voxel_edges=0, exposure=2)
scene.set_floor(-0.85, (1.0, 1.0, 1.0))
scene.set_background_color((0.5, 0.5, 0.4))
scene.set_directional_light((1, 1, -1), 0.2, (1, 0.8, 0.6))
@ti.func
def create_block(pos, size, color, color_noise):
for I in ti.grouped(
ti.ndrange((pos[0], pos[0] + size[0]), (pos[1], pos[1] + size[1]),
(pos[2], pos[2] + size[2]))):
scene.set_voxel(I, 1, color + color_noise * ti.random())
@ti.func
def create_leaves(pos, radius, color):
for I in ti.grouped(
ti.ndrange((-radius, radius), (-radius, radius),
(-radius, +radius))):
f = I / radius
h = 0.5 - max(f[1], -0.5) * 0.5
d = vec2(f[0], f[2]).norm()
prob = max(0, 1 - d)**2 * h # xz mask
prob *= h # y mask
# noise
prob += ti.sin(f[0] * 5 + pos[0]) * 0.02
prob += ti.sin(f[1] * 9 + pos[1]) * 0.01
prob += ti.sin(f[2] * 10 + pos[2]) * 0.03
if prob < 0.1:
prob = 0.0
if ti.random() < prob:
scene.set_voxel(pos + I, 1, color + (ti.random() - 0.5) * 0.2)
@ti.func
def create_tree(pos, height, radius, color):
create_block(pos, ivec3(3, height - radius * 0.5, 3), vec3(0.7), vec3(0.3))
# Leaves
create_leaves(pos + ivec3(0, height, 0), radius, color)
# Ground
for i, j in ti.ndrange((-radius, radius), (-radius, radius)):
prob = max((radius - vec2(i, j).norm()) / radius, 0)
prob = prob * prob
if ti.random() < prob * prob:
scene.set_voxel(pos + ivec3(i, 1, j), 1,
color + ti.random() * vec3(0.1))
@ti.func
def make_fence(start, direction, length):
color = vec3(0.5, 0.3, 0.2)
create_block(start, direction * length + ivec3(3, 2, 3), color, vec3(0.1))
fence_dist = 3
for i in range(length // fence_dist + 1):
create_block(start + direction * i * fence_dist + ivec3(1, -3, 1),
ivec3(1, 5, 1), color, vec3(0))
@ti.kernel
def initialize_voxels():
for i in range(4):
create_block(ivec3(-60, -(i + 1)**2 - 40, -60),
ivec3(120, 2 * i + 1, 120),
vec3(0.5 - i * 0.1) * vec3(1.0, 0.8, 0.6),
vec3(0.05 * (3 - i)))
create_block(ivec3(-60, -40, -60), ivec3(120, 1, 120), vec3(0.3, 0.2, 0.1),
vec3(0.01))
create_tree(ivec3(-20, -40, 25), 65, 35, vec3(1.0, 0.3, 0.15))
create_tree(ivec3(45, -40, -45), 15, 10, vec3(0.8, 0.4, 0.1))
create_tree(ivec3(20, -40, 0), 45, 25, vec3(1.0, 0.4, 0.1))
create_tree(ivec3(30, -40, -20), 25, 15, vec3(1.0, 0.4, 0.1))
create_tree(ivec3(30, -40, 30), 45, 25, vec3(1.0, 0.4, 0.1))
make_fence(ivec3(-58, -36, -58), ivec3(1, 0, 0), 115)
make_fence(ivec3(-59, -36, 57), ivec3(1, 0, 0), 115)
make_fence(ivec3(-59, -36, -58), ivec3(0, 0, 1), 115)
make_fence(ivec3(57, -36, -58), ivec3(0, 0, 1), 115)
initialize_voxels()
scene.finish()