Created
February 5, 2019 14:21
-
-
Save Szaq/b2dbdc0956e6c5917d43eef514e655bd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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