作业描述
给之前的墨戏引擎包了个更好的皮,现在可实时调参,保存图片了。基本把 GGUI 的所有组件都用上了。可惜没找到能方便调用笔压的方法。
效果展示
其实感觉交这个作业有点尴尬,毕竟之前是当小作业交,大作业改动不大,但是不交又感觉亏了(虽然已经中奖拿了好多礼品😂)。
或许你第一次提交的moxi代码还有吗?最近在学习格子玻尔兹曼,想参考一下,组件太多,阅读起来不方便!!
第一次的代码也挺乱的,不过给你参考吧,要用0.8.5或之前的版本运行,主要是后面的版本不支持taichi_glsl,要把里面对glsl的依赖改了
import taichi as ti
import matplotlib.image as mpig
import taichi_glsl as tg
ti.init(arch=ti.cuda)
res = 512
brushRadius = 0.03
RGB = ti.types.vector(3, float)
RGBA = ti.types.struct(rgb=RGB, a=float)
_Pigment_Surface_c = RGB.field(shape=(res, res))
_Pigment_Surface_a=ti.field(dtype=float,shape=(res,res))
_Pigment_flow_c = RGB.field(shape=(res, res))
_Pigment_flow_a=ti.field(dtype=float,shape=(res,res))
_Pigment_flow_star_c = RGB.field(shape=(res, res))
_Pigment_flow_star_a=ti.field(dtype=float,shape=(res,res))
_Water_Surface = ti.field(float, shape=(res, res))
_Flow = ti.Vector.field(9, dtype=float, shape=(res, res))
_FlowNext = ti.Vector.field(9, dtype=float, shape=(res, res))
_Feq = ti.Vector.field(9, dtype=float, shape=(res, res))
_kapar = ti.Vector.field(9, dtype=float, shape=(res, res))
# _Fixture = ti.Vector.field(4, dtype=float, shape=(res, res))
_BackGroundLayer = ti.Vector.field(3, dtype=float, shape=(res, res))
_FrameBuffer = ti.Vector.field(3, dtype=float, shape=(res, res))
cursor = ti.field(float, shape=2)
currentColor = RGBA.field(shape=2)
currentColor[0] = RGBA(rgb=[0.0, 0.4, 0.25], a=0.5)
currentColor[1] = RGBA(rgb=[1.0, 1.0, 0.2], a=0.5)
_paper = ti.field(dtype=float, shape=(res, res))
_fibers = ti.field(dtype=float, shape=(res, res))
_rou = ti.field(float, shape=(res, res))
_sigma = ti.field(float, shape=(res, res))
_paper.from_numpy(mpig.imread("paper_512_2.png")[:, :, 0])
_fibers.from_numpy(mpig.imread("fibers_512_3.png")[:, :, 0])
_ispinning = ti.field(dtype=int, shape=(res, res))
_kar = ti.field(dtype=float, shape=(res, res))
_FlowVelocity = ti.Vector.field(2, dtype=float, shape=(res, res))
e = ti.Vector.field(2, dtype=int, shape=9)
e[0] = ti.Vector([0, 0])
e[1] = ti.Vector([0, 1])
e[2] = ti.Vector([-1, 0])
e[3] = ti.Vector([0, -1])
e[4] = ti.Vector([1, 0])
e[5] = ti.Vector([1, 1])
e[6] = ti.Vector([-1, 1])
e[7] = ti.Vector([-1, -1])
e[8] = ti.Vector([1, -1])
k = (0, 3, 4, 1, 2, 7, 8, 5, 6)
w = (4.0/9.0, 1.0/9.0, 1.0/9.0, 1.0/9.0, 1.0 /
9.0, 1.0/36.0, 1.0/36.0, 1.0/36.0, 1.0/36.0)
# if(True):
# w = (4.0/9.0, 0.95/9.0, 1.0/9.0, 1.05/9.0, 1.0 /
# 9.0, 1.0/36.0, 1.0/36.0, 1.0/36.0, 1.0/36.0)
q1 = -0.05
q2 = 0.9
q3 = 0.9
@ti.kernel
def ini_sigma():
for P in ti.grouped(_sigma):
_sigma[P] = q1+q2*_fibers[P]+q3*_paper[P]
@ti.kernel
def get_ispinning():
for P in ti.grouped(_ispinning):
if (_rou[P] == 0 and
_rou[P+e[1]] < _sigma[P+e[1]] and
_rou[P+e[2]] < _sigma[P+e[2]] and
_rou[P+e[3]] < _sigma[P+e[3]] and
_rou[P+e[4]] < _sigma[P+e[4]] and
_rou[P+e[5]] < (_sigma[P+e[5]]*1.414213562373095048) and
_rou[P+e[6]] < (_sigma[P+e[6]]*1.414213562373095048) and
_rou[P+e[7]] < (_sigma[P+e[7]]*1.414213562373095048) and
_rou[P+e[8]] < (_sigma[P+e[8]]*1.414213562373095048)):
_ispinning[P] = 1
else:
_ispinning[P] = 0
@ti.kernel
def update_karpa():
for P in ti.grouped(_kapar):
for i in ti.static(range(9)):
P_nebor = P+e[i]
_kapar[P][i] = 0.5*(_kar[P]+_kar[P_nebor])
@ti.kernel
def ini_k():
for P in ti.grouped(_kar):
_kar[P] = _paper[P]
@ti.kernel
def update_k_for_pinning():
for P in ti.grouped(_kar):
if(_ispinning[P]):
_kar[P] = 1
@ti.kernel
def update_rou():
for P in ti.grouped(_rou):
_rou[P] = _Flow[P].sum()*(0.995)
omiga = 0.5
@ti.kernel
def update_FlowNext():
for P in ti.grouped(_FlowNext):
for i in ti.static(range(9)):
prePos = P-e[i]
_FlowNext[P][i] = omiga * \
(_Feq[prePos][i]-_Flow[prePos][i])+_Feq[prePos][i]
@ti.kernel
def update_flow():
for P in ti.grouped(_Flow):
# _Flow[P]=_FlowNext[P]
for i in ti.static(range(9)):
prePos = P-e[i]
_Flow[P][i] = _kapar[P][i] * \
(_FlowNext[P][k[i]] - _FlowNext[prePos][i]) + \
_FlowNext[prePos][i]
@ti.kernel
def update_Feq():
alpha = 0.5
for P in ti.grouped(_Feq):
_FlowVelocity[P] = ti.Vector([0.0, 0.0])
for j in ti.static(range(1, 9)):
_FlowVelocity[P] += _Flow[P][j]*e[j]
for i in ti.static(range(9)):
_Feq[P][i] = w[i]*(_rou[P] + tg.scalar.smoothstep(_rou[P], 0, alpha)*(3 * e[i].dot(_FlowVelocity[P]) +
4.5 * (e[i].dot(_FlowVelocity[P]))**2 - 1.5 * _FlowVelocity[P].dot(_FlowVelocity[P])))
@ti.kernel
def fill_BG():
for p in ti.grouped(_BackGroundLayer):
_BackGroundLayer[p] = ti.Vector([1,1,1])
# @ti.kernel
# def fill_PL(r: float, g: float, b: float, a: float):
# for P in ti.grouped(_Pigment_Surface):
# _Pigment_Surface[P][0] = r
# _Pigment_Surface[P][1] = g
# _Pigment_Surface[P][2] = b
# _Pigment_Surface[P].a = a
@ti.kernel
def render():
for P in ti.grouped(_FrameBuffer):
_FrameBuffer[P] = tg.scalar.mix(
_BackGroundLayer[P], _Pigment_Surface_c[P], _Pigment_Surface_a[P])
_FrameBuffer[P] = tg.scalar.mix(
_FrameBuffer[P], _Pigment_flow_c[P], _Pigment_flow_a[P])
_FrameBuffer[P] = tg.scalar.mix(
_FrameBuffer[P], ti.Vector([0.0, 0.2, 0.6]), _rou[P]*0.5)
@ti.kernel
def drawStrok(color: ti.template(), i: int, radius: ti.f32):
center = ti.Vector([cursor[0], cursor[1]])
for P in ti.grouped(_Pigment_Surface_c):
dis = (P/res-center).norm()
if dis < radius:
# mask = max(1-_rou[P]/0.5,0.1)
brush_tip = tg.scalar.clamp(1-dis/radius, 0, 1)
_Water_Surface[P] += max(1-_rou[P]/0.5, 0.7)
_Water_Surface[P] = tg.scalar.clamp(_Water_Surface[P])
_Pigment_Surface_c[P] = color[i].rgb
_Pigment_Surface_a[P] += brush_tip*color[i].a
# _Pigment_Surface[P]=tg.scalar.clamp(_Pigment_Surface[P],color[i][3])
_kar[P] = _paper[P]
psy = ti.field(dtype=float, shape=(res, res))
@ti.kernel
def waterSurface_to_flow():
for P in ti.grouped(_Flow):
psy[P] = tg.scalar.clamp(_Water_Surface[P], 0, 1.0-_rou[P])
_Flow[P][0] += psy[P]
_Water_Surface[P] -= psy[P]
@ti.kernel
def Pigment_S_to_F():
for P in ti.grouped(psy):
if (psy[P] > 0):
denom = (_rou[P]+psy[P])
_Pigment_flow_c[P] = (_Pigment_flow_c[P]*_rou[P]*_Pigment_flow_a[P] +
_Pigment_Surface_c[P]*psy[P]*_Pigment_Surface_a[P])/ \
(_rou[P]*_Pigment_flow_a[P]+psy[P]*_Pigment_Surface_a[P])
_Pigment_flow_a[P] = tg.scalar.clamp(
_Pigment_flow_a[P]+psy[P]*_Pigment_Surface_a[P]/denom, 0, 1)
_Pigment_Surface_a[P] = tg.scalar.clamp(
_Pigment_Surface_a[P]-(psy[P]/denom), 0, 1)
@ti.kernel
def update_Pf_star():
for P in ti.grouped(_Pigment_flow_star_c):
# _Pigment_flow_star_a[P]=0
# if (_ispinning[P] and (_rou[P] > 0)):
# _Pigment_flow_star_c[P]=_Pigment_flow_c[P-4*_FlowVelocity[P]]
# else:
_Pigment_flow_star_c[P]=tg.sampling.bilerp(_Pigment_flow_c,P-4*_FlowVelocity[P])
_Pigment_flow_star_a[P] = tg.sampling.bilerp(_Pigment_flow_a, P-4*_FlowVelocity[P])
@ti.kernel
def update_Pf():
for P in ti.grouped(_Pigment_flow_c):
gama_star = tg.scalar.mix(1, 0.1, tg.scalar.smoothstep(
_FlowVelocity[P].norm()*4, 0, 0.05))
_Pigment_flow_a[P] = (_Pigment_flow_a[P]-_Pigment_flow_star_a[P]
)*gama_star+_Pigment_flow_star_a[P]
_Pigment_flow_c[P] = (_Pigment_flow_c[P]-_Pigment_flow_star_c[P]
)*gama_star+_Pigment_flow_star_c[P]
_rouPre = ti.field(dtype=float, shape=(res, res))
@ti.kernel
def _update_rouPre():
for P in ti.grouped(_rouPre):
_rouPre[P] = _rou[P]
# miu = -0.2
# ksy = 0.5
# niu = 0.0001
# @ti.kernel
# def update_Fixture():
# for P in ti.grouped(_Fixture):
# fixFactor = 0.0
# wLoss = max(_rouPre[P]-_rou[P], 0)
# if (wLoss > 0):
# fixFactor = wLoss/_rouPre[P]
# u_star = tg.scalar.clamp(miu+ksy*_Pigment_flow[P].a, 0, 1)
# fixFactor = max(
# fixFactor*(1-tg.scalar.smoothstep(_rou[P], 0, u_star)), niu)
# tempV = fixFactor*_Pigment_flow[P].a
# # _Fixture[P]+=tempV
# _Fixture[P][3] = tg.scalar.clamp(_Fixture[P][3]+tempV)
# _Pigment_flow[P].a = tg.scalar.clamp(_Pigment_flow[P].a-tempV)
@ti.kernel
def ini_to_1(field: ti.template()):
for P in ti.grouped(field):
field[P] = ti.Vector([1.0,1.0,1.0])
gui = ti.ui.Window("ti-ink", (res, res))
canvas=gui.get_canvas()
fill_BG()
ini_k()
ini_sigma()
cursor[0] = 0.5
cursor[1] = 0.5
# ini_to_0(_Pigment_Surface.rgb)
ini_to_1(_Pigment_flow_c)
# ini_to_0(_Fixture)
while gui.running:
gui.get_event()
if(gui.is_pressed(ti.GUI.LMB)):
cursor[0] = gui.get_cursor_pos()[0]
cursor[1] = gui.get_cursor_pos()[1]
drawStrok(currentColor, 0, brushRadius)
if(gui.is_pressed(ti.GUI.RMB)):
cursor[0] = gui.get_cursor_pos()[0]
cursor[1] = gui.get_cursor_pos()[1]
drawStrok(currentColor, 1, brushRadius)
waterSurface_to_flow()
Pigment_S_to_F()
update_rou()
update_Feq()
update_FlowNext()
update_flow()
update_Pf_star()
update_Pf()
# _update_rouPre()
get_ispinning()
update_k_for_pinning()
update_karpa()
# update_Fixture()
render()
canvas.set_image(_FrameBuffer)
gui.show()
好的!非常感谢