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("""
|
tmpl = tempita.Template("""
|
||||||
__device__
|
__device__
|
||||||
void apply_xf{{xfid}}(float *ix, float *iy, float *icolor,
|
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;
|
float tx, ty, ox = *ix, oy = *iy;
|
||||||
{{apply_affine('ox', 'oy', 'tx', 'ty', px, 'xf.c', 'pre')}}
|
{{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}}
|
{{for v in xform.vars}}
|
||||||
if (1) {
|
if (1) {
|
||||||
float w = {{px.get('xf.var[%d]' % v)}};
|
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}}
|
{{endfor}}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
|
|||||||
|
|
||||||
{{for xfid, xform in enumerate(features.xforms)}}
|
{{for xfid, xform in enumerate(features.xforms)}}
|
||||||
if (xfsel <= {{packer.get('cp.norm_density[%d]' % xfid)}}) {
|
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
|
} else
|
||||||
{{endfor}}
|
{{endfor}}
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
|
|||||||
|
|
||||||
nsamps--;
|
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++;
|
consec_bad++;
|
||||||
if (consec_bad > {{features.max_oob}}) {
|
if (consec_bad > {{features.max_oob}}) {
|
||||||
x = mwc_next_11(&rctx);
|
x = mwc_next_11(&rctx);
|
||||||
@ -109,8 +109,8 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: dither?
|
// TODO: dither?
|
||||||
int i = ((int)((y + 1.0f) * 511.0f) * 1024)
|
int i = ((int)((y + 0.5f) * 1023.0f) * 1024)
|
||||||
+ (int)((x + 1.0f) * 511.0f) + 1025;
|
+ (int)((x + 0.5f) * 1023.0f) + 1025;
|
||||||
|
|
||||||
// since info was declared const, C++ barfs unless it's loaded first
|
// since info was declared const, C++ barfs unless it's loaded first
|
||||||
float cp_step_frac = {{packer.get('cp_step_frac')}};
|
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):
|
def silly(features, cps):
|
||||||
nsteps = 1000
|
nsteps = 500
|
||||||
abuf = np.zeros((1024, 1024, 4), dtype=np.float32)
|
abuf = np.zeros((1024, 1024, 4), dtype=np.float32)
|
||||||
dbuf = np.zeros((1024, 1024), dtype=np.float32)
|
dbuf = np.zeros((1024, 1024), dtype=np.float32)
|
||||||
seeds = mwc.MWC.make_seeds(512 * nsteps)
|
seeds = mwc.MWC.make_seeds(512 * nsteps)
|
||||||
@ -139,28 +139,37 @@ def silly(features, cps):
|
|||||||
|
|
||||||
for lno, line in enumerate(code.split('\n')):
|
for lno, line in enumerate(code.split('\n')):
|
||||||
print '%3d %s' % (lno, line)
|
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))()
|
cps_as_array = (Genome * len(cps))()
|
||||||
for i, cp in enumerate(cps):
|
for i, cp in enumerate(cps):
|
||||||
cps_as_array[i] = cp
|
cps_as_array[i] = cp
|
||||||
|
|
||||||
cp = Genome()
|
|
||||||
memset(byref(cp), 0, sizeof(cp))
|
|
||||||
infos = []
|
infos = []
|
||||||
|
pal = np.empty((16, 256, 4), dtype=np.uint8)
|
||||||
|
|
||||||
# TODO: move this into a common function
|
# TODO: move this into a common function
|
||||||
pal = np.empty((16, 256, 4), dtype=np.uint8)
|
if len(cps) > 1:
|
||||||
sampAt = [int(i/15.*(nsteps-1)) for i in range(16)]
|
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)
|
infos = np.concatenate(infos)
|
||||||
|
|
||||||
dpal = cuda.make_multichannel_2d_array(pal, 'C')
|
dpal = cuda.make_multichannel_2d_array(pal, 'C')
|
||||||
|
@ -1,40 +1,58 @@
|
|||||||
|
import tempita
|
||||||
|
|
||||||
var_nos = {}
|
var_nos = {}
|
||||||
var_code = {}
|
var_code = {}
|
||||||
|
|
||||||
def _var(num, name = None):
|
def var(num, name, code):
|
||||||
def _var1(func):
|
var_nos[num] = name
|
||||||
if name:
|
var_code[name] = tempita.Template(code)
|
||||||
namelo = name
|
|
||||||
else:
|
|
||||||
namelo = func.__name__
|
|
||||||
var_nos[num] = namelo
|
|
||||||
var_code[namelo] = func
|
|
||||||
return _var1
|
|
||||||
|
|
||||||
# Variables note: all functions will have their weights as 'w',
|
# Variables note: all functions will have their weights as 'w',
|
||||||
# input variables 'tx' and 'ty', and output 'ox' and 'oy' available
|
# input variables 'tx' and 'ty', and output 'ox' and 'oy' available
|
||||||
# from the calling context. Each statement will be placed inside brackets,
|
# from the calling context. Each statement will be placed inside brackets,
|
||||||
# to avoid namespace pollution.
|
# to avoid namespace pollution.
|
||||||
@_var(0)
|
var(0, 'linear', """
|
||||||
def linear():
|
|
||||||
return """
|
|
||||||
ox += tx * w;
|
ox += tx * w;
|
||||||
oy += ty * w;
|
oy += ty * w;
|
||||||
"""
|
""")
|
||||||
|
|
||||||
@_var(1)
|
var(1, 'sinusoidal', """
|
||||||
def sinusoidal():
|
ox += w * sinf(tx);
|
||||||
return """
|
oy += w * sinf(ty);
|
||||||
ox += w * sin(tx);
|
""")
|
||||||
oy += w * sin(ty);
|
|
||||||
"""
|
|
||||||
|
|
||||||
@_var(2)
|
var(2, 'spherical', """
|
||||||
def spherical():
|
|
||||||
return """
|
|
||||||
float r2 = w / (tx*tx + ty*ty + 1e-20);
|
float r2 = w / (tx*tx + ty*ty + 1e-20);
|
||||||
ox += tx * r2;
|
ox += tx * r2;
|
||||||
oy += ty * 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):
|
def main(args):
|
||||||
membench()
|
|
||||||
return
|
|
||||||
|
|
||||||
#MWCTest.test_mwc()
|
#MWCTest.test_mwc()
|
||||||
with open(args[-1]) as fp:
|
with open(args[-1]) as fp:
|
||||||
genomes = Genome.from_string(fp.read())
|
genomes = Genome.from_string(fp.read())
|
||||||
anim = Animation(genomes)
|
anim = Animation(genomes)
|
||||||
accum, den = silly(anim.features, genomes)
|
accum, den = silly(anim.features, genomes)
|
||||||
|
|
||||||
if '-g' not in args:
|
|
||||||
return
|
|
||||||
|
|
||||||
noalpha = np.delete(accum, 3, axis=2)
|
noalpha = np.delete(accum, 3, axis=2)
|
||||||
scipy.misc.imsave('rendered.png', noalpha)
|
scipy.misc.imsave('rendered.png', noalpha)
|
||||||
|
|
||||||
|
if '-g' not in args:
|
||||||
|
return
|
||||||
|
|
||||||
imgbuf = (np.minimum(accum * 255, 255)).astype(np.uint8)
|
imgbuf = (np.minimum(accum * 255, 255)).astype(np.uint8)
|
||||||
|
|
||||||
image = pyglet.image.ImageData(1024, 1024, 'RGBA', imgbuf.tostring(), -4096)
|
image = pyglet.image.ImageData(1024, 1024, 'RGBA', imgbuf.tostring(), -4096)
|
||||||
|
Loading…
Reference in New Issue
Block a user