缘起
再次感谢Taichi给我这次水博客的机会
最初是在第 0 期 Taichi Open Office Hour听说了这个活动(刚才检查这个链接才发现自己好像有抽中了奖,可邮箱里没有🫠,upd:收到了,5月5日中午),想着五一反正也是封校,不如搞点艺术
寻找思路的发现
首先是跑了给的几个example,然后发现example6.py中提到了pinterest,这下不思路来了,遂在各个站中找灵感。
我的作品是由油管上这个视频启发而来的,可以说是基本上把它的作品写在了代码里,希望不要判我作弊😢
当然,这个过程中我还找到了一个非常神奇的网站artstation,里面作品档次高太多了,这里特别展示一位大佬Mari K的一套作品(我看大佬是允许转载的),这不比《黑客帝国4》高多了
作品思路
所有颜色我都是从日本传统色里取的,然后转成了实数,不得不说最后结果有些失真
本次作品是有码量限制的,所以用了大量的分号压行,也没有地方写注释,唯一可以判别的是靠颜色的标注
整个作品还是比较方正的,所以先写个函数用来放置长方体:
@ti.func
def set_blocks(st, ed, kd, color):
for I in ti.grouped(ti.ndrange((st[0], ed[0]), (st[1], ed[1]),(st[2], ed[2]))):
scene.set_voxel(I, kd, color)
而灯这一步比较复杂,便专门写了一个函数来搭建
@ti.func
def set_lamp(x,y,z):
col_pil3,col_s,col_l=vec3(0.211,0.211,0.211),vec3(0.793,0.105,0.270),vec3(0.980,0.883,0.316)
set_blocks(vec3(x,y-7,z),vec3(x+1,y,z+1),1,col_pil3);set_blocks(vec3(x-1,y-8,z-1),vec3(x+2,y-7,z+2),1,col_s)
set_blocks(vec3(x-2,y-9,z-1),vec3(x+3,y-8,z+2),2,col_l);set_blocks(vec3(x-1,y-9,z-2),vec3(x+2,y-8,z+3),2,col_l)
set_blocks(vec3(x-3,y-14,z-1),vec3(x+4,y-9,z+2),1,col_s);set_blocks(vec3(x-1,y-14,z-3),vec3(x+2,y-9,z+4),1,col_s)
set_blocks(vec3(x-2,y-14,z-2),vec3(x+3,y-9,z+3),1,col_s);set_blocks(vec3(x-3,y-11,z-1),vec3(x+4,y-10,z+2),2,col_l)
set_blocks(vec3(x-1,y-11,z-3),vec3(x+2,y-10,z+4),2,col_l);set_blocks(vec3(x-2,y-11,z-2),vec3(x+3,y-10,z+3),2,col_l)
set_blocks(vec3(x-3,y-13,z-1),vec3(x+4,y-12,z+2),2,col_l);set_blocks(vec3(x-1,y-13,z-3),vec3(x+2,y-12,z+4),2,col_l)
set_blocks(vec3(x-2,y-13,z-2),vec3(x+3,y-12,z+3),2,col_l);set_blocks(vec3(x-1,y-16,z-1),vec3(x+2,y-15,z+2),1,col_s)
set_blocks(vec3(x-2,y-15,z-1),vec3(x+3,y-14,z+2),2,col_l);set_blocks(vec3(x-1,y-15,z-2),vec3(x+2,y-14,z+3),2,col_l)
set_blocks(vec3(x,y-19,z),vec3(x+1,y-15,z+1),2,vec3(1,1,1))
这一部分建好了基座和栅栏
col_ground,col_fence,col_pil2=vec3(0.723,0.532,0.488),vec3(0.621,0.207,0.227),vec3(0.555, 0.207, 0.289)
set_blocks(vec3(-37,-1,-37),vec3(37,0,37),1,col_ground);set_blocks(vec3(-7,-3,38),vec3(7,-2,41),1,col_ground)
for i in ti.static(range(-32,32,6)):set_blocks(vec3(-37,-1,i),vec3(37,0,i+1),0,col_ground)
set_blocks(vec3(33,2,-36),vec3(35,4,36),1,col_fence);set_blocks(vec3(33,7,-36),vec3(35,9,36),1,col_fence)
for i in ti.static(range(-36,36,4)):set_blocks(vec3(33,2,i),vec3(34,7,i+1),1,col_fence)
set_blocks(vec3(-35,2,-36),vec3(-33,4,36),1,col_fence);set_blocks(vec3(-35,7,-36),vec3(-33,9,36),1,col_fence)
for i in ti.static(range(-36,36,4)):set_blocks(vec3(-34,2,i),vec3(-33,7,i+1),1,col_fence)
set_blocks(vec3(-36,2,-35),vec3(36,4,-33),1,col_fence);set_blocks(vec3(-36,7,-35),vec3(36,9,-33),1,col_fence)
for i in ti.static(range(-36,36,4)):set_blocks(vec3(i,2,-34),vec3(i+1,7,-33),1,col_fence)
set_blocks(vec3(-36,2,33),vec3(36,4,35),1,col_fence);set_blocks(vec3(-36,7,33),vec3(36,9,35),1,col_fence)
for i in ti.static(range(-36,36,4)):set_blocks(vec3(i,2,33),vec3(i+1,7,34),1,col_fence)
set_blocks(vec3(-15,2,33),vec3(15,9,35),0,col_fence);set_blocks(vec3(-1,57,-1),vec3(1,58,1),2,vec3(1,1,1))
这一部分则搭好了房屋框架
col_pil1,col_wall,col_top=vec3(0.336,0.246,0.180),vec3(0.840, 0.723, 0.555),vec3(0.934,0.730,0.141)
set_blocks(vec3(33,-4,33),vec3(36,9,36),1,col_pil1);set_blocks(vec3(33,-4,-36),vec3(36,9,-33),1,col_pil1)
set_blocks(vec3(-36,-4,33),vec3(-33,9,36),1,col_pil1);set_blocks(vec3(-36,-4,-36),vec3(-33,9,-33),1,col_pil1)
set_blocks(vec3(-18,0,33),vec3(-15,9,36),1,col_pil1);set_blocks(vec3(15,0,33),vec3(18,9,36),1,col_pil1)
set_blocks(vec3(-18,0,-18),vec3(18,38,18),1,col_wall);set_blocks(vec3(-17,0,-17),vec3(17,38,17),0,col_wall)
col_gunjo=vec3(0.316,0.656,0.863);set_blocks(vec3(-18,10,-7),vec3(18,25,7),0,col_wall)
set_blocks(vec3(16,0,16),vec3(20,38,20),1,col_pil2);set_blocks(vec3(-20,0,16),vec3(-16,38,20),1,col_pil2)
set_blocks(vec3(16,0,-20),vec3(20,38,-16),1,col_pil2);set_blocks(vec3(-20,0,-20),vec3(-20,38,-20),1,col_pil2)
set_blocks(vec3(7,0,16),vec3(11,38,20),1,col_pil2);set_blocks(vec3(-11,0,16),vec3(-7,38,20),1,col_pil2)
set_blocks(vec3(7,0,-20),vec3(11,38,-16),1,col_pil2);set_blocks(vec3(-11,0,-20),vec3(-7,38,-16),1,col_pil2)
set_blocks(vec3(16,0,7),vec3(20,38,11),1,col_pil2);set_blocks(vec3(16,0,-11),vec3(20,38,-7),1,col_pil2)
set_blocks(vec3(-20,0,7),vec3(-16,38,11),1,col_pil2);set_blocks(vec3(-20,0,-11),vec3(-16,38,-7),1,col_pil2)
set_blocks(vec3(-19,25,-19),vec3(19,28,19),1,col_pil2);set_blocks(vec3(-16,25,-16),vec3(16,28,16),0,col_pil2)
set_blocks(vec3(-19,7,-19),vec3(19,10,19),1,col_pil2);set_blocks(vec3(-16,7,-16),vec3(16,10,16),0,col_pil2set_blocks(vec3(-7,0,-20),vec3(7,25,20),0,vec3(0.840, 0.723, 0.555))
for i in ti.static(range(-18,18,7)):
set_blocks(vec3(i,35,-28),vec3(i+3,38,28),1,col_pil2);set_blocks(vec3(-28,35,i),vec3(28,38,i+3),1,col_pil2)
for i in ti.static(range(2,7,2)):
set_blocks(vec3(17,10,i-1),vec3(18,25,i),1,col_pil2);set_blocks(vec3(17,10,-i),vec3(18,25,-i+1),1,col_pil2)
set_blocks(vec3(-18,10,i-1),vec3(-17,25,i),1,col_pil2);set_blocks(vec3(-18,10,-i),vec3(-17,25,-i+1),1,col_pil2)
for i in ti.static(range(12,25,4)):
set_blocks(vec3(18,i,-7),vec3(19,i+2,7),1,col_pil2);set_blocks(vec3(-19,i,-7),vec3(-18,i+2,7),1,col_pil2)
屋顶是整个神社部分最复杂的地方:先用一个正金字塔和倒金字塔组合,在加上突出的棱(有趣的是这里的颜色就是群青(gunjo,#51a8dd))
for i in ti.static(range(0,3)):
set_blocks(vec3(-(25+i*3),38+i,-(25+i*3)),vec3(25+i*3,39+i,25+i*3),1,col_gunjo)
for i in ti.static(range(0,6)):
set_blocks(vec3(-(35-i*3),41+i,-(35-i*3)),vec3(35-i*3,42+i,35-i*3),1,col_gunjo)
set_blocks(vec3((32-i*3),41+i,(32-i*3)),vec3((35-i*3),43+i,(35-i*3)),1,col_gunjo)
set_blocks(vec3(-(35-i*3),41+i,(32-i*3)),vec3(-(32-i*3),43+i,(35-i*3)),1,col_gunjo)
set_blocks(vec3((32-i*3),41+i,-(35-i*3)),vec3((35-i*3),43+i,-(32-i*3)),1,col_gunjo)
set_blocks(vec3(-(35-i*3),41+i,-(35-i*3)),vec3(-(32-i*3),43+i,-(32-i*3)),1,col_gunjo)
for j in ti.static(range(-13,13,8)):
set_blocks(vec3(j,41+i,(34-i*3)),vec3(j+2,43+i,(37-i*3)),1,col_gunjo)
set_blocks(vec3(j,41+i,-(37-i*3)),vec3(j+2,43+i,-(34-i*3)),1,col_gunjo)
set_blocks(vec3((34-i*3),41+i,j),vec3((37-i*3),43+i,j+2),1,col_gunjo)
set_blocks(vec3(-(37-i*3),41+i,j),vec3(-(34-i*3),43+i,j+2),1,col_gunjo)
for i in ti.static(range(0,4)):
set_blocks(vec3((33+i),41+i,(33+i)),vec3((35+i),43+i,(35+i)),1,col_gunjo)
set_blocks(vec3(-(35+i),41+i,(33+i)),vec3(-(33+i),43+i,(35+i)),1,col_gunjo)
set_blocks(vec3((33+i),41+i,-(35+i)),vec3((35+i),43+i,-(33+i)),1,col_gunjo)
set_blocks(vec3(-(35+i),41+i,-(35+i)),vec3(-(33+i),43+i,-(33+i)),1,col_gunjo)
加上顶上的部件,挂上灯
set_blocks(vec3(-1,47,-1),vec3(1,57,1),1,col_top);set_blocks(vec3(-5,47,-5),vec3(5,48,5),1,col_top)
set_blocks(vec3(-2,49,-2),vec3(2,50,2),1,col_top);set_blocks(vec3(-2,51,-2),vec3(2,52,2),1,col_top)
set_blocks(vec3(-2,54,-1),vec3(2,56,1),1,col_top);set_blocks(vec3(-1,54,-2),vec3(1,56,2),1,col_top)
set_lamp(31,41,31);set_lamp(-31,41,31);set_lamp(31,41,-31);set_lamp(-31,41,-31)
再加上一个鸟居
col_torii,col_black=vec3(0.938,0.254,0.332),vec3(0.043,0.063,0.074)
set_blocks(vec3(-20,-4,60),vec3(-18,45,62),1,col_torii);set_blocks(vec3(18,-4,60),vec3(20,45,62),1,col_torii)
set_blocks(vec3(-25,38,60),vec3(25,40,62),1,col_torii);set_blocks(vec3(-30,45,60),vec3(30,47,62),1,col_torii)
set_blocks(vec3(-32,47,60),vec3(32,48,62),1,col_black);set_blocks(vec3(-34,48,60),vec3(34,49,62),1,col_black)
set_blocks(vec3(-2,40,60),vec3(2,45,62),1,col_torii)
场景设置如下
scene = Scene(voxel_edges=0, exposure=1.2);scene.set_floor(-0.05, (0.957, 0.586, 0.664))
scene.set_background_color((0.942, 0.578, 0.512));scene.set_directional_light((1, 1, 1), 0.2, (1, 0.8, 0.6))
Repo 最后还有几行的余地,等我再次兴起,看看还能添加点什么
作品成果图
遇到的问题
首先是我把Taichi升级到v1.0.1之后直接显示Vulkan无法分配显存,回滚到v1.0.0便没有这个问题了 Upd:已经有issue了
[Taichi] version 1.0.1, llvm 10.0.0, commit 1c3619d9, win, python 3.9.7
[Taichi] Starting on arch=vulkan
[I 05/02/22 21:51:00.086 18096] [D:/a/taichi/taichi/taichi/backends/vulkan/vulkan_device_creator.cpp:pick_physical_device@363] Found Vulkan Device 0 (NVIDIA GeForce GTX 1060)
[I 05/02/22 21:51:00.087 18096] [D:/a/taichi/taichi/taichi/backends/vulkan/vulkan_device_creator.cpp:pick_physical_device@363] Found Vulkan Device 1 (Intel(R) UHD Graphics 620)
[I 05/02/22 21:51:00.089 18096] [D:/a/taichi/taichi/taichi/backends/vulkan/vulkan_device_creator.cpp:create_logical_device@431] Vulkan Device "NVIDIA GeForce GTX 1060" supports Vulkan 0 version 1.3.194
Assertion failed: m_VulkanFunctions.vkGetDeviceBufferMemoryRequirements != nullptr, file D:/a/taichi/taichi/external/VulkanMemoryAllocator/include\vk_mem_alloc.h, line 14440
齐次我在运行的时候Vulkan是识别了两张显卡,可它偏要用我的核显去跑🫥,应该是有办法设置的,可是这场比赛明显不允许