Skip to content

Instantly share code, notes, and snippets.

@Szaq
Last active May 27, 2019 13:05
Show Gist options
  • Save Szaq/ac194a29d4c3a2a97c30f869c2ea0579 to your computer and use it in GitHub Desktop.
Save Szaq/ac194a29d4c3a2a97c30f869c2ea0579 to your computer and use it in GitHub Desktop.
vector custom_random(vector Seed, vector Pixelator, float RandomSeed, float Division) {
return hashnoise(Pixelator * 2343249.2 + Seed * RandomSeed);
}
float count_treshold(float RandomizedCount, float Count) {
float Mix = Count < 0 ? (1 - RandomizedCount) : RandomizedCount;
return Mix < abs(Count);
}
float clipping_mask(vector Vector, float CountTreshold) {
return (Vector[0] > 0 && Vector[0] < 1 && Vector[1] > 0 && Vector[1] < 1) ? CountTreshold : 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 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,
int Layers = 1,
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 RandomMultiplier = 19.0,
vector LayerOffset = 0.5,
float RandomProfile = 0.0,
float XYRatio = 1.0,
string DiffuseTexture = "",
string RoughnessTexture = "",
string MetallicTexture = "",
string NormalTexture = "",
string HeightTexture = "",
output color DiffuseOutput = 0.0,
output color RoughnessOutput = 0.0,
output color MetallicOutput = 0.0,
output color NormalOutput = 0.0,
output color HeightOutput = 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)
{
DiffuseOutput = 0;
RoughnessOutput = 0.0;
MetallicOutput = 0.0;
NormalOutput = 0.0;
HeightOutput = 0.0;
ClippingMask = 0.0;
Random1 = 0.0;
Random2 = 0.0;
Random3 = 0.0;
Random4 = 0.0;
for (int layer = 0; layer < Layers; layer++) {
vector ModBase = vector(1 / Division);
vector AbsBase = (InputMap + layer * LayerOffset)/ModBase;
vector Sawtooth = (AbsBase - floor(AbsBase)) * ModBase;//fmod(abs(InputMap), vector(1 / Division));
vector Pixelator = (InputMap + layer * LayerOffset) - Sawtooth;
vector AngleSizeCount = custom_random(vector(9.7, 6.9, 13), Pixelator, RandomSeed * RandomMultiplier * layer, Division);
float RandomizedAngle = mix(AngleSizeCount[0], smoothstep(0, 1, AngleSizeCount[0]), RandomProfile);
float RandomizedSizeUnscaled = mix(AngleSizeCount[1], smoothstep(0, 1, AngleSizeCount[1]),RandomProfile);
float RandomizedSize = mix(IndividualSize, RandomizedSizeUnscaled * IndividualSize, RandomSize);
float RandomizedCount = AngleSizeCount[2];
vector OffsetOutputRandom = custom_random(vector(12.2, 1.3, 2.70), Pixelator, RandomSeed * RandomMultiplier * layer, Division);
float RandomizedOffset = mix(OffsetOutputRandom[0], smoothstep(0, 1, OffsetOutputRandom[0]), RandomProfile);
float RandomizedOutput = mix(OffsetOutputRandom[1], smoothstep(0, 1, OffsetOutputRandom[1]), RandomProfile);
vector ExtraRandomOutput = custom_random(vector(-4.5, 0.3, 16.900), Pixelator, RandomSeed * RandomMultiplier * layer, Division);
vector RandomizedLocation = randomize_location(Sawtooth * Division, 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 Vector = cell_rotation(RandomizedLocation, RandomAngle, RandomizedSize, XYRatio);
float CurrentClippingMask = clipping_mask(Vector, count_treshold(RandomizedCount, Count));
Random1 += OffsetOutputRandom[2] * CurrentClippingMask;
Random2 += ExtraRandomOutput[0] * CurrentClippingMask;
Random3 += ExtraRandomOutput[1] * CurrentClippingMask;
Random4 += ExtraRandomOutput[2] * CurrentClippingMask;
OutRandomSize = mix(1, RandomizedSize, RandomSize);
OutRandomRotation = RandomizedAngle * RandomRotation / 360;
float Alpha = 0;
vector CurrentDiffuse = texture(DiffuseTexture, Vector[0], Vector[1],"interp","closest", "alpha", Alpha);
DiffuseOutput = DiffuseOutput * (1 - CurrentClippingMask * Alpha) + CurrentDiffuse * CurrentClippingMask * Alpha;
RoughnessOutput = RoughnessOutput * (1 - CurrentClippingMask * Alpha) + texture(RoughnessTexture, Vector[0], Vector[1],"interp","closest") * CurrentClippingMask * Alpha;
MetallicOutput = MetallicOutput * (1 - CurrentClippingMask * Alpha) + texture(MetallicTexture, Vector[0], Vector[1],"interp","closest") * CurrentClippingMask * Alpha;
NormalOutput = NormalOutput * (1 - CurrentClippingMask * Alpha) + texture(NormalTexture, Vector[0], Vector[1],"interp","closest") * CurrentClippingMask * Alpha;
HeightOutput += texture(HeightTexture, Vector[0], Vector[1],"interp","closest") * CurrentClippingMask;
ClippingMask += CurrentClippingMask * Alpha;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment