mirror of
https://github.com/stevenrobertson/cuburn.git
synced 2025-02-05 11:40:04 -05:00
Add a few vars, and support for rendering single flames
This commit is contained in:
parent
84c2583ba8
commit
8ee5d3edd8
@ -37,7 +37,7 @@ texture<uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> palTex;
|
||||
tmpl = tempita.Template("""
|
||||
__device__
|
||||
void apply_xf{{xfid}}(float *ix, float *iy, float *icolor,
|
||||
const iter_info *info) {
|
||||
const iter_info *info, mwc_st *rctx) {
|
||||
float tx, ty, ox = *ix, oy = *iy;
|
||||
{{apply_affine('ox', 'oy', 'tx', 'ty', px, 'xf.c', 'pre')}}
|
||||
|
||||
@ -47,7 +47,7 @@ void apply_xf{{xfid}}(float *ix, float *iy, float *icolor,
|
||||
{{for v in xform.vars}}
|
||||
if (1) {
|
||||
float w = {{px.get('xf.var[%d]' % v)}};
|
||||
{{variations.var_code[variations.var_nos[v]]()}}
|
||||
{{variations.var_code[variations.var_nos[v]].substitute(locals())}}
|
||||
}
|
||||
{{endfor}}
|
||||
|
||||
@ -82,7 +82,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
|
||||
|
||||
{{for xfid, xform in enumerate(features.xforms)}}
|
||||
if (xfsel <= {{packer.get('cp.norm_density[%d]' % xfid)}}) {
|
||||
apply_xf{{xfid}}(&x, &y, &color, info);
|
||||
apply_xf{{xfid}}(&x, &y, &color, info, &rctx);
|
||||
} else
|
||||
{{endfor}}
|
||||
{
|
||||
@ -97,7 +97,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
|
||||
|
||||
nsamps--;
|
||||
|
||||
if (x <= -1.0f || x >= 1.0f || y <= -1.0f || y >= 1.0f) {
|
||||
if (x <= -0.5f || x >= 0.5f || y <= -0.5f || y >= 0.5f) {
|
||||
consec_bad++;
|
||||
if (consec_bad > {{features.max_oob}}) {
|
||||
x = mwc_next_11(&rctx);
|
||||
@ -109,8 +109,8 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
|
||||
}
|
||||
|
||||
// TODO: dither?
|
||||
int i = ((int)((y + 1.0f) * 511.0f) * 1024)
|
||||
+ (int)((x + 1.0f) * 511.0f) + 1025;
|
||||
int i = ((int)((y + 0.5f) * 1023.0f) * 1024)
|
||||
+ (int)((x + 0.5f) * 1023.0f) + 1025;
|
||||
|
||||
// since info was declared const, C++ barfs unless it's loaded first
|
||||
float cp_step_frac = {{packer.get('cp_step_frac')}};
|
||||
@ -129,7 +129,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
|
||||
|
||||
|
||||
def silly(features, cps):
|
||||
nsteps = 1000
|
||||
nsteps = 500
|
||||
abuf = np.zeros((1024, 1024, 4), dtype=np.float32)
|
||||
dbuf = np.zeros((1024, 1024), dtype=np.float32)
|
||||
seeds = mwc.MWC.make_seeds(512 * nsteps)
|
||||
@ -139,28 +139,37 @@ def silly(features, cps):
|
||||
|
||||
for lno, line in enumerate(code.split('\n')):
|
||||
print '%3d %s' % (lno, line)
|
||||
mod = SourceModule(code, options=[], keep=True)
|
||||
mod = SourceModule(code, options=['--use_fast_math'], keep=True)
|
||||
|
||||
cps_as_array = (Genome * len(cps))()
|
||||
for i, cp in enumerate(cps):
|
||||
cps_as_array[i] = cp
|
||||
|
||||
cp = Genome()
|
||||
memset(byref(cp), 0, sizeof(cp))
|
||||
infos = []
|
||||
pal = np.empty((16, 256, 4), dtype=np.uint8)
|
||||
|
||||
# TODO: move this into a common function
|
||||
pal = np.empty((16, 256, 4), dtype=np.uint8)
|
||||
sampAt = [int(i/15.*(nsteps-1)) for i in range(16)]
|
||||
if len(cps) > 1:
|
||||
cp = Genome()
|
||||
memset(byref(cp), 0, sizeof(cp))
|
||||
|
||||
sampAt = [int(i/15.*(nsteps-1)) for i in range(16)]
|
||||
for n in range(nsteps):
|
||||
flam3_interpolate(cps_as_array, 2, float(n)/nsteps - 0.5,
|
||||
0, byref(cp))
|
||||
cp._init()
|
||||
if n in sampAt:
|
||||
pidx = sampAt.index(n)
|
||||
for i, e in enumerate(cp.palette.entries):
|
||||
pal[pidx][i] = np.uint8(np.array(e.color) * 255.0)
|
||||
infos.append(iter.packer.pack(cp=cp, cp_step_frac=float(n)/nsteps))
|
||||
else:
|
||||
for i, e in enumerate(cps[0].palette.entries):
|
||||
pal[0][i] = np.uint8(np.array(e.color) * 255.0)
|
||||
pal[1:] = pal[0]
|
||||
infos.append(iter.packer.pack(cp=cps[0], cp_step_frac=0))
|
||||
infos *= nsteps
|
||||
|
||||
for n in range(nsteps):
|
||||
flam3_interpolate(cps_as_array, 2, float(n)/nsteps - 0.5, 0, byref(cp))
|
||||
cp._init()
|
||||
if n in sampAt:
|
||||
pidx = sampAt.index(n)
|
||||
for i, e in enumerate(cp.palette.entries):
|
||||
pal[pidx][i] = np.uint8(np.array(e.color) * 255.0)
|
||||
infos.append(iter.packer.pack(cp=cp, cp_step_frac=float(n)/nsteps))
|
||||
infos = np.concatenate(infos)
|
||||
|
||||
dpal = cuda.make_multichannel_2d_array(pal, 'C')
|
||||
|
@ -1,40 +1,58 @@
|
||||
import tempita
|
||||
|
||||
var_nos = {}
|
||||
var_code = {}
|
||||
|
||||
def _var(num, name = None):
|
||||
def _var1(func):
|
||||
if name:
|
||||
namelo = name
|
||||
else:
|
||||
namelo = func.__name__
|
||||
var_nos[num] = namelo
|
||||
var_code[namelo] = func
|
||||
return _var1
|
||||
def var(num, name, code):
|
||||
var_nos[num] = name
|
||||
var_code[name] = tempita.Template(code)
|
||||
|
||||
# Variables note: all functions will have their weights as 'w',
|
||||
# input variables 'tx' and 'ty', and output 'ox' and 'oy' available
|
||||
# from the calling context. Each statement will be placed inside brackets,
|
||||
# to avoid namespace pollution.
|
||||
@_var(0)
|
||||
def linear():
|
||||
return """
|
||||
var(0, 'linear', """
|
||||
ox += tx * w;
|
||||
oy += ty * w;
|
||||
"""
|
||||
""")
|
||||
|
||||
@_var(1)
|
||||
def sinusoidal():
|
||||
return """
|
||||
ox += w * sin(tx);
|
||||
oy += w * sin(ty);
|
||||
"""
|
||||
var(1, 'sinusoidal', """
|
||||
ox += w * sinf(tx);
|
||||
oy += w * sinf(ty);
|
||||
""")
|
||||
|
||||
@_var(2)
|
||||
def spherical():
|
||||
return """
|
||||
var(2, 'spherical', """
|
||||
float r2 = w / (tx*tx + ty*ty + 1e-20);
|
||||
ox += tx * r2;
|
||||
oy += ty * r2;
|
||||
"""
|
||||
""")
|
||||
|
||||
var(5, 'polar', """
|
||||
ox += w * atan2f(tx, ty) * M_1_PI;
|
||||
oy += w * (sqrtf(tx * tx + ty * ty) - 1.0);
|
||||
""")
|
||||
|
||||
|
||||
var(10, 'hyperbolic', """
|
||||
float a = atan2f(tx, ty);
|
||||
float r = sqrt(tx*tx + ty*ty) + 1e-20;
|
||||
ox += w * sinf(a) / r;
|
||||
oy += w * cosf(a) * r;
|
||||
""")
|
||||
|
||||
var(33, 'juliascope', """
|
||||
float ang = atan2f(ty, tx);
|
||||
float power = {{px.get('xf.juliascope_power', 'juscope_power')}};
|
||||
float t_rnd = truncf(mwc_next_01(rctx) * fabsf(power));
|
||||
// TODO: don't draw the extra random number
|
||||
if (mwc_next(rctx) & 1) ang = -ang;
|
||||
float tmpr = (2 * M_PI * t_rnd + ang) / power;
|
||||
|
||||
float cn = {{px.get('xf.juliascope_dist / xf.juliascope_power / 2',
|
||||
'juscope_cn')}};
|
||||
float r = w * powf(tx * tx + ty * ty, cn);
|
||||
|
||||
ox += r * cosf(tmpr);
|
||||
oy += r * sinf(tmpr);
|
||||
""")
|
||||
|
||||
|
9
main.py
9
main.py
@ -32,21 +32,18 @@ from cuburn.code.iter import silly, membench
|
||||
|
||||
|
||||
def main(args):
|
||||
membench()
|
||||
return
|
||||
|
||||
#MWCTest.test_mwc()
|
||||
with open(args[-1]) as fp:
|
||||
genomes = Genome.from_string(fp.read())
|
||||
anim = Animation(genomes)
|
||||
accum, den = silly(anim.features, genomes)
|
||||
|
||||
if '-g' not in args:
|
||||
return
|
||||
|
||||
noalpha = np.delete(accum, 3, axis=2)
|
||||
scipy.misc.imsave('rendered.png', noalpha)
|
||||
|
||||
if '-g' not in args:
|
||||
return
|
||||
|
||||
imgbuf = (np.minimum(accum * 255, 255)).astype(np.uint8)
|
||||
|
||||
image = pyglet.image.ImageData(1024, 1024, 'RGBA', imgbuf.tostring(), -4096)
|
||||
|
Loading…
Reference in New Issue
Block a user