How I made my first Generative Art NFT called Roses

How I made my first Generative Art NFT called Roses

Project Link:
https://www.fxhash.xyz/generative/20694?ref=matej-konrad

A little over a year ago, I discovered the captivating world of generative art created through code. I was fascinated by the endless possibilities of this creative medium and was eager to try my hand at generating my unique piece of art.

I began my journey into creative coding by delving into Processing & p5js, immersing myself in tutorials, and engaging with communities on Twitter and discord.

While exploring, I discovered a fascinating website called fx(hash). This platform is designed to create and distribute generative art tokens on the tezos blockchain, where anyone can publish their generative art piece (or generative token) and hopes it gets fully minted.

Then, after a couple of months of sketching, prototyping, and learning about the techniques, I could not stop thinking about an output I made while trying to re-create Roses.

How roses came to life

Roses is a generative art token published on fx(hash) representing a bouquet of roses. As said before, I was trying to recreate a rose with code.
First, I started experimenting with a technique to draw the center and the leaves around it, but nothing worked.

I had an idea, what if I drew a spiral, then put some noise on it, and voila, I got a pretty looking rose!

So how does it work?

How to generate roses with code?

Here is a simple representation of the drawing algorithm

function Rose(_x, _y) {
	const steps = 10
	const r = 30
	const theta = 1
	let x = _x;
	let y = _y;

	// The function used to add the noise
	const addNoise = (x, y, to) => {
		const spX = map(x, 0, width, 0, spacesX);
		const spY = map(y, 0, height, 0, spacesY);
		return to + map(noise(spX, spY), 0, 1, -noiseLevel, noiseLevel)
	};
	
	function drawRose() {
		beginShape();
		for (let i = 0; i < steps; i++) {
		  curveVertex(x, y);
		  x = x + addNoise(x, y, cos(theta)) * r;
		  y = y + addNoise(y, y, sin(theta)) * r;
		  theta += 0.1;
		  r += 0.03;
		}
		endShape();
	};

	return { drawRose }
}

The code defines a function draw() that draws a shape using a curve vertex approach.

The rose is generated by looping through steps (which is set to 10) and using a set of equations to calculate the x and y coordinates for each vertex. The equation used to calculate the x and y values use the addNoise function, which adds randomness to the shape by mapping a noise value to the x and y coordinates.

In each iteration of the loop, the value  r increases by 0.03 and theta increases by 0.1. The value of r is used as a scaling factor, while theta is used to calculate the x and y values based on the polar coordinates of a point. The cos and sin functions convert the polar coordinates to Cartesian coordinates.

The beginShape and endShape functions are p5.js functions used to define the start and end of a shape drawn with the curveVertex function, which is also part of p5.js.

After this, we can iterate through creating a couple of these roses, which makes a "bouquet" of them.

Frame

I have decided to add a rectangular frame to this generative art piece as it encapsulates the art better than without. In addition, it gives a sense of completeness and makes you focus on the center of the image.

It's generated using four rectangles, each going from corner to corner around the edges of the sketch.

Choosing the colors

Colors must have been the most challenging part for me. I searched the internet for the colors and panicked a lot about it. In the end, I searched for inspiration on the internet but still made the selection myself, as I wanted the colors to be authentic.

My favorite color palette must be the one called Doom. I got the inspiration for this palette while listening to MF Doom's album called "MM... Food"
![[Screenshot 2023-02-13 at 20.59.26.png]]
MM... FOOD album cover

![[Pasted image 20230213205831.png]]
Roses #15
https://www.fxhash.xyz/gentk/1246836

Find colors with enough contrast

While working with palettes, I wanted to pass on the following when selecting the color palette:

const color = {
    name: 'Doom',
    colors: [
      '#a43d34',
      '#a6b95d',
      '#000000',
      '#d3d1dc',
      '#8c5b61',
      '#eaddca',
      '#fefffd',
    ],
}

I quickly stumbled on a problem. Some colors did not have enough of a contrast between each other.

I searched through stack overflow and found the following piece of awesome code.

function luminance(r, g, b) {
  const a = [r, g, b].map((v) => {
    v /= 255;
    return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
  });
  return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}

function contrast(rgb1, rgb2) {
  var lum1 = luminance(rgb1[0], rgb1[1], rgb1[2]);
  var lum2 = luminance(rgb2[0], rgb2[1], rgb2[2]);
  var brightest = Math.max(lum1, lum2);
  var darkest = Math.min(lum1, lum2);
  return (brightest + 0.05) / (darkest + 0.05);
}

The luminance function takes in 3 parameters: r, g, and b, which represent the red, green, and blue values of color, respectively. It maps each color value to a number between 0 and 1 and performs a calculation to determine the luminance of the color, which is a measure of the color's perceived brightness. The calculation is based on the formula for the relative luminance specified in the W3C's Web Content Accessibility Guidelines (WCAG).

The contrast function takes in two arrays, rgb1 and rgb2, representing two colors. The function calculates the luminance of each color using the luminance function and then uses the luminance values to determine the contrast between the two colors. The contrast ratio is calculated as the ratio of the brightest color's luminance to the darkest color's luminance. The resulting ratio is returned by the contrast function.

Publishing

After creating the sketch, adding the frame, and choosing the colors, publishing it on fx(hash) was time.

At first, I struggled with publishing, as the outputs were always different for different hashes.

After a couple of hours, I figured it out, and it was time!

I also wrote a blog post about some tips on publishing the fx(hash) token. Check it out:
https://www.konradmatej.com/how-to-make-genart-ready-for-fxhash/

Minting

After publishing, you must wait 3 hours for the sketch to be live. This is the default for fx(hash) creators new to the platform.

I was super nervous if anyone would like the artwork.
The mint started at 25 Oct 2022 at 22:12:14
https://tzkt.io/op2cXJqm8qjadNfbM21uQ4XbGrBun1DmZCuzSLGZE9o6LhMiP3y/68753720

I went to sleep and completely forgot about the mint since I had an overwhelmingly busy day at work. Then I remembered. I checked it at around 16:00, and voila:
Mint completed on 26 Oct 2022 at 14:52:59
https://tzkt.io/oozLkmZbPi5QvsVhVZwoQ6J4h7EDFbQ5A3Z9VV5W7G7ufKBPD33/62885823

I felt amazing! The work I have put into this has proven valuable since people liked it enough to spend 1 Tezos on it, at least. It was a great feeling of validation!

Conclusion

In conclusion, while the hype around Roses may have died down since its launch, it remains an actively traded NFT on the fx(hash) marketplace.

If you want to acquire one, you can get one on fx(hash).

Thanks for reading! And thanks to all the people that have minted and supported the project. 👋