Пример #1
0
        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");
        }
Пример #2
0
        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");
        }