public override void EmitDefs(StringBuilder outCode) { //If using customized Worley noise, we need to emit a custom function to call in the shader. if (NoiseType != NoiseTypes.Worley || IsWorleyDefault) { return; } outCode.Append("#define DIST(a, b) ("); outCode.AppendLine(Worley_DistanceCalc.Replace("$1", "a").Replace("$2", "b") + ")"); outCode.Append("#define OUTVAL(a, b) ("); outCode.AppendLine(Worley_NoiseCalc.Replace("$1", "a").Replace("$2", "b") + ")"); outCode.AppendLine("#define INSERT_MIN(a, b, new) if (new < a) { b = a; a = new; } else { b = min(b, new); }"); if (Wraps) { outCode.AppendLine("#define WORLEY_POS(p, nDims) (p + lerp(0.5 - cellVariance, 0.5 + cellVariance, hashTo##nDims(WRAP(p))))"); } else { outCode.AppendLine("#define WORLEY_POS(p, nDims) (p + lerp(0.5 - cellVariance, 0.5 + cellVariance, hashTo##nDims(p)))"); } outCode.Append("float "); outCode.Append(GetFunc(NoiseType, NDimensions, Wraps)); if (NDimensions == 1) { outCode.Append("(float seed, float cellVariance"); if (Wraps) { outCode.Append(", float valMax"); } outCode.AppendLine(@") { float cellThis = floor(seed), cellLess = cellThis - 1.0, cellMore = cellThis + 1.0; float noise1 = DIST(WORLEY_POS(cellThis, 1), seed), noise2 = DIST(WORLEY_POS(cellLess, 1), seed), noise3 = DIST(WORLEY_POS(cellMore, 1), seed); float min1 = min(noise1, noise2), min2 = max(noise1, noise2); INSERT_MIN(min1, min2, noise3); return OUTVAL(min1, min2); }"); } else if (NDimensions == 2) { outCode.Append("(float2 seed, float2 cellVariance"); if (Wraps) { outCode.Append(", float2 valMax"); } outCode.AppendLine(@") { float2 centerCell = floor(seed); float min1, min2; const float3 c = float3(-1.0, 0.0, 1.0); //Calculate the first two noise values and store them in min1/min2. float2 cellPos = centerCell; float cellNoise = DIST(WORLEY_POS(cellPos, 2), seed); { cellPos = centerCell + c.xx; float cellNoise2 = DIST(WORLEY_POS(cellPos, 2), seed); min1 = min(cellNoise2, cellNoise); min2 = max(cellNoise2, cellNoise); } //Now calculate the rest of the noise values. #define DO_VAL(swizzle) \ cellPos = centerCell + c.swizzle; \ cellNoise = DIST(WORLEY_POS(cellPos, 2), seed); \ INSERT_MIN(min1, min2, cellNoise); DO_VAL(xy); DO_VAL(xz); DO_VAL(yx); DO_VAL(yz); DO_VAL(zx); DO_VAL(zy); DO_VAL(zz); #undef DO_VAL return OUTVAL(min1, min2); }"); } else if (NDimensions == 3) { outCode.Append("(float3 seed, float3 cellVariance"); if (Wraps) { outCode.Append(", float3 valMax"); } outCode.AppendLine(@") { float3 cellyyy = floor(seed); float min1, min2; const float3 c = float3(-1.0, 0.0, 1.0); //Calculate the first two noise values and store them in min1/min2. float3 cellPos = cellyyy; float cellNoise = DIST(WORLEY_POS(cellPos, 3), seed); { cellPos = cellyyy + c.xxx; float cellNoise2 = DIST(WORLEY_POS(cellPos, 3), seed); min1 = min(cellNoise2, cellNoise); min2 = max(cellNoise2, cellNoise); } //Now calculate the rest of the noise values. #define DO_VAL(swizzle) \ cellPos = cellyyy + c.swizzle; \ cellNoise = DIST(WORLEY_POS(cellPos, 3), seed); \ INSERT_MIN(min1, min2, cellNoise); DO_VAL(xxy) DO_VAL(xxz) DO_VAL(xyx) DO_VAL(xyy) DO_VAL(xyz) DO_VAL(xzx) DO_VAL(xzy) DO_VAL(xzz) DO_VAL(yxx) DO_VAL(yxy) DO_VAL(yxz) DO_VAL(yyx) DO_VAL(yyz) DO_VAL(yzx) DO_VAL(yzy) DO_VAL(yzz) DO_VAL(zxx) DO_VAL(zxy) DO_VAL(zxz) DO_VAL(zyx) DO_VAL(zyy) DO_VAL(zyz) DO_VAL(zzx) DO_VAL(zzy) DO_VAL(zzz) #undef DO_VAL return OUTVAL(min1, min2); }"); } else if (NDimensions == 4) { outCode.Append("(float4 seed, float4 cellVariance"); if (Wraps) { outCode.Append(", float4 valMax"); } outCode.AppendLine(@") { float min1, min2; const float3 c = float3(-1.0, 0.0, 1.0); float4 cellPos; float cellNoise; //The center noise value. float4 cellyyyy = floor(seed); //Calculate the first two noise values and store them in min1/min2. cellPos = cellyyyy; cellNoise = DIST(WORLEY_POS(cellPos, 4), seed); { cellPos = cellyyyy + c.xxxx; float cellNoise2 = DIST(WORLEY_POS(cellPos, 4), seed); min1 = min(cellNoise2, cellNoise); min2 = max(cellNoise2, cellNoise); } //Define a way to easily iterate over every possible swizzle of a 4D vector. #define DO(swizzle) \ cellPos = cellyyyy + c.swizzle; \ cellNoise = DIST(WORLEY_POS(cellPos, 4), seed); \ INSERT_MIN(min1, min2, cellNoise); //Runs DO() on every swizzle of 'c' that has the given XYZ. #define FOREACH_XYZ(swizzleXYZ) \ DO(swizzleXYZ##x) DO(swizzleXYZ##y) DO(swizzleXYZ##z) //Runs DO() on every swizzle of 'c' that has the given XY. #define FOREACH_XY(swizzleXY) \ FOREACH_XYZ(swizzleXY##x) FOREACH_XYZ(swizzleXY##y) FOREACH_XYZ(swizzleXY##z) //Runs DO() on every swizzle of 'c' that has the given X. #define FOREACH_X(swizzleX) \ FOREACH_XY(swizzleX##x) FOREACH_XY(swizzleX##y) FOREACH_XY(swizzleX##z) //Runs DO() on every swizzle, except yyyx and yyyy because we already did those. #define FOREACH_DO \ FOREACH_X(x) \ FOREACH_XY(yx) \ FOREACH_XYZ(yyx) \ DO(yyyz) \ FOREACH_XYZ(yyz) \ FOREACH_XY(yz) \ FOREACH_X(z) FOREACH_DO; return OUTVAL(min1, min2); #undef FOREACH_XYZ #undef FOREACH_XY #undef FOREACH_X #undef FOREACH_DO #undef DO }"); } else { UnityEngine.Assertions.Assert.IsTrue(false, NDimensions.ToString()); } outCode.AppendLine("#undef DIST"); outCode.AppendLine("#undef OUTVAL"); outCode.AppendLine("#undef INSERT_MIN"); outCode.AppendLine("#undef WORLEY_POS"); }
public override void EmitDefs(StringBuilder outCode) { //If using customized Worley noise, we need to emit a custom function to call in the shader. if (NoiseType != NoiseTypes.Worley || IsWorleyDefault) { return; } outCode.Append("#define DIST(a, b) ("); outCode.AppendLine(Worley_DistanceCalc.Replace("$1", "a").Replace("$2", "b") + ")"); outCode.Append("#define OUTVAL(a, b) ("); outCode.AppendLine(Worley_NoiseCalc.Replace("$1", "a").Replace("$2", "b") + ")"); outCode.AppendLine("#define INSERT_MIN(a, b, new) if (new < a) { b = a; a = new; } else b = min(b, new);"); outCode.AppendLine("#define WORLEY_POS(p, nDims) (p + lerp(0.5 - cellVariance, 0.5 + cellVariance, hashValue##nDims(p)))"); outCode.Append("float "); outCode.Append(GetFunc(NoiseType, NDimensions)); if (NDimensions == 1) { outCode.Append(@"(float seed, float cellVariance) { float cellThis = floor(seed), cellLess = cellThis - 1.0, cellMore = cellThis + 1.0; float noise1 = DIST(WORLEY_POS(cellThis, 1), seed), noise2 = DIST(WORLEY_POS(cellLess, 1), seed), noise3 = DIST(WORLEY_POS(cellMore, 1), seed); float min1 = min(noise1, noise2), min2 = max(noise1, noise2); INSERT_MIN(min1, min2, noise3); return OUTVAL(min1, min2); }"); } else if (NDimensions == 2) { outCode.AppendLine(@"(float2 seed, float2 cellVariance) { float2 centerCell = floor(seed); float min1, min2; const float3 c = float3(-1.0, 0.0, 1.0); //Calculate the first two noise values and store them in min1/min2. float2 cellPos = centerCell; float cellNoise = DIST(WORLEY_POS(cellPos, 2), seed); { cellPos = centerCell + c.xx; float cellNoise2 = DIST(WORLEY_POS(cellPos, 2), seed); min1 = min(cellNoise2, cellNoise); min2 = max(cellNoise2, cellNoise); } //Now calculate the rest of the noise values. #define DO_VAL(swizzle) \ cellPos = centerCell + c.swizzle; \ cellNoise = DIST(WORLEY_POS(cellPos, 2), seed); \ INSERT_MIN(min1, min2, cellNoise); DO_VAL(xy); DO_VAL(xz); DO_VAL(yx); DO_VAL(yz); DO_VAL(zx); DO_VAL(zy); DO_VAL(zz); #undef DO_VAL return OUTVAL(min1, min2); }"); } else if (NDimensions == 3) { outCode.AppendLine(@"(float3 seed, float3 cellVariance) { float3 cellyyy = floor(seed); float min1, min2; const float3 c = float3(-1.0, 0.0, 1.0); //Calculate the first two noise values and store them in min1/min2. float3 cellPos = cellyyy; float cellNoise = DIST(WORLEY_POS(cellPos, 3), seed); { cellPos = cellyyy + c.xxx; float cellNoise2 = DIST(WORLEY_POS(cellPos, 3), seed); min1 = min(cellNoise2, cellNoise); min2 = max(cellNoise2, cellNoise); } //Now calculate the rest of the noise values. #define DO_VAL(swizzle) \ cellPos = cellyyy = c.swizzle; \ cellNoise = DIST(WORLEY_POS(cellPos, 3), seed); \ INSERT_MIN(min1, min2, cellNoise); DO_VAL(xxy) DO_VAL(xxz) DO_VAL(xyx) DO_VAL(xyy) DO_VAL(xyz) DO_VAL(xzx) DO_VAL(xzy) DO_VAL(xzz) DO_VAL(yxx) DO_VAL(yxy) DO_VAL(yxz) DO_VAL(yyx) DO_VAL(yyz) DO_VAL(yzx) DO_VAL(yzy) DO_VAL(yzz) DO_VAL(zxx) DO_VAL(zxy) DO_VAL(zxz) DO_VAL(zyx) DO_VAL(zyy) DO_VAL(zyz) DO_VAL(zzx) DO_VAL(zzy) DO_VAL(zzz) #undef DO_VAL return OUTVAL(min1, min2); }"); } else { UnityEngine.Assertions.Assert.IsTrue(false, NDimensions.ToString()); } outCode.AppendLine("#undef DIST"); outCode.AppendLine("#undef OUTVAL"); outCode.AppendLine("#undef INSERT_MIN"); outCode.AppendLine("#undef WORLEY_POS"); }