Worley noise cellular pattern

Developer
Size
8,070 Kb
Views
22,264

How do I make an worley noise cellular pattern?

Based on "Cellular Texturing" by Worley Noise http://www.hellopixel.net/experiments/javascript/worley-noise/worley.html. What is a worley noise cellular pattern? How do you make a worley noise cellular pattern? This script and codes were developed by Endre Simo on 28 November 2022, Monday.

Worley noise cellular pattern Previews

Worley noise cellular pattern - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Worley noise cellular pattern</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div style="position:absolute; left:50%; top:50%; margin-left:-450px; margin-top: -300px;"> <div id="main" style="position:relative; display: block; width: 900px; height: 600px;"> <canvas id="canvas" style="position:relative;"></canvas> </div>
</div>
<script> function getIEVersion() { var rv = -1; // Return value assumes failure. if (navigator.appName == 'Microsoft Internet Explorer') { var ua = navigator.userAgent; var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); if (re.test(ua) != null) rv = parseFloat( RegExp.$1 ); } return rv; } function checkVersion() { var ver = getIEVersion(); if ( ver != -1 ) { if (ver <= 9.0) { document.body.innerHTML = ""; document.body.innerHTML = "<p class='no-canvas'>" + "You need a <a href='https://www.google.com/chrome'>modern browser</a> to view this experiment." + "</p>"; } } } checkVersion();
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js" type="text/javascript"></script> <script src="js/index.js"></script>
</body>
</html>

Worley noise cellular pattern - Script Codes CSS Codes

html, body { width: 100%; height: 100%; overflow: hidden; background: #111; margin: 0; padding: 0; -webkit-user-select: none; -moz-user-select: none; -khtml-user-select: none; user-select: none;
}
/*******************************
* Main display
********************************/
div#main { width: 100%; margin: 0 auto; border: 1px solid #222; -webkit-border-radius: 2px; -moz-border-radius: 2px; -ms-border-radius: 2px; -o-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 0px 2px 17px rgba(0,0,0,.80), inset 0 0 15px 15px rgba(5,5,5,.2); -moz-box-shadow: 0px 2px 17px rgba(0,0,0,.80), inset 0 0 15px 15px rgba(5,5,5,.2); box-shadow: 0px 2px 17px rgba(0,0,0,.80), inset 0 0 15px 15px rgba(5,5,5,.2);
}
canvas { width: 740px; height: 480px; float:left; margin-left: 2%; margin-top: 2%; width: 96%; height: 94%; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; border: 1px solid rgba(0,0,0,.2); -webkit-box-shadow: inset 0 0 20px #000; -moz-box-shadow: inset 0 0 20px #000; -ms-box-shadow: inset 0 0 20px #000; box-shadow: inset 0 0 20px #000;
}
.no-canvas { color: #999999; font-size: 24px; text-align: center; margin-top: 150px;
}

Worley noise cellular pattern - Script Codes JS Codes

function CellDataStruct(maxOrder, at) { this.dim = at.length; this.at = at; this.maxOrder = maxOrder; this.F = new Array(maxOrder); this.delta = new Array(new Array(maxOrder), new Array(at.length)); this.ID = new Array(maxOrder);
}
function CellNoise() { this.b32 = Math.pow(2,32); this.Constants = { POISON_COUNT : [ 4, 3, 1, 1, 1, 2, 4, 2, 2, 2, 5, 1, 0, 2, 1, 2, 2, 0, 4, 3, 2, 1, 2, 1, 3, 2, 2, 4, 2, 2, 5, 1, 2, 3, 2, 2, 2, 2, 2, 3, 2, 4, 2, 5, 3, 2, 2, 2, 5, 3, 3, 5, 2, 1, 3, 3, 4, 4, 2, 3, 0, 4, 2, 2, 2, 1, 3, 2, 2, 2, 3, 3, 3, 1, 2, 0, 2, 1, 1, 2, 2, 2, 2, 5, 3, 2, 3, 2, 3, 2, 2, 1, 0, 2, 1, 1, 2, 1, 2, 2, 1, 3, 4, 2, 2, 2, 5, 4, 2, 4, 2, 2, 5, 4, 3, 2, 2, 5, 4, 3, 3, 3, 5, 2, 2, 2, 2, 2, 3, 1, 1, 5, 2, 1, 3, 3, 4, 3, 2, 4, 3, 3, 3, 4, 5, 1, 4, 2, 4, 3, 1, 2, 3, 5, 3, 2, 1, 3, 1, 3, 3, 3, 2, 3, 1, 5, 5, 4, 2, 2, 4, 1, 3, 4, 1, 5, 3, 3, 5, 3, 4, 3, 2, 2, 1, 1, 1, 1, 1, 2, 4, 5, 4, 5, 4, 2, 1, 5, 1, 1, 2, 3, 3, 3, 2, 5, 2, 3, 3, 2, 0, 2, 1, 1, 4, 2, 1, 3, 2, 1, 2, 2, 3, 2, 5, 5, 3, 4, 5, 5, 2, 4, 4, 5, 3, 2, 2, 2, 1, 4, 2, 3, 3, 4, 2, 5, 4, 2, 4, 2, 2, 2, 4, 5, 3, 2 ], DENSITY_ADJUSTMENT : 0.398150, DENSITY_ADJUSTMENT_INV : 1.0 / 0.398150 };
}
CellNoise.prototype.noise = function(cd) { if (cd.dim == 3) { /* * Adjustment variable to make F[0] average 1.0 when using * EUCLIDEAN distance in 3D */ this.Constants.DENSITY_ADJUSTMENT = 0.294631; this.Constants.DENSITY_ADJUSTMENT_INV = 1.0 / this.Constants.DENSITY_ADJUSTMENT; this.noise3D(cd); } else if (cd.dim == 2) { /* * Adjustment variable to make F[0] average at 1.0 when using * EUCLIDEAN distance in 2D */ this.Constants.DENSITY_ADJUSTMENT = 0.294631; this.Constants.DENSITY_ADJUSTMENT_INV = 1.0 / this.Constants.DENSITY_ADJUSTMENT; this.noise2D(cd); }
}
/* * Noise function for three dimensions. * Coordinating the search on the above cube level. * Deciding in which cube to search. */
CellNoise.prototype.noise3D = function (cd) { var x2, y2, z2, mx2, my2, mz2; var newAt = new Array(3); var intAt = new Array(3); var i; for (i = 0; i < cd.maxOrder; i++) { cd.F[i] = Number.POSITIVE_INFINITY; } newAt[0] = this.Constants.DENSITY_ADJUSTMENT * cd.at[0]; newAt[1] = this.Constants.DENSITY_ADJUSTMENT * cd.at[1]; newAt[2] = this.Constants.DENSITY_ADJUSTMENT * cd.at[2]; intAt[0] = ~~newAt[0]; intAt[1] = ~~newAt[1]; intAt[2] = ~~newAt[2]; /* * The center cube. It's very likely that the closest feature * point will be found in this cube. */ this.Add3DSamples(intAt[0], intAt[1], intAt[2], newAt, cd); x2 = newAt[0] - intAt[0]; y2 = newAt[1] - intAt[1]; z2 = newAt[2] - intAt[2]; mx2 = (1.0 - x2) * (1.0 - x2); my2 = (1.0 - y2) * (1.0 - y2); mz2 = (1.0 - z2) * (1.0 - z2); x2 *= x2; y2 *= y2; z2 *= z2; /* * Check the 6 facing cubes from sample location. * These are most likely the closest locations to have feature points */ if ( x2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1], intAt[2], newAt, cd); } if ( y2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1] - 1, intAt[2], newAt, cd); } if ( z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1], intAt[2] - 1, newAt, cd); } if (mx2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1], intAt[2], newAt, cd); } if (my2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1] + 1, intAt[2], newAt, cd); } if (mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1], intAt[2] + 1, newAt, cd); } /* * The 12 edge cubes. These are next closest. */ if ( x2 + y2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1] - 1, intAt[2], newAt, cd); } if ( x2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1], intAt[2] - 1, newAt, cd); } if ( y2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1] - 1, intAt[2] - 1, newAt, cd); } if (mx2 + my2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1] + 1, intAt[2], newAt, cd); } if (mx2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1], intAt[2] + 1, newAt, cd); } if (my2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1] + 1, intAt[2] + 1, newAt, cd); } if ( x2 + my2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1] + 1, intAt[2], newAt, cd); } if ( x2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1], intAt[2] + 1, newAt, cd); } if ( y2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1] - 1, intAt[2] + 1, newAt, cd); } if (mx2 + y2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1] - 1, intAt[2], newAt, cd); } if (mx2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1], intAt[2] - 1, newAt, cd); } if (my2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0], intAt[1] + 1, intAt[2] - 1, newAt, cd); } /* * The 8 corner cubes. */ if ( x2 + y2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1] - 1, intAt[2] - 1, newAt, cd); } if ( x2 + y2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1] - 1, intAt[2] + 1, newAt, cd); } if ( x2 + my2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1] + 1, intAt[2] - 1, newAt, cd); } if ( x2 + my2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1] + 1, intAt[2] + 1, newAt, cd); } if (mx2 + y2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1] - 1, intAt[2] - 1, newAt, cd); } if ( x2 + my2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] - 1, intAt[1] + 1, intAt[2] - 1, newAt, cd); } if (mx2 + y2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1] - 1, intAt[2] + 1, newAt, cd); } if (mx2 + my2 + z2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1] + 1, intAt[2] - 1, newAt, cd); } if (mx2 + my2 + mz2 < cd.F[cd.maxOrder - 1]) { this.Add3DSamples(intAt[0] + 1, intAt[1] + 1, intAt[2] + 1, newAt, cd); } for (i = 0; i < cd.maxOrder; i++) { cd.F[i] = Math.sqrt(cd.F[i] * this.Constants.DENSITY_ADJUSTMENT_INV); cd.delta[i][0] *= this.Constants.DENSITY_ADJUSTMENT_INV; cd.delta[i][1] *= this.Constants.DENSITY_ADJUSTMENT_INV; cd.delta[i][2] *= this.Constants.DENSITY_ADJUSTMENT_INV; }
}
CellNoise.prototype.noise2D = function(cd) { var x2, y2, mx2, my2, i; var newAt = new Array(2); var intAt = new Array(2); for (i=0; i < cd.maxOrder; i++) { cd.F[i] = Number.POSITIVE_INFINITY; } newAt[0] = this.Constants.DENSITY_ADJUSTMENT * cd.at[0]; newAt[1] = this.Constants.DENSITY_ADJUSTMENT * cd.at[1]; intAt[0] = ~~newAt[0]; intAt[1] = ~~newAt[1]; /* * The center cube. It's very likely that the closest feature * point will be found in this cube. */ this.Add2DSamples(intAt[0], intAt[1], newAt, cd); x2 = newAt[0] - intAt[0]; y2 = newAt[1] - intAt[1]; mx2 = (1.0 - x2) * (1.0 - x2); my2 = (1.0 - y2) * (1.0 - y2); x2 *= x2; y2 *= y2; /* * Check the 4 facing cubes from sample location. * These are most likely the closest locations to have feature points */ if ( x2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0] - 1, intAt[1], newAt, cd); } if ( y2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0], intAt[1] - 1, newAt, cd); } if (mx2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0] + 1, intAt[1], newAt, cd); } if (my2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0], intAt[1] + 1, newAt, cd); } /* * Check the 4 square cubes from sample location. * These are probably much distant then the nearby cubes */ if (x2 + y2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0] - 1, intAt[1] - 1, newAt, cd); } if (x2 + my2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0] - 1, intAt[1] + 1, newAt, cd); } if (mx2 + y2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0] + 1, intAt[1] - 1, newAt, cd); } if (mx2 + my2 < cd.F[cd.maxOrder - 1]) { this.Add2DSamples(intAt[0] + 1, intAt[1] + 1, newAt, cd); } for (i = 0; i < cd.maxOrder; i++) { cd.F[i] = Math.sqrt(cd.F[i]) * this.Constants.DENSITY_ADJUSTMENT_INV; cd.delta[i][0] *= this.Constants.DENSITY_ADJUSTMENT_INV; cd.delta[i][1] *= this.Constants.DENSITY_ADJUSTMENT_INV; }
}
/* * Generating the sample points in 3D */
CellNoise.prototype.Add3DSamples = function(xi, yi, zi, at, cd) { var dx, dy, dz, fx, fy, fz, d2, abs = Math.abs; var count, i, j, index, seed, id; /* * Generating a random seed, based on the cube's ID number. The seed might be * better if it were a nonlinear hash like Perlin uses for noise, but we do very * well with this faster simple one. * Our LCG uses Knuth-approved constants for maximal periods. */ seed = this.u32(this.u32(702395077 * xi) + this.u32(915488749 * yi) + this.u32(2120969693 * zi)); // Number of feature points in this cube count = this.Constants.POISON_COUNT[parseInt(0xFF & (seed >> 24))]; seed = this.u32(1402024253 * seed * 586950981); for (j = 0; j < count; j++) { id = seed; seed = this.u32(1402024253 * seed + 586950981); // Compute the 0..1 feature point xyz's location fx = (seed + 0.5) / 4294967296.0; seed = this.u32(1402024253 * seed + 586950981); fy = (seed + 0.5) / 4294967296.0; seed = this.u32(1402024253 * seed + 586950981); fz = (seed + 0.5) / 4294967296.0; seed = this.u32(1402024253 * seed + 586950981); /* Calculate distance from feature point to sample location*/ dx = xi + fx - at[0]; dy = yi + fy - at[1]; dz = zi + fz - at[2]; /* * Distance computation */ if (GUI.renderMethod == 1) { d2 = dx*dx + dy*dy + dz*dz; } else if (GUI.renderMethod == 2) { d2 = Math.max(Math.max(abs(dx), abs(dy)), abs(dz)); d2 *= d2; } else if (GUI.renderMethod == 3) { d2 = abs(dx) + abs(dy) + abs(dz); d2 *= d2; } else if (GUI.renderMethod == 4) { d2 = dx*dx + dy*dy + dz*dz + dx*dy + dx*dz + dy*dz; d2 *= d2; } /* Store the closest points */ //Calculate the closest feature point distance to sample location if (d2 < cd.F[cd.maxOrder - 1]) { index = cd.maxOrder; while(index > 0 && d2 < cd.F[index-1]) { index--; } for (i = cd.maxOrder - 1; i-- > index; ) { cd.F[i + 1] = cd.F[i]; cd.ID[i + 1] = cd.ID[i]; cd.delta[i + 1][0] = cd.delta[i][0]; cd.delta[i + 1][1] = cd.delta[i][1]; cd.delta[i + 1][2] = cd.delta[i][2]; } cd.F[index] = d2; cd.ID[index] = id; cd.delta[index][0] = dx; cd.delta[index][1] = dy; cd.delta[index][2] = dz; } } return this.Add3DSamples;
}
/* * Generating the sample points in 2D */
CellNoise.prototype.Add2DSamples = function(xi, yi, at, cd) { var dx, dy, fx, fy, d2, abs = Math.abs; var count, i, j, index, seed, id; /* * Generating a random seed, based on the cube's ID number. The seed might be * better if it were a nonlinear hash like Perlin uses for noise, but we do very * well with this faster simple one. * Our LCG uses Knuth-approved constants for maximal periods. */ seed = this.u32(this.u32(702395077 * xi) + this.u32(915488749 * yi)); // Number of feature points in this cube count = this.Constants.POISON_COUNT[parseInt(0xFF & (seed >> 24))]; seed = this.u32(1402024253 * seed * 586950981); for (j = 0; j < count; j++) { id = seed; seed = this.u32(1402024253 * seed + 586950981); // Compute the 0..1 feature point xyz's location fx = (seed + 0.5) / 4294967296.0; seed = this.u32(1402024253 * seed + 586950981); fy = (seed + 0.5) / 4294967296.0; seed = this.u32(1402024253 * seed + 586950981); /* Calculate distance from feature point to sample location*/ dx = xi + fx - at[0]; dy = yi + fy - at[1]; /* * Distance computation */ if (GUI.renderMethod === 1) { d2 = dx*dx + dy*dy; } else if (GUI.renderMethod == 2) { d2 = Math.max(abs(dx), abs(dy)); d2 *= d2; } else if (GUI.renderMethod == 3) { d2 = abs(dx) + abs(dy); d2 *= d2; } else if (GUI.renderMethod == 4) { d2 = dx*dx + dy*dy + dx*dy; d2 *= d2; } /* Store the closest points */ if (d2 < cd.F[cd.maxOrder - 1]) { index = cd.maxOrder; while(index > 0 && d2 < cd.F[index-1]) { index--; } for (i = cd.maxOrder - 1; i-- > index;) { cd.F[i + 1] = cd.F[i]; cd.ID[i + 1] = cd.ID[i]; cd.delta[i + 1][0] = cd.delta[i][0]; cd.delta[i + 1][1] = cd.delta[i][1]; } cd.F[index] = d2; cd.ID[index] = id; cd.delta[index][0] = dx; cd.delta[index][1] = dy; } } return this.Add2DSamples;
}
CellNoise.prototype.u32 = function(s) { var st = s % this.b32; if (st < 0) st += this.b32; return st;
}
var noWebWorkers = (function() { var cn, cd, x, y, t = 0, freq = 0.15, at = [0, 0, 0]; var that = this; cn = new CellNoise(); cd = new CellDataStruct(2, at); return { render : function(method, render) { switch (method) { case 'cellDistanceDiff' : cellDistanceDiff(); break; case 'cellDistanceDiffMod' : cellDistanceDiffMod(); break; case 'firstOrderDistance' : firstOrderDistance(); break; case 'secondOrderDistance' : secondOrderDistance(); break; case 'noiseNoise' : noiseNoise(); break; default : draw(); } } }; /* * Different implementation methods provides different outputs. * Playing with values gives completely different shapes and dimensions. */
// Example 1. -> Cell Distance Difference function cellDistanceDiff() { at[2] += freq; t += freq; for (y = 0; y < canvasHeight; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < canvasWidth; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * canvasWidth + x) * 4; imageData.data[index] = cd.F[1] * cd.F[0] * GUI.red; imageData.data[index+1] = cd.F[0] * cd.F[0] * GUI.green; imageData.data[index+2] = cd.F[1] * cd.F[0] * GUI.blue; imageData.data[index+3] = 255; } } ctx.putImageData(imageData, 0, 0); }
// Example 2. -> Cell Distance Difference Modified function cellDistanceDiffMod() { at[2] += freq; t += freq; for (y = 0; y < canvasHeight; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < canvasWidth; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * canvasWidth + x) * 4; imageData.data[index] = cd.F[1] * cd.F[0] * GUI.red; imageData.data[index+1] = cd.F[0] * cd.F[0] + cd.F[1] * GUI.green; imageData.data[index+2] = cd.F[0] * cd.F[1] + cd.F[1] * GUI.blue; imageData.data[index+3] = 255; } } ctx.putImageData(imageData, 0, 0); }
//Example 3. -> First order distance function firstOrderDistance() { at[2] += freq; t += freq; for (y = 0; y < canvasHeight; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < canvasWidth; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * canvasWidth + x) * 4; imageData.data[index] = cd.F[0] * GUI.red; imageData.data[index+1] = cd.F[0] * GUI.green; imageData.data[index+2] = cd.F[0] * GUI.blue; imageData.data[index+3] = 255; } } ctx.putImageData(imageData, 0, 0); }
//Example 4. -> Second order distance function secondOrderDistance() { at[2] += freq; t += freq; for (y = 0; y < canvasHeight; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < canvasWidth; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * canvasWidth + x) * 4; imageData.data[index] = cd.F[1] * GUI.red; imageData.data[index+1] = cd.F[1] * GUI.green; imageData.data[index+2] = cd.F[1] * GUI.blue; imageData.data[index+3] = 255; } } ctx.putImageData(imageData, 0, 0); }
//Example 5. -> Noise noise combination function noiseNoise() { at[2] += freq; t += freq; for (y = 0; y < canvasHeight; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < canvasWidth; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); at[0] = 0.04 * cd.F[0] * (y + 10); at[1] = 0.04 * cd.F[0] * (x + 100); cd.at = at; cn.noise(cd); var index = ~~(y * canvasWidth + x) * 4; imageData.data[index] = (cd.F[1] + cd.F[0]) * GUI.red; imageData.data[index+1] = (cd.F[1] + cd.F[0]) * GUI.green; imageData.data[index+2] = cd.F[0] * GUI.blue; imageData.data[index+3] = 255; } } ctx.putImageData(imageData, 0, 0); } function draw() { var pix, piy; at[2] += freq; //t += freq[2]; for (y = 0; y < canvasHeight; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < canvasWidth; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(((y) * canvasWidth + (x))) * 4; imageData.data[index] = cd.F[1] * cd.F[0] * GUI.red; imageData.data[index+1] = cd.F[0] * cd.F[0] * GUI.green; imageData.data[index+2] = cd.F[1] * cd.F[0] * GUI.blue; imageData.data[index+3] = 255; } } ctx.putImageData(imageData, 0, 0); }
}).call(this);
//importScripts('CellNoise.js' , 'CellDataStruct.js');
var x, y, t = 0, freq = freq || [0.8, 0.8, 0.1], at = at || [0, 0, 0];
var cn = cn ? cn : new CellNoise();
var cd = cd ? cd : new CellDataStruct(2, at);
var withOutWorker = false;
function renderScene(method, img, width, height) { this.method = method; switch (method) { case 'cellDistanceDiff' : cellDistanceDiff(img, width, height); // self.postMessage({ 'image' : img, 'method' : method }); break; case 'firstOrderDistance' : firstOrderDistance(img, width, height); self.postMessage({ 'image' : img, 'method' : method }); break; case 'secondOrderDistance' : secondOrderDistance(img, width, height); // self.postMessage({ 'image' : img, 'method' : method }); break; case 'fractalNoise' : noiseNoise(img, width, height); // self.postMessage({ 'image' : img, 'method' : method }); break; default : draw(img, width, height); // self.postMessage({ 'image' : img, 'method' : method }); }
}
self.onmessage = function(event) { if (event.data.message === 'render' && event.data.method === this.method) { renderScene(event.data.method, event.data.image, event.data.image.width, event.data.image.height); } if (withOutWorker) self.close();
}
/* * Different implementation methods provides different outputs. * Playing with values gives completely different shapes and dimensions. */
// Example 1. -> Cell Distance Difference
function cellDistanceDiff(img, w, h) { at[2] += freq; t += freq; for (y = 0; y < h; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < w; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * w + x) * 4; img.data[index] = cd.F[1] * cd.F[0] * GUI.red; img.data[index+1] = cd.F[0] * cd.F[0] * GUI.green; img.data[index+2] = cd.F[1] * cd.F[0] * GUI.blue; img.data[index+3] = 255; } } ctx.putImageData(img, 0, 0);
}
// Example 2. -> Cell Distance Difference Modified
function cellDistanceDiffMod(img, w, h) { at[2] += freq; t += freq; for (y = 0; y < h; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < w; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * w + x) * 4; img.data[index] = cd.F[1] * cd.F[0] * GUI.red; img.data[index+1] = cd.F[0] * cd.F[0] + cd.F[1] * GUI.green; img.data[index+2] = cd.F[0] * cd.F[1] + cd.F[1] * GUI.blue; img.data[index+3] = 255; } } ctx.putImageData(img, 0, 0);
}
//Example 3. -> First order distance
function firstOrderDistance(img, w, h) { at[2] += freq; t += freq; for (y = 0; y < h; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < w; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * w + x) * 4; img.data[index] = cd.F[0] * GUI.red; img.data[index+1] = cd.F[0] * GUI.green; img.data[index+2] = cd.F[0] * GUI.blue; img.data[index+3] = 255; } } ctx.putImageData(img, 0, 0);
}
//Example 4. -> Second order distance
function secondOrderDistance(img, w, h) { at[2] += freq; t += freq; for (y = 0; y < h; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < w; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(y * w + x) * 4; img.data[index] = cd.F[1] * GUI.red; img.data[index+1] = cd.F[1] * GUI.green; img.data[index+2] = cd.F[1] * GUI.blue; img.data[index+3] = 255; } } ctx.putImageData(img, 0, 0);
}
//Example 5. -> Noise noise combination
function noiseNoise(img, w, h) { at[2] += freq; t += freq; for (y = 0; y < h; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < w; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); at[0] = 0.04 * cd.F[0] * (y + 10); at[1] = 0.04 * cd.F[0] * (x + 100); cd.at = at; cn.noise(cd); var index = ~~(y * w + x) * 4; img.data[index] = (cd.F[1] + cd.F[0]) * GUI.red; img.data[index+1] = (cd.F[1] + cd.F[0]) * GUI.green; img.data[index+2] = cd.F[0] * GUI.blue; img.data[index+3] = 255; } } ctx.putImageData(img, 0, 0);
}
function draw(img, w, h) { var pix, piy; at[2] += freq; //t += freq[2]; for (y = 0; y < h; y ++) { at[0] = GUI.cellDimension * (y + t); for (x = 0; x < w; x ++) { at[1] = GUI.cellDimension * (x + t); cd.at = at; cn.noise(cd); var index = ~~(((y) * w + (x))) * 4; img.data[index] = cd.F[1] * cd.F[0] * GUI.red; img.data[index+1] = cd.F[0] * cd.F[0] * GUI.green; img.data[index+2] = cd.F[1] * cd.F[0] * GUI.blue; img.data[index+3] = 255; } } ctx.putImageData(img, 0, 0);
}
(function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); };
}());
var keyPressed = false;
var ctx, canvas, canvasWidth, canvasHeight, imageData, gui, controller, random = Math.random, reachRedMax = false, reachRedMin = false, reachGreenMax = false, reachGreenMin = false, reachBlueMax = false, reachBlueMin = false, increaseRed = true, increaseGreen = true, increaseBlue = true;
var GUI = new function() { this.renderMethod = 1; this.renderFunction = 'cellDistanceDiffMod'; this.title = 'Worley Noise'; this.cellDimension = 0.14; this.red = 120; this.green = 150; this.blue = 150; this.colorize = false; this.reset = function() { this.renderMethod = 1; this.renderFunction = 'cellDistanceDiffMod'; this.title = 'Worley Noise'; this.cellDimension = 0.14; this.red = 120; this.green = 150; this.blue = 150; }
};
function createUI() { gui = new dat.GUI({autoPlace:false, width: 270, align: "left"}); gui.domElement.style.position = 'relative'; gui.domElement.style.top = '40px'; gui.domElement.style.left = '50px'; document.body.appendChild(gui.domElement); //gui.remember(GUI); //gui.add(GUI, 'title').name('Title'); gui.add(GUI, 'renderMethod').options({ 'Euclidean': 1, 'Cityblock': 2, 'Manhattan': 3, 'Quadratic': 4}).name('Render Method'); gui.add(GUI, 'renderFunction').options( ['cellDistanceDiffMod', 'cellDistanceDiff','firstOrderDistance', 'secondOrderDistance', 'noiseNoise']).name('Render Function'); gui.add(GUI, 'cellDimension').min(0.05).max(0.18).step(0.01).name('Cell Dimension'); gui.add(GUI, 'red').min(20).max(255).step(1).name('Red value').listen().onChange(disableAutoColor); gui.add(GUI, 'green').min(20).max(255).step(1).name('Green value').listen().onChange(disableAutoColor); gui.add(GUI, 'blue').min(20).max(255).step(1).name('Blue value').listen().onChange(disableAutoColor); // gui.add(GUI, 'withWorkers').name('With Webworkers'); // Disable Web Workers // gui.add(GUI, 'withOutWorkers').name('Without Webworkers'); gui.add(GUI, 'reset').name('Reset'); controller = gui.add(GUI, 'colorize').name('Autocolor').onFinishChange(function(e) { autoColorize(); })
}
function disableAutoColor() { GUI.colorize = false; controller.setValue(false);
}
function autoColorize() { if (GUI.colorize == false) return; requestAnimationFrame(autoColorize); //Lame method to test each value, but some handwork do not harm :) if (reachRedMin && increaseRed) GUI.red++; else if (reachRedMax && !increaseRed) GUI.red--; if (!reachRedMax && increaseRed) GUI.red++; if (reachGreenMin && increaseGreen) GUI.green++; else if (reachGreenMax && !increaseGreen) GUI.green--; if (!reachGreenMax && increaseGreen) GUI.green++; if (reachBlueMin && increaseBlue) GUI.blue++; else if (reachBlueMax && !increaseBlue) GUI.blue--; if (!reachBlueMax && increaseBlue) GUI.blue++; if (parseInt(GUI.red, 10) == 255){ reachRedMax = true; increaseRed = false; } else if (parseInt(GUI.red, 10) == 10) { reachRedMin = true; increaseRed = true; } if (parseInt(GUI.green, 10) == 255){ reachGreenMax = true; increaseGreen = false; } else if (parseInt(GUI.green, 10) == 10) { reachGreenMin = true; increaseGreen = true; } if (parseInt(GUI.blue, 10) == 255){ reachBlueMax = true; increaseBlue = false; } else if (parseInt(GUI.blue, 10) == 10) { reachBlueMin = true; increaseBlue = true; }
}
function init(width, height) { canvasWidth = (width !== undefined) ? width : 200; canvasHeight = (height !== undefined) ? height : 200; canvas = document.getElementById('canvas'); canvas.setAttribute('width', canvasWidth); canvas.setAttribute('height', canvasHeight); ctx = canvas.getContext('2d'); imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
}
createUI();
init(150, 90);
renderWithoutWorkers();
function render(method, canvas, iterations) { var context = canvas.getContext('2d'); for(var i=0; i < iterations; i++) { startWorker(method, context, i); }
}
function startWorker(method, context, threadId) { var img = context.createImageData(canvasWidth, canvasHeight); var worker = new Worker('Worker.js'); worker.onmessage = function(event) { var buffImg = context.getImageData(0, 0, canvasWidth, canvasHeight); var threadImg = event.data.image; var tf = 1.0 / threadId; var bf = 1.0 - tf; for (var i=0; i < threadImg.data.length; i++) { threadImg.data[i] = (threadImg.data[i] * tf) + (buffImg.data[i] * bf); } context.putImageData(threadImg, 0, 0); worker.postMessage({ 'message' : 'render', 'image' : img, 'threadId' : threadId, 'method' : method }); } worker.onerror = function(event) { console.log('Worker error on', threadId); throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")"); } worker.postMessage({ 'message' : 'render', 'image' : img, 'threadId' : threadId, 'method' : method }); return worker;
}
function renderWithWorkers() { requestAnimationFrame(renderWithWorkers); render(GUI.renderFunction, canvas, 2); window.addEventListener('keypress', function(event) { if (event.ctrlKey && event.keyCode == 72) keyPressed = !keyPressed; }, false); if (keyPressed) stats.style.display = 'none';
}
function renderWithoutWorkers() { requestAnimationFrame(renderWithoutWorkers); noWebWorkers.render(GUI.renderFunction, GUI.renderMethod); window.addEventListener('keypress', function(event) { if (event.ctrlKey && event.keyCode == 72) keyPressed = !keyPressed; }, false); if (keyPressed) stats.style.display = 'none';
}
Worley noise cellular pattern - Script Codes
Worley noise cellular pattern - Script Codes
Home Page Home
Developer Endre Simo
Username esimov
Uploaded November 28, 2022
Rating 3.5
Size 8,070 Kb
Views 22,264
Do you need developer help for Worley noise cellular pattern?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Endre Simo (esimov) Script Codes
Create amazing video scripts with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!