summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2023-09-03 01:02:14 -0700
committerVito Caputo <vcaputo@pengaru.com>2023-09-03 01:02:14 -0700
commit62a08f9e7b9b1d258caf6680b2978fce4dc303d3 (patch)
tree5b6921c7b16c723af4b54c58c0dede7ecb2d332f
parent7e2d6bf6304ef22ce8f35bc6c5eac323f2f39d01 (diff)
modules/flow: add colors
This is a first stab at colorizing the output. The flow field now has two v3f_t datums per cell, direction and color. It's a bit pastel-y and color choice/palettes definitely needs work, at least some gamma correction would make sense. But I kind of like the pastel look actually, some of the combinations start looking very 80s aesthetic. A good way to watch flow's possibilities is: --module=rtv,channels=flow,duration=10,context_duration=10,caption_duration=0 \ --video=sdl,fullscreen=on --defaults --go The long-ish duration really gives a chance to get into the groove of things before switching
-rw-r--r--src/modules/flow/ff.c30
-rw-r--r--src/modules/flow/ff.h9
-rw-r--r--src/modules/flow/flow.c17
3 files changed, 34 insertions, 22 deletions
diff --git a/src/modules/flow/ff.c b/src/modules/flow/ff.c
index a0ab56c..f4280b9 100644
--- a/src/modules/flow/ff.c
+++ b/src/modules/flow/ff.c
@@ -7,8 +7,8 @@
typedef struct ff_t {
unsigned size;
- v3f_t *fields[2];
- void (*populator)(void *context, unsigned size, const v3f_t *other, v3f_t *field);
+ ff_data_t *fields[2];
+ void (*populator)(void *context, unsigned size, const ff_data_t *other, ff_data_t *field);
void *populator_context;
} ff_t;
@@ -39,7 +39,7 @@ ff_t * ff_free(ff_t *ff)
}
-ff_t * ff_new(unsigned size, void (*populator)(void *context, unsigned size, const v3f_t *other, v3f_t *field), void *context)
+ff_t * ff_new(unsigned size, void (*populator)(void *context, unsigned size, const ff_data_t *other, ff_data_t *field), void *context)
{
ff_t *ff;
@@ -48,7 +48,7 @@ ff_t * ff_new(unsigned size, void (*populator)(void *context, unsigned size, con
return NULL;
for (int i = 0; i < 2; i++) {
- ff->fields[i] = calloc(size * size * size, sizeof(v3f_t));
+ ff->fields[i] = calloc(size * size * size, sizeof(ff_data_t));
if (!ff->fields[i])
return ff_free(ff);
}
@@ -64,10 +64,11 @@ ff_t * ff_new(unsigned size, void (*populator)(void *context, unsigned size, con
}
-static inline v3f_t ff_sample(v3f_t *field, size_t size, v3f_t *min, v3f_t *max, v3f_t *t)
+static inline ff_data_t ff_sample(ff_data_t *field, size_t size, v3f_t *min, v3f_t *max, v3f_t *t)
{
- v3f_t *a, *b, *c, *d, *e, *f, *g, *h;
- size_t ss = size * size;
+ ff_data_t *a, *b, *c, *d, *e, *f, *g, *h;
+ size_t ss = size * size;
+ ff_data_t res;
a = &field[(size_t)min->x * ss + (size_t)max->y * size + (size_t)min->z];
b = &field[(size_t)max->x * ss + (size_t)max->y * size + (size_t)min->z];
@@ -78,16 +79,20 @@ static inline v3f_t ff_sample(v3f_t *field, size_t size, v3f_t *min, v3f_t *max,
g = &field[(size_t)min->x * ss + (size_t)min->y * size + (size_t)max->z];
h = &field[(size_t)max->x * ss + (size_t)min->y * size + (size_t)max->z];
- return v3f_trilerp(a, b, c, d, e, f, g, h, t);
+ res.direction = v3f_trilerp(&a->direction, &b->direction, &c->direction, &d->direction, &e->direction, &f->direction, &g->direction, &h->direction, t);
+ res.color = v3f_trilerp(&a->color, &b->color, &c->color, &d->color, &e->color, &f->color, &g->color, &h->color, t);
+
+ return res;
}
/* return an interpolated value from ff for the supplied coordinate */
/* coordinate must be in the range 0-1,0-1,0-1 */
/* w must be in the range 0-1 and determines how much of field 0 or 1 contributes to the result */
-v3f_t ff_get(ff_t *ff, v3f_t *coordinate, float w)
+ff_data_t ff_get(ff_t *ff, v3f_t *coordinate, float w)
{
- v3f_t scaled, min, max, t, A, B;
+ v3f_t scaled, min, max, t;
+ ff_data_t A, B, res;
assert(w <= 1.f && w >= 0.f);
assert(coordinate->x <= 1.f && coordinate->x >= 0.f);
@@ -119,5 +124,8 @@ v3f_t ff_get(ff_t *ff, v3f_t *coordinate, float w)
A = ff_sample(ff->fields[0], ff->size, &min, &max, &t);
B = ff_sample(ff->fields[1], ff->size, &min, &max, &t);
- return v3f_nlerp(&A, &B, w);
+ res.direction = v3f_nlerp(&A.direction, &B.direction, w);
+ res.color = v3f_nlerp(&A.color, &B.color, w);
+
+ return res;
}
diff --git a/src/modules/flow/ff.h b/src/modules/flow/ff.h
index 0324ea0..b148c2e 100644
--- a/src/modules/flow/ff.h
+++ b/src/modules/flow/ff.h
@@ -5,9 +5,14 @@
typedef struct ff_t ff_t;
-ff_t * ff_new(unsigned size, void (*populator)(void *context, unsigned size, const v3f_t *other, v3f_t *field), void *context);
+typedef struct ff_data_t {
+ v3f_t direction;
+ v3f_t color;
+} ff_data_t;
+
+ff_t * ff_new(unsigned size, void (*populator)(void *context, unsigned size, const ff_data_t *other, ff_data_t *field), void *context);
ff_t * ff_free(ff_t *ff);
-v3f_t ff_get(ff_t *ff, v3f_t *coordinate, float w);
+ff_data_t ff_get(ff_t *ff, v3f_t *coordinate, float w);
void ff_populate(ff_t *ff, unsigned idx);
#endif
diff --git a/src/modules/flow/flow.c b/src/modules/flow/flow.c
index 636458f..973fad0 100644
--- a/src/modules/flow/flow.c
+++ b/src/modules/flow/flow.c
@@ -48,7 +48,7 @@ typedef struct flow_setup_t {
} flow_setup_t;
-static void populator(void *context, unsigned size, const v3f_t *other, v3f_t *field)
+static void populator(void *context, unsigned size, const ff_data_t *other, ff_data_t *field)
{
flow_context_t *ctxt = context;
unsigned *seedp = &ctxt->til_module_context.seed;
@@ -58,9 +58,11 @@ static void populator(void *context, unsigned size, const v3f_t *other, v3f_t *f
for (y = 0; y < size; y++) {
for (z = 0; z < size; z++) {
v3f_t v = v3f_rand(seedp, -1.0f, 1.0f);
+ v3f_t c = v3f_rand(seedp, 0.f, 1.0f);
size_t idx = x * size * size + y * size + z;
- field[idx] = v3f_lerp(&other[idx], &v, .75f);
+ field[idx].direction = v3f_lerp(&other[idx].direction, &v, .75f);
+ field[idx].color = v3f_lerp(&other[idx].color, &c, .75f);
}
}
}
@@ -150,22 +152,19 @@ static void flow_render_fragment(til_module_context_t *context, til_stream_t *st
for (unsigned j = 0; j < ctxt->n_elements; j++) {
flow_element_t *e = &ctxt->elements[j];
v3f_t pos = e->position;
- v3f_t v = ff_get(ctxt->ff, &pos, w * .5f + .5f);
+ ff_data_t d = ff_get(ctxt->ff, &pos, w * .5f + .5f);
- v = v3f_mult_scalar(&v, .001f);
+ d.direction = v3f_mult_scalar(&d.direction, .001f);
for (unsigned k = 0; k < ctxt->n_iters; k++) {
unsigned x, y;
- v3f_t color;
- pos = v3f_add(&pos, &v);
+ pos = v3f_add(&pos, &d.direction);
#define ZCONST 1.0f
x = (pos.x * 2.f - 1.f) / (pos.z + ZCONST) * fragment->width + (fragment->width >> 1);
y = (pos.y * 2.f - 1.f) / (pos.z + ZCONST) * fragment->height + (fragment->height >> 1) ;
- color.x = color.y = color.z = e->lifetime;
-
- if (!til_fb_fragment_put_pixel_checked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, x, y, color_to_uint32_rgb(color)) ||
+ if (!til_fb_fragment_put_pixel_checked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, x, y, color_to_uint32_rgb(d.color)) ||
pos.x < 0.f || pos.x > 1.f ||
pos.y < 0.f || pos.y > 1.f ||
pos.z < 0.f || pos.z > 1.f)
© All Rights Reserved