Exemple #1
0
def main(ctx, width, height, channels, seed, name, preset_name):
    generators.set_seed(seed)

    kwargs, preset_name = presets.load(preset_name)

    print(preset_name)

    kwargs["shape"] = [height, width, channels]

    # print(kwargs)

    if "freq" not in kwargs:
        kwargs["freq"] = 3

    if "octaves" not in kwargs:
        kwargs["octaves"] = 1

    if "ridges" not in kwargs:
        kwargs["ridges"] = False

    tensor = generators.multires(**kwargs)

    tensor = recipes.post_process(tensor, **kwargs)

    with tf.Session().as_default():
        save(tensor, name)
Exemple #2
0
def _control():
    shape = [SMALL_Y, SMALL_X, 1]

    control = generators.multires(shape=shape, freq=FREQ, octaves=OCTAVES, refract_range=.5)

    erode_kwargs = {
        "alpha": .025,
        "density": 40,
        "iterations": 20,
        "inverse": True,
    }

    iterations = 5
    for i in range(iterations):
        control = effects.erode(control, shape, **erode_kwargs)
        control = effects.convolve(constants.ValueMask.conv2d_blur, control, shape)

    post_shape = [LARGE_Y, LARGE_X, 1]
    control = effects.resample(control, post_shape)

    iterations = 2
    for i in range(iterations):
        control = effects.erode(control, post_shape, **erode_kwargs)
        control = effects.convolve(constants.ValueMask.conv2d_blur, control, post_shape)

    control = effects.convolve(constants.ValueMask.conv2d_sharpen, control, post_shape)
    control = effects.normalize(control)

    with tf.Session().as_default():
        save(control, CONTROL_FILENAME)
Exemple #3
0
def grime(tensor, shape):
    """
    """

    value_shape = [shape[0], shape[1], 1]

    mask = multires(5,
                    value_shape,
                    distrib="exp",
                    octaves=8,
                    refract_range=1.0,
                    deriv=3,
                    deriv_alpha=.5)

    dusty = effects.blend(tensor, .25, tf.square(mask) * .125)

    specks = basic(
        [int(shape[0] * .25), int(shape[1] * .25)],
        value_shape,
        distrib="exp",
        refract_range=.1)
    specks = 1.0 - tf.sqrt(effects.normalize(tf.maximum(specks - .5, 0.0)))

    dusty = effects.blend(dusty, basic([shape[0], shape[1]], value_shape),
                          .125) * specks

    return effects.blend(tensor, dusty, mask)
Exemple #4
0
def lowland():
    shape = [LARGE_Y, LARGE_X, 3]

    kwargs = {
        "deriv": 1,
        "deriv_alpha": .5,
        "freq": FREQ,
        "hue_range": .125 + random.random() * .25,
        "hue_rotation": .875 + random.random() * .125,
        "lattice_drift": 1,
        "octaves": OCTAVES,
        "point_freq": 5,
        "saturation": SATURATION * 2,
        "voronoi_alpha": .333,
        "voronoi_inverse": True,
        "voronoi_nth": 0,
        "with_voronoi": 2,
    }

    tensor = generators.multires(shape=shape, **kwargs)

    tensor = tf.image.adjust_brightness(tensor, .1)

    with tf.Session().as_default():
        save(tensor, LOW_FILENAME)
Exemple #5
0
    def render(self,
               tensor=None,
               shape=DEFAULT_SHAPE,
               time=0.0,
               speed=1.0,
               filename="art.png"):
        """Render the preset to an image file."""

        # import json
        # logger.debug("Rendering noise: "
        #              + json.dumps(self.__dict__,
        #                           default=lambda v: dict(v) if isinstance(v, SettingsDict) else str(v),
        #                           indent=4))

        try:
            tensor = multires(tensor=tensor,
                              shape=shape,
                              octave_effects=self.octave_effects,
                              post_effects=self.post_effects,
                              time=time,
                              speed=speed,
                              **self.generator_kwargs)

            with tf.compat.v1.Session().as_default():
                save(tensor, filename)

        except Exception as e:
            logger.error(f"Error rendering preset named {self.name}: {e}")

            raise
Exemple #6
0
def glitch(tensor, shape, time=0.0, speed=1.0):
    """
    Apply a glitch effect.

    :param Tensor tensor:
    :param list[int] shape:
    :return: Tensor
    """

    height, width, channels = shape

    tensor = effects.normalize(tensor)

    base = multires(2,
                    shape,
                    time=time,
                    speed=speed,
                    distrib=ValueDistribution.simplex,
                    octaves=random.randint(2, 5),
                    spline_order=0,
                    refract_range=random.random())
    stylized = effects.normalize(
        effects.color_map(base,
                          tensor,
                          shape,
                          horizontal=True,
                          displacement=2.5))

    jpegged = effects.color_map(base,
                                stylized,
                                shape,
                                horizontal=True,
                                displacement=2.5)

    if channels in (1, 3):
        jpegged = effects.jpeg_decimate(jpegged, shape)

    # Offset a single color channel
    separated = [stylized[:, :, i] for i in range(channels)]
    x_index = (effects.row_index(shape) + random.randint(1, width)) % width
    index = tf.cast(tf.stack([effects.column_index(shape), x_index], 2),
                    tf.int32)

    channel = random.randint(0, channels - 1)
    separated[channel] = effects.normalize(
        tf.gather_nd(separated[channel], index) % random.random())

    stylized = tf.stack(separated, 2)

    combined = effects.blend(tf.multiply(stylized, 1.0), jpegged, base)
    combined = effects.blend(tensor, combined, tf.maximum(base * 2 - 1, 0))
    combined = effects.blend(combined, effects.pixel_sort(combined, shape),
                             1.0 - base)

    combined = tf.image.adjust_contrast(combined, 1.75)

    return combined
Exemple #7
0
def nebula(tensor, shape, time=0.0, speed=1.0):
    overlay = multires(random.randint(2, 4),
                       shape,
                       time=time,
                       speed=speed,
                       distrib=ValueDistribution.simplex_exp,
                       ridges=True,
                       octaves=6)

    overlay -= multires(random.randint(2, 4),
                        shape,
                        time=time,
                        speed=speed,
                        distrib=ValueDistribution.simplex,
                        ridges=True,
                        octaves=4)

    overlay = tf.maximum(overlay, 0)

    return tf.maximum(tensor, overlay * .25)
Exemple #8
0
def blended():
    shape = [LARGE_Y, LARGE_X, 3]

    erode_kwargs = {
        "alpha": .025,
        "density": 250,
        "iterations": 50,
        "inverse": True,
    }

    control = tf.image.convert_image_dtype(load(CONTROL_FILENAME), tf.float32)

    water = tf.ones(shape) * tf.stack([.05, .2, .333])
    water = effects.blend(water, control * 4.0, .125)

    low = tf.image.convert_image_dtype(load(LOW_FILENAME), tf.float32)
    mid = tf.image.convert_image_dtype(load(MID_FILENAME), tf.float32)
    high = tf.image.convert_image_dtype(load(HIGH_FILENAME), tf.float32)

    blend_control = generators.multires(shape=shape,
                                        freq=FREQ * 4,
                                        ridges=True,
                                        octaves=4)
    blend_control = 1.0 - effects.value_map(
        blend_control, shape, keep_dims=True) * .5

    combined_land = effects.blend_layers(control, shape, blend_control,
                                         control * 2, low, mid, high)
    combined_land = effects.erode(combined_land,
                                  shape,
                                  xy_blend=.25,
                                  **erode_kwargs)
    combined_land = effects.erode(combined_land, shape, **erode_kwargs)

    combined_land_0 = effects.shadow(combined_land, shape, alpha=1.0)
    combined_land_1 = effects.shadow(combined_land,
                                     shape,
                                     alpha=1.0,
                                     reference=control)

    combined_land = effects.blend(combined_land_0, combined_land_1, .5)

    combined = effects.blend_layers(control, shape, .01, water, combined_land,
                                    combined_land, combined_land)
    combined = effects.blend(combined_land, combined, .625)

    combined = tf.image.adjust_brightness(combined, .1)
    combined = tf.image.adjust_contrast(combined, .75)
    combined = tf.image.adjust_saturation(combined, .625)

    with tf.Session().as_default():
        save(combined, BLENDED_FILENAME)
Exemple #9
0
def glitch(tensor, shape):
    """
    Apply a glitch effect.

    :param Tensor tensor:
    :param list[int] shape:
    :return: Tensor
    """

    height, width, channels = shape

    tensor = effects.normalize(tensor)

    base = multires(2,
                    shape,
                    octaves=random.randint(2, 5),
                    spline_order=0,
                    refract_range=random.random())
    stylized = effects.normalize(
        effects.color_map(base,
                          tensor,
                          shape,
                          horizontal=True,
                          displacement=2.5))

    jpegged = effects.jpeg_decimate(
        effects.color_map(base,
                          stylized,
                          shape,
                          horizontal=True,
                          displacement=2.5), shape)

    # Offset a single color channel
    separated = [stylized[:, :, i] for i in range(channels)]
    x_index = (effects.row_index(shape) + random.randint(1, width)) % width
    index = tf.cast(tf.stack([effects.column_index(shape), x_index], 2),
                    tf.int32)

    channel = random.randint(0, channels - 1)
    separated[channel] = effects.normalize(
        tf.gather_nd(separated[channel], index) % random.random())

    channel = random.randint(0, channels - 1)
    top, _ = tf.nn.top_k(effects.value_map(tensor, shape), k=width)
    separated[channel] += top

    stylized = tf.stack(separated, 2)

    combined = effects.blend(tf.multiply(stylized, 1.0), jpegged, base)
    combined = effects.blend(tensor, combined, tf.maximum(base * 2 - 1, 0))

    return combined
Exemple #10
0
def frame(tensor, shape, time=0.0, speed=1.0):
    """
    """

    half_shape = [int(shape[0] * .5), int(shape[1] * .5), shape[2]]
    half_value_shape = [half_shape[0], half_shape[1], 1]

    noise = multires(64,
                     half_value_shape,
                     time=time,
                     speed=speed,
                     distrib=ValueDistribution.simplex,
                     octaves=8)

    black = tf.zeros(half_value_shape)
    white = tf.ones(half_value_shape)

    mask = effects.singularity(None,
                               half_value_shape,
                               1,
                               dist_func=3,
                               inverse=True)
    mask = effects.normalize(mask + noise * .005)
    mask = effects.blend_layers(tf.sqrt(mask), half_value_shape, 0.0125, white,
                                black, black, black)

    faded = effects._downsample(tensor, shape, half_shape)
    faded = tf.image.adjust_brightness(faded, .1)
    faded = tf.image.adjust_contrast(faded, .75)
    faded = effects.light_leak(faded, half_shape, .125)
    faded = effects.vignette(faded, half_shape, 0.05, .75)

    edge_texture = white * .9 + effects.shadow(noise, half_value_shape,
                                               1.0) * .1

    out = effects.blend(faded, edge_texture, mask)
    out = effects.aberration(out, half_shape, .00666)
    out = grime(out, half_shape)

    out = tf.image.adjust_saturation(out, .5)
    out = tf.image.random_hue(out, .05)

    out = effects.resample(out, shape)

    out = scratches(out, shape)

    out = stray_hair(out, shape)

    return out
Exemple #11
0
def clouds(input_filename):
    tensor = tf.image.convert_image_dtype(load(input_filename), tf.float32)

    pre_shape = [SMALL_Y, SMALL_X, 1]
    post_shape = [LARGE_Y, LARGE_X, 1]

    control_kwargs = {
        "freq": FREQ * 2,
        "lattice_drift": 1,
        "octaves": OCTAVES,
        "ridges": True,
        "shape": pre_shape,
        "warp_freq": 3,
        "warp_range": .25,
        "warp_octaves": 2,
    }

    control = generators.multires(**control_kwargs)

    layer_0 = tf.ones(pre_shape)
    layer_1 = tf.zeros(pre_shape)

    combined = effects.blend_layers(control, pre_shape, 1.0, layer_0, layer_1)

    shadow = effects.offset(combined, pre_shape, random.randint(-15, 15),
                            random.randint(-15, 15))
    shadow = tf.minimum(shadow * 2.5, 1.0)
    shadow = effects.convolve(effects.ConvKernel.blur, shadow, pre_shape)
    shadow = effects.convolve(effects.ConvKernel.blur, shadow, pre_shape)
    shadow = effects.convolve(effects.ConvKernel.blur, shadow, pre_shape)

    shadow = effects.resample(shadow, post_shape)
    combined = effects.resample(combined, post_shape)

    tensor = effects.blend(tensor, tf.zeros(post_shape), shadow * .5)
    tensor = effects.blend(tensor, tf.ones(post_shape), combined)

    post_shape = [LARGE_Y, LARGE_X, 3]

    tensor = effects.shadow(tensor, post_shape, alpha=.25)

    tensor = effects.bloom(tensor, post_shape, .333)
    tensor = recipes.dither(tensor, post_shape, .075)

    combined = tf.image.adjust_contrast(combined, 1.125)

    with tf.Session().as_default():
        save(tensor, FINAL_FILENAME)
Exemple #12
0
def texture(tensor, shape, time=0.0, speed=1.0):
    """
    """

    value_shape = [shape[0], shape[1], 1]

    noise = multires(64,
                     value_shape,
                     time=time,
                     speed=speed,
                     distrib=ValueDistribution.simplex,
                     octaves=8,
                     ridges=True)

    return tensor * (tf.ones(value_shape) * .95 +
                     effects.shadow(noise, value_shape, 1.0) * .05)
Exemple #13
0
def clouds(tensor, shape, time=0.0, speed=1.0):
    """Top-down cloud cover effect"""

    pre_shape = [int(shape[0] * .25) or 1, int(shape[1] * .25) or 1, 1]

    control_kwargs = {
        "freq": random.randint(2, 4),
        "lattice_drift": 1,
        "octaves": 8,
        "ridges": True,
        "speed": speed,
        "shape": pre_shape,
        "time": time,
        "warp_freq": 3,
        "warp_range": .125,
        "warp_octaves": 2,
        "distrib": ValueDistribution.simplex,
    }

    control = multires(**control_kwargs)

    layer_0 = tf.ones(pre_shape)
    layer_1 = tf.zeros(pre_shape)

    combined = effects.blend_layers(control, pre_shape, 1.0, layer_0, layer_1)

    shadow = effects.offset(combined, pre_shape, random.randint(-15, 15),
                            random.randint(-15, 15))
    shadow = tf.minimum(shadow * 2.5, 1.0)

    for _ in range(3):
        shadow = effects.convolve(ValueMask.conv2d_blur, shadow, pre_shape)

    post_shape = [shape[0], shape[1], 1]

    shadow = effects.resample(shadow, post_shape)
    combined = effects.resample(combined, post_shape)

    tensor = effects.blend(tensor, tf.zeros(shape), shadow * .75)
    tensor = effects.blend(tensor, tf.ones(shape), combined)

    tensor = effects.shadow(tensor, shape, alpha=.5)

    return tensor
Exemple #14
0
def midland():
    shape = [LARGE_Y, LARGE_X, 3]

    kwargs = {
        "deriv": 1,
        "deriv_alpha": .25,
        "freq": FREQ * 2,
        "hue_range": .25 + random.random() * .125,
        "hue_rotation": .875 + random.random() * .1,
        "octaves": OCTAVES,
        "point_freq": 5,
        "saturation": SATURATION * 2,
        "voronoi_refract": .5,
        "voronoi_alpha": .5,
        "voronoi_nth": 1,
        "with_voronoi": 6,
    }

    tensor = generators.multires(shape=shape, **kwargs)

    with tf.Session().as_default():
        save(tensor, MID_FILENAME)
Exemple #15
0
def main(ctx, width, height, channels, time, clut, seed, overrides, name,
         preset_name):
    presets.bake_presets(seed)

    if preset_name == 'random':
        preset_name = 'random-preset'

    kwargs = presets.preset(preset_name)

    print(kwargs['name'])

    kwargs['shape'] = [height, width, channels]
    kwargs['time'] = time

    if 'freq' not in kwargs:
        kwargs['freq'] = 3

    if 'octaves' not in kwargs:
        kwargs['octaves'] = 1

    if 'ridges' not in kwargs:
        kwargs['ridges'] = False

    if clut:
        kwargs['clut'] = clut
        kwargs['clut_horizontal'] = True

    if overrides:
        kwargs.update(json.loads(overrides))

    # print(json.dumps(kwargs, sort_keys=True, indent=4, default=str))

    tensor = generators.multires(**kwargs)

    tensor = recipes.post_process(tensor, **kwargs)

    with tf.Session().as_default():
        save(tensor, name)
Exemple #16
0
def run_preset(preset_name, shape, filename, tensor=None):
    kwargs = presets.preset(preset_name)

    kwargs['shape'] = shape

    if 'freq' not in kwargs:
        kwargs['freq'] = 3

    if 'octaves' not in kwargs:
        kwargs['octaves'] = 1

    if 'ridges' not in kwargs:
        kwargs['ridges'] = False

    kwargs['post_brightness'] = .125

    if tensor is None:
        tensor = generators.multires(**kwargs)

    tensor = recipes.post_process(tensor, **kwargs)

    with tf.Session().as_default():
        save(tensor, filename)
Exemple #17
0
def grime(tensor, shape, time=0.0, speed=1.0):
    """
    """

    value_shape = [shape[0], shape[1], 1]

    mask = multires(5,
                    value_shape,
                    time=time,
                    speed=speed,
                    distrib=ValueDistribution.simplex_exp,
                    octaves=8,
                    refract_range=1.0,
                    refract_y_from_offset=True,
                    deriv=3,
                    deriv_alpha=.5)

    dusty = effects.blend(tensor, .25, tf.square(mask) * .125)

    specks = basic(
        [int(shape[0] * .25), int(shape[1] * .25)],
        value_shape,
        time=time,
        speed=speed,
        distrib=ValueDistribution.simplex_exp,
        refract_range=.1)
    specks = 1.0 - tf.sqrt(effects.normalize(tf.maximum(specks - .5, 0.0)))

    dusty = effects.blend(
        dusty,
        basic([shape[0], shape[1]],
              value_shape,
              time=time,
              speed=speed,
              distrib=ValueDistribution.simplex), .125) * specks

    return effects.blend(tensor, dusty, mask)
Exemple #18
0
def highland():
    shape = [LARGE_Y, LARGE_X, 3]

    kwargs = {
        "deriv": 1,
        "deriv_alpha": 0.25 + random.random() * .125,
        "freq": FREQ * 4,
        "hue_range": .125 + random.random() * .125,
        "hue_rotation": .925 + random.random() * .05,
        "octaves": OCTAVES,
        "point_freq": 8,
        "ridges": True,
        "saturation": SATURATION,
        "voronoi_alpha": .5,
        "voronoi_nth": 3,
        "with_voronoi": 2,
    }

    tensor = generators.multires(shape=shape, **kwargs)

    tensor = tf.image.adjust_brightness(tensor, .1)

    with tf.Session().as_default():
        save(tensor, HIGH_FILENAME)
Exemple #19
0
def main(ctx, freq, width, height, channels, octaves, ridges, post_ridges, sin,
         wavelet, lattice_drift, vortex, warp, warp_octaves, warp_interp,
         warp_freq, reflect, refract, reindex, reverb, reverb_iterations,
         post_reindex, post_reflect, post_refract, clut, clut_horizontal,
         clut_range, ripple, ripple_freq, ripple_kink, worms, worms_density,
         worms_duration, worms_stride, worms_stride_deviation, worms_alpha,
         worms_kink, wormhole, wormhole_kink, wormhole_stride, sobel, outline,
         normals, post_deriv, deriv, deriv_alpha, interp, distrib, corners,
         mask, mask_inverse, posterize, erosion_worms, voronoi, voronoi_func,
         voronoi_nth, voronoi_alpha, voronoi_refract, voronoi_inverse, glitch,
         vhs, crt, scan_error, snow, dither, aberration, light_leak, vignette,
         vignette_brightness, pop, bloom, rgb, hue_range, hue_rotation,
         saturation, saturation_distrib, post_hue_rotation, post_saturation,
         brightness_distrib, input_dir, dla, dla_padding, point_freq,
         point_distrib, point_corners, point_generations, point_drift, shadow,
         density, seed, name, **convolve_kwargs):

    generators.set_seed(seed)

    shape = [height, width, channels]

    tensor = generators.multires(freq=freq,
                                 shape=shape,
                                 octaves=octaves,
                                 ridges=ridges,
                                 post_ridges=post_ridges,
                                 sin=sin,
                                 wavelet=wavelet,
                                 lattice_drift=lattice_drift,
                                 reflect_range=reflect,
                                 refract_range=refract,
                                 reindex_range=reindex,
                                 with_reverb=reverb,
                                 reverb_iterations=reverb_iterations,
                                 post_reindex_range=post_reindex,
                                 post_reflect_range=post_reflect,
                                 post_refract_range=post_refract,
                                 ripple_range=ripple,
                                 ripple_freq=ripple_freq,
                                 ripple_kink=ripple_kink,
                                 clut=clut,
                                 clut_horizontal=clut_horizontal,
                                 clut_range=clut_range,
                                 with_worms=worms,
                                 worms_density=worms_density,
                                 worms_duration=worms_duration,
                                 worms_stride=worms_stride,
                                 worms_stride_deviation=worms_stride_deviation,
                                 worms_alpha=worms_alpha,
                                 worms_kink=worms_kink,
                                 with_wormhole=wormhole,
                                 wormhole_kink=wormhole_kink,
                                 wormhole_stride=wormhole_stride,
                                 with_erosion_worms=erosion_worms,
                                 with_voronoi=voronoi,
                                 voronoi_func=voronoi_func,
                                 voronoi_nth=voronoi_nth,
                                 voronoi_alpha=voronoi_alpha,
                                 voronoi_refract=voronoi_refract,
                                 voronoi_inverse=voronoi_inverse,
                                 with_dla=dla,
                                 dla_padding=dla_padding,
                                 point_freq=point_freq,
                                 point_distrib=point_distrib,
                                 point_corners=point_corners,
                                 point_generations=point_generations,
                                 point_drift=point_drift,
                                 with_outline=outline,
                                 with_sobel=sobel,
                                 with_normal_map=normals,
                                 post_deriv=post_deriv,
                                 deriv=deriv,
                                 deriv_alpha=deriv_alpha,
                                 spline_order=interp,
                                 distrib=distrib,
                                 corners=corners,
                                 mask=mask,
                                 mask_inverse=mask_inverse,
                                 warp_range=warp,
                                 warp_octaves=warp_octaves,
                                 warp_interp=warp_interp,
                                 warp_freq=warp_freq,
                                 posterize_levels=posterize,
                                 vortex_range=vortex,
                                 rgb=rgb,
                                 hue_range=hue_range,
                                 hue_rotation=hue_rotation,
                                 saturation=saturation,
                                 post_hue_rotation=post_hue_rotation,
                                 post_saturation=post_saturation,
                                 brightness_distrib=brightness_distrib,
                                 saturation_distrib=saturation_distrib,
                                 input_dir=input_dir,
                                 with_aberration=aberration,
                                 with_bloom=bloom,
                                 with_pop=pop,
                                 with_light_leak=light_leak,
                                 with_vignette=vignette,
                                 vignette_brightness=vignette_brightness,
                                 with_shadow=shadow,
                                 with_density_map=density,
                                 **convolve_kwargs)

    tensor = recipes.post_process(tensor,
                                  shape=shape,
                                  freq=freq,
                                  with_glitch=glitch,
                                  with_vhs=vhs,
                                  with_crt=crt,
                                  with_scan_error=scan_error,
                                  with_snow=snow,
                                  with_dither=dither)

    with tf.Session().as_default():
        save(tensor, name)

    print(name)
Exemple #20
0
def spatter(tensor, shape, time=0.0, speed=1.0):
    """
    """

    value_shape = [shape[0], shape[1], 1]

    # Generate a smear
    smear = multires(random.randint(2, 4),
                     value_shape,
                     time=time,
                     speed=speed,
                     distrib=ValueDistribution.simplex_exp,
                     ridges=True,
                     octaves=6,
                     spline_order=3)

    smear = effects.warp(
        smear,
        value_shape,
        [random.randint(2, 3), random.randint(1, 3)],
        octaves=random.randint(1, 2),
        displacement=1.0 + random.random(),
        spline_order=3,
        time=time,
        speed=speed)

    # Add spatter dots
    smear = tf.maximum(
        smear,
        multires(random.randint(25, 50),
                 value_shape,
                 time=time,
                 speed=speed,
                 distrib=ValueDistribution.simplex_exp,
                 post_brightness=-.25,
                 post_contrast=4,
                 octaves=4,
                 spline_order=1))

    smear = tf.maximum(
        smear,
        multires(random.randint(200, 250),
                 value_shape,
                 time=time,
                 speed=speed,
                 distrib=ValueDistribution.simplex_exp,
                 post_brightness=-.25,
                 post_contrast=4,
                 octaves=4,
                 spline_order=1))

    # Remove some of it
    smear = tf.maximum(
        0.0, smear - multires(random.randint(2, 3),
                              value_shape,
                              time=time,
                              speed=speed,
                              distrib=ValueDistribution.simplex_exp,
                              ridges=True,
                              octaves=3,
                              spline_order=2))

    #
    if shape[2] == 3:
        splash = tf.image.random_hue(
            tf.ones(shape) * tf.stack([.875, 0.125, 0.125]), .5)

    else:
        splash = tf.zeros(shape)

    return effects.blend_layers(effects.normalize(smear), shape, .005, tensor,
                                splash)