Skip to content

Instantly share code, notes, and snippets.

@Szaq
Created February 5, 2019 14:21
Show Gist options
  • Save Szaq/b2dbdc0956e6c5917d43eef514e655bd to your computer and use it in GitHub Desktop.
Save Szaq/b2dbdc0956e6c5917d43eef514e655bd to your computer and use it in GitHub Desktop.
vector sawtooth(vector Input, vector DividedScale, vector DividedOffset) {
vector Offseted = Input - DividedOffset;
vector Absolute = abs(Offseted);
vector Normalized = Offseted / Absolute;
vector Squared = Normalized * Offseted;
vector Modulo = fmod(Squared, DividedScale) / DividedScale;
vector Inverted = 1 - Modulo;
return 1 - ((1 - Normalized) * Modulo + Normalized * Inverted);
}
vector pixelator(vector InputMap, float Division, vector Scale, vector Offset) {
vector DividedOffset = Offset / Division;
vector DividedScale = Scale / Division;
return InputMap - sawtooth(InputMap, DividedScale, DividedOffset) * DividedScale;
}
vector cellnoise_color(vector p)
{
float r = cellnoise(p);
float g = cellnoise(point(p[1], p[0], p[2]));
float b = cellnoise(point(p[1], p[2], p[0]));
return vector(r, g, b);
}
vector cells_distance_closest_voronoi(vector Vector, float Scale) {
vector p = Vector * Scale;
vector pa[4];
float da[4];
int xx, yy, zz, xi, yi, zi;
xi = (int)floor(p[0]);
yi = (int)floor(p[1]);
zi = (int)floor(p[2]);
da[0] = 1e10;
da[1] = 1e10;
da[2] = 1e10;
da[3] = 1e10;
for (xx = xi - 1; xx <= xi + 1; xx++) {
for (yy = yi - 1; yy <= yi + 1; yy++) {
for (zz = zi - 1; zz <= zi + 1; zz++) {
vector ip = vector(xx, yy, zz);
vector vp = cellnoise_color(ip);
vector pd = p - (vp + ip);
float d = dot(pd, pd);
vp += vector(xx, yy, zz);
if (d < da[0]) {
da[3] = da[2];
da[2] = da[1];
da[1] = da[0];
da[0] = d;
pa[3] = pa[2];
pa[2] = pa[1];
pa[1] = pa[0];
pa[0] = vp;
}
else if (d < da[1]) {
da[3] = da[2];
da[2] = da[1];
da[1] = d;
pa[3] = pa[2];
pa[2] = pa[1];
pa[1] = vp;
}
else if (d < da[2]) {
da[3] = da[2];
da[2] = d;
pa[3] = pa[2];
pa[2] = vp;
}
else if (d < da[3]) {
da[3] = d;
pa[3] = vp;
}
}
}
}
return cellnoise_color(pa[0]);
}
vector randomize_location(vector Sawtooth, float OffsetPhaseShiftRad, float RandomizedOffset, float RandomizedOutput, float RandomOffset) {
float SinOffsetPhaseShift = sin(OffsetPhaseShiftRad);
float CosOffsetPhaseShift = cos(OffsetPhaseShiftRad);
float NormalizedOffset = (RandomizedOffset- 0.5) * 2;
float NormalizedOutput = (RandomizedOutput- 0.5) * 2;
return vector(NormalizedOffset * CosOffsetPhaseShift - NormalizedOutput * SinOffsetPhaseShift,
NormalizedOffset * SinOffsetPhaseShift + NormalizedOutput * CosOffsetPhaseShift,
0) * RandomOffset + Sawtooth;
}
vector custom_random(vector Seed, vector Pixelator, float RandomSeed, float Division) {
return pow(cells_distance_closest_voronoi(Pixelator + Seed * RandomSeed, 21.185 * Division), 0.75);
}
float count_treshold(float RandomizedCount, float Count) {
float Alpha = Count < 0;
float Mix = (1 - RandomizedCount) * Alpha + RandomizedCount * (1 - Alpha);
return Mix < abs(Count) ? 1 : 0;
}
float clipping_mask(vector Vector, float CountTreshold) {
return (Vector[0] > 0 && Vector[0] < 1 && Vector[1] > 0 && Vector[1] < 1) ? CountTreshold : 0;
}
vector cell_rotation(vector RandomizedLocation, float RandomAngle, float RandomSize, float XYRatio) {
float SquareRootXYRatio = sqrt(XYRatio);
vector CenteredLocation = RandomizedLocation - 0.5;
vector SinLocation = CenteredLocation * sin(RandomAngle);
vector CosLocation = CenteredLocation * cos(RandomAngle);
return vector(CosLocation[0] - SinLocation[1], SinLocation[0] + CosLocation[1], 0.0)
* vector(1.0 / SquareRootXYRatio, SquareRootXYRatio, 0.0)
/ RandomSize
+ 0.5;
}
shader scatter_material(
vector InputMap = 0,
float Count = 1,
float Division = 10,
float IndividualSize = 0.5,
float RandomSize = 0.0,
float Rotation = 0.0,
float RandomRotation = 0.0,
float RotationSteps = 0.0,
float RandomOffset = 0.0,
float OffsetPhaseShift = 0.0,
float RandomSeed = 0.0,
float RandomProfile = 0.0,
float XYRatio = 1.0,
output vector Vector = 0.0,
output float ClippingMask = 0.0,
output float OutRandomSize = 0.0,
output float OutRandomRotation = 0.0,
output float Random1 = 0.0,
output float Random2 = 0.0,
output float Random3 = 0.0,
output float Random4 = 0.0)
{
vector Pixelator = pixelator(InputMap, Division, 1, 0);
vector AngleSizeCount = custom_random(vector(9.7, 6.9, 13), Pixelator, RandomSeed, Division);
float RandomizedAngle = smoothstep(0, 1, AngleSizeCount[0]) * RandomProfile + AngleSizeCount[0] * (1 - RandomProfile);
float RandomizedSizeUnscaled = smoothstep(0, 1, AngleSizeCount[1]) * RandomProfile + AngleSizeCount[1] * (1 - RandomProfile);
float RandomizedSize = IndividualSize * (1 - RandomSize) + RandomizedSizeUnscaled * IndividualSize * RandomSize;
float RandomizedCount = AngleSizeCount[2];
vector OffsetOutputRandom = custom_random(vector(12.2, 1.3, 2.70), Pixelator, RandomSeed, Division);
float RandomizedOffset = smoothstep(0, 1, OffsetOutputRandom[0]) * RandomProfile + OffsetOutputRandom[0] * (1 - RandomProfile);
float RandomizedOutput = smoothstep(0, 1, OffsetOutputRandom[1]) * RandomProfile + OffsetOutputRandom[1] * (1 - RandomProfile);
vector ExtraRandomOutput = custom_random(vector(-4.5, 0.3, 16.900), Pixelator, RandomSeed, Division);
vector RandomizedLocation = randomize_location(sawtooth(InputMap, 1 / Division, 0), radians(OffsetPhaseShift), RandomizedOffset, RandomizedOutput, RandomOffset / 200);
float RandomRotationRad = radians(RandomRotation);
float ScaledRandomAngle = RandomizedAngle * RandomRotationRad;
float RandomAngle = ScaledRandomAngle + radians(Rotation) - (abs(RandomRotationRad) > 0 ? fmod(ScaledRandomAngle, radians(RotationSteps)) : 0.0);
vector RotatedLocation = cell_rotation(RandomizedLocation, RandomAngle, RandomizedSize, XYRatio);
Vector = vector(RotatedLocation[0], RotatedLocation[1], 0);
ClippingMask = clipping_mask(RotatedLocation, count_treshold(RandomizedCount, Count));
Random1 = OffsetOutputRandom[2];
Random2 = ExtraRandomOutput[0];
Random3 = ExtraRandomOutput[1];
Random4 = ExtraRandomOutput[2];
OutRandomSize = 1 * (1 - RandomSize) + RandomizedSize * RandomSize;
OutRandomRotation = RandomizedAngle * RandomRotation / 360;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment