//- number of polygon vertices and rounding precision
- let n = 7, p = 2;
//- base (central angle) in degres & radians
- let deg = 360/n, rad = 2*Math.PI/n;
//- vertex & gradient array
- let v = [], g = [];

//- create gradient stack for background (mesh gradient emulation)
- for(let i = 0; i < n; i++)
	//- current angle in radians
	- let ca = i*rad;
	//- add to array of vertex coords
	- v.push(['cos', 'sin'].map(f => +(50*(1 + Math[f](ca))).toFixed(p)));
	// current angle in degrees incl. gradient start offset
	- ca = (i*deg + 90)%360;
	// add to array of gradient baxkground layers
	- g.push(`linear-gradient(${ca}deg, hsl(${ca}, 100%, 0%), hsl(${ca}, 100%, 65%))`);

body(style=`--v: ${v.map(p => p.map(c => `${c}%`).join(' ')).join(',')}; --b: ${g.join(', ')}`)
	// contains nothing but filter => functionally same as a style elem
	// zero its dimensions and hide it from screen readers
	svg(width='0' height='0' aria-hidden='true')
		// sRGB is what we normally want (but not default)
		filter#grain(color-interpolation-filters='sRGB')
			// generate fine noise
			feTurbulence(type='fractalNoise' baseFrequency='.713' numOctaves='3')
			// use noise as displacement map
			feDisplacementMap(in='SourceGraphic' scale='99' xChannelSelector='R')
			// place filter input underneath to cover transparent edge pixels
			feBlend(in2='SourceGraphic')
			// bump up saturation
			//feColorMatrix(type='saturate' values='1.125')
	// the polygons
	.poly
	.poly
View Compiled
/* take out of document flow */
svg[height='0'][aria-hidden='true'] { position: fixed }

.poly {
	display: inline-block;
	width: clamp(8em, 45vw, 50em);
	aspect-ratio: 1;
	background: var(--b);
	background-blend-mode: lighten;
	clip-path: polygon(var(--v));
	
	& + & { filter: url(#grain) }
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.