Пример #1
0
 public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
 {
     registry.ProvideFunction("SkinningMatrices", sb =>
     {
         sb.AppendLine("uniform StructuredBuffer<float3x4> _SkinMatrices;");
     });
     registry.ProvideFunction(GetFunctionName(), sb =>
     {
         sb.AppendLine("void {0}(uint4 indices, int indexOffset, $precision4 weights, $precision3 positionIn, $precision3 normalIn, $precision3 tangentIn, out $precision3 positionOut, out $precision3 normalOut, out $precision3 tangentOut)",
                       GetFunctionName());
         sb.AppendLine("{");
         using (sb.IndentScope())
         {
             sb.AppendLine("for (int i = 0; i < 4; i++)");
             sb.AppendLine("{");
             using (sb.IndentScope())
             {
                 sb.AppendLine("$precision3x4 skinMatrix = _SkinMatrices[indices[i] + indexOffset];");
                 sb.AppendLine("$precision3 vtransformed = mul(skinMatrix, $precision4(positionIn, 1));");
                 sb.AppendLine("$precision3 ntransformed = mul(skinMatrix, $precision4(normalIn, 0));");
                 sb.AppendLine("$precision3 ttransformed = mul(skinMatrix, $precision4(tangentIn, 0));");
                 sb.AppendLine("");
                 sb.AppendLine("positionOut += vtransformed * weights[i];");
                 sb.AppendLine("normalOut += ntransformed * weights[i];");
                 sb.AppendLine("tangentOut += ttransformed * weights[i];");
             }
             sb.AppendLine("}");
         }
         sb.AppendLine("}");
     });
 }
Пример #2
0
        void IGeneratesFunction.GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.RequiresIncludePath("Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl");

            var hashType       = this.hashType;
            var hashTypeString = hashType.ToString();
            var HashFunction   = kHashFunctionPrefix[(int)hashType];

            registry.ProvideFunction($"Unity_GradientNoise_{hashTypeString}_Dir_$precision", s =>
            {
                s.AppendLine($"$precision2 Unity_GradientNoise_{hashTypeString}_Dir_$precision($precision2 p)");
                using (s.BlockScope())
                {
                    s.AppendLine($"$precision x; {HashFunction}$precision(p, x);");
                    s.AppendLine("return normalize($precision2(x - floor(x + 0.5), abs(x) - 0.5));");
                }
            });

            registry.ProvideFunction($"Unity_GradientNoise_{hashTypeString}_$precision", s =>
            {
                s.AppendLine($"void Unity_GradientNoise_{hashTypeString}_$precision ($precision2 UV, $precision3 Scale, out $precision Out)");
                using (s.BlockScope())
                {
                    s.AppendLine("$precision2 p = UV * Scale;");
                    s.AppendLine("$precision2 ip = floor(p);");
                    s.AppendLine("$precision2 fp = frac(p);");
                    s.AppendLine($"$precision d00 = dot(Unity_GradientNoise_{hashTypeString}_Dir_$precision(ip), fp);");
                    s.AppendLine($"$precision d01 = dot(Unity_GradientNoise_{hashTypeString}_Dir_$precision(ip + $precision2(0, 1)), fp - $precision2(0, 1));");
                    s.AppendLine($"$precision d10 = dot(Unity_GradientNoise_{hashTypeString}_Dir_$precision(ip + $precision2(1, 0)), fp - $precision2(1, 0));");
                    s.AppendLine($"$precision d11 = dot(Unity_GradientNoise_{hashTypeString}_Dir_$precision(ip + $precision2(1, 1)), fp - $precision2(1, 1));");
                    s.AppendLine("fp = fp * fp * fp * (fp * (fp * 6 - 15) + 10);");
                    s.AppendLine("Out = lerp(lerp(d00, d01, fp.y), lerp(d10, d11, fp.y), fp.x) + 0.5;");
                }
            });
        }
        public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction("unity_gradientNoise_dir", s => s.Append(@"
float2 unity_gradientNoise_dir(float2 p)
{
    // Permutation and hashing used in webgl-nosie goo.gl/pX7HtC
    p = p % 289;
    float x = (34 * p.x + 1) * p.x % 289 + p.y;
    x = (34 * x + 1) * x % 289;
    x = frac(x / 41) * 2 - 1;
    return normalize(float2(x - floor(x + 0.5), abs(x) - 0.5));
}
"));

            registry.ProvideFunction("unity_gradientNoise", s => s.Append(@"
float unity_gradientNoise(float2 p)
{
    float2 ip = floor(p);
    float2 fp = frac(p);
    float d00 = dot(unity_gradientNoise_dir(ip), fp);
    float d01 = dot(unity_gradientNoise_dir(ip + float2(0, 1)), fp - float2(0, 1));
    float d10 = dot(unity_gradientNoise_dir(ip + float2(1, 0)), fp - float2(1, 0));
    float d11 = dot(unity_gradientNoise_dir(ip + float2(1, 1)), fp - float2(1, 1));
    fp = fp * fp * fp * (fp * (fp * 6 - 15) + 10);
    return lerp(lerp(d00, d01, fp.y), lerp(d10, d11, fp.y), fp.x);
}
"));

            base.GenerateNodeFunction(registry, generationMode);
        }
Пример #4
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction("DeformedMeshData", sb =>
            {
                sb.AppendLine("struct DeformedVertexData");
                sb.AppendLine("{");
                using (sb.IndentScope())
                {
                    sb.AppendLine("float3 Position;");
                    sb.AppendLine("float3 Normal;");
                    sb.AppendLine("float3 Tangent;");
                }
                sb.AppendLine("};");
                sb.AppendLine("uniform StructuredBuffer<DeformedVertexData> _DeformedMeshData : register(t1);");
            });

            registry.ProvideFunction(GetFunctionName(), sb =>
            {
                sb.AppendLine($"void {GetFunctionName()}(" +
                              "uint vertexID, " +
                              "out $precision3 positionOut, " +
                              "out $precision3 normalOut, " +
                              "out $precision3 tangentOut)");

                sb.AppendLine("{");
                using (sb.IndentScope())
                {
                    sb.AppendLine("const DeformedVertexData vertexData = _DeformedMeshData[asuint(UNITY_ACCESS_HYBRID_INSTANCED_PROP(_ComputeMeshIndex, float)) + vertexID];");
                    sb.AppendLine("positionOut = vertexData.Position;");
                    sb.AppendLine("normalOut = vertexData.Normal;");
                    sb.AppendLine("tangentOut = vertexData.Tangent;");
                }
                sb.AppendLine("}");
            });
        }
        public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction("lambert", s => s.Append(@"
float4 lambert (float3 normal, float3 light_direction) {
	float ndotl = max(dot(normal, light_direction), 0);
    // if(ndotl < 0.2) ndotl = 0.2;
    // else if(ndotl < 0.4) ndotl = 0.4;
    // else if(ndotl < 0.6) ndotl = 0.6;
    // else if(ndotl < 0.8) ndotl = 0.8;
    // else ndotl = 1;
	float4 c = float4(ndotl, ndotl, ndotl, 1);
	return c;
}
"));
            registry.ProvideFunction("sphere_distance", s => s.Append(@"
float sphere_distance(float3 position, float3 center, float radius)
{
    // return max(-(distance(position + float3(0.1, 0, 0), center) - radius), distance(position - float3(0.1, 0, 0), center) - radius);
    return distance(position, center) - radius;
}"));
            registry.ProvideFunction("sphere_normal", s => s.Append(@"
float3 sphere_normal(float3 position, float3 center, float radius)
{
	const float eps = 0.01;

	return normalize
	(	float3
		(	sphere_distance(position + float3(eps, 0, 0), center, radius) - sphere_distance(position - float3(eps, 0, 0), center, radius),
			sphere_distance(position + float3(0, eps, 0), center, radius) - sphere_distance(position - float3(0, eps, 0), center, radius),
			sphere_distance(position + float3(0, 0, eps), center, radius) - sphere_distance(position - float3(0, 0, eps), center, radius)
		)
	);
}
"));
            registry.ProvideFunction("sphere_render", s => s.Append(@"
float4 sphere_render(float3 position, float3 center, float radius, float3 light_direction)
{
	float3 normal = sphere_normal(position, center, radius);
	return lambert(normal, light_direction);
}
"));
            registry.ProvideFunction("sphere_raymarch", s => s.Append(@"
float4 sphere_raymarch(float3 position, float3 direction, float3 center, float radius, float3 light_direction, int steps, float min_distance)
{
	for(int i = 0; i < steps; i++)
	{
		float distance = sphere_distance(position, center, radius);
		if (distance < min_distance)
            return sphere_render(position, center, radius, light_direction);

		position -= distance * direction;
	}
	return float4(1,1,1,0); // White
}
"));

            base.GenerateNodeFunction(registry, graphContext, generationMode);
        }
        public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction("lambert", s => s.Append(@"
float4 lambert (float3 normal, float3 light_direction) {
	float ndotl = max(dot(normal, light_direction), 0);
    // if(ndotl < 0.2) ndotl = 0.2;
    // else if(ndotl < 0.4) ndotl = 0.4;
    // else if(ndotl < 0.6) ndotl = 0.6;
    // else if(ndotl < 0.8) ndotl = 0.8;
    // else ndotl = 1;
	float4 c = float4(ndotl, ndotl, ndotl, 1);
	return c;
}
"));
            registry.ProvideFunction("box_distance", s => s.Append(@"
float box_distance(float3 position, float3 center, float3 bounding)
{
    float3 d = abs(position - center) - bounding;
    return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}"));
            registry.ProvideFunction("box_normal", s => s.Append(@"
float3 box_normal(float3 position, float3 center, float3 bounding)
{
	const float eps = 0.01;

	return normalize
	(	float3
		(	box_distance(position + float3(eps, 0, 0), center, bounding) - box_distance(position - float3(eps, 0, 0), center, bounding),
			box_distance(position + float3(0, eps, 0), center, bounding) - box_distance(position - float3(0, eps, 0), center, bounding),
			box_distance(position + float3(0, 0, eps), center, bounding) - box_distance(position - float3(0, 0, eps), center, bounding)
		)
	);
}
"));
            registry.ProvideFunction("box_render", s => s.Append(@"
float4 box_render(float3 position, float3 center, float3 bounding, float3 light_direction)
{
	float3 normal = box_normal(position, center, bounding);
	return lambert(normal, light_direction);
}
"));
            registry.ProvideFunction("box_raymarch", s => s.Append(@"
float4 box_raymarch(float3 position, float3 direction, float3 center, float3 bounding, float3 light_direction, int steps, float min_distance)
{
	for(int i = 0; i < steps; i++)
	{
		float distance = box_distance(position, center, bounding);
		if (distance < min_distance)
            return box_render(position, center, bounding, light_direction);

		position -= distance * direction;
	}
	return float4(1,1,1,0); // White
}
"));

            base.GenerateNodeFunction(registry, graphContext, generationMode);
        }
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            // we don't declare this include via the registry include path
            // because it uses macro magic, and can be included more than once, generating different functions
            string perPixelDisplacementInclude = @"#include ""Packages/com.unity.render-pipelines.core/ShaderLibrary/PerPixelDisplacement.hlsl""";

            // Texture sample inputs
            var samplerSlot  = FindInputSlot <MaterialSlot>(kHeightmapSamplerSlotId);
            var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
            var heightmap    = GetSlotValue(kHeightmapSlotId, generationMode);

            // We first generate components that can be used by multiple POM node
            registry.ProvideFunction("Unique", s =>
            {
                s.AppendLine("struct PerPixelHeightDisplacementParam");
                using (s.BlockSemicolonScope())
                {
                    s.AppendLine("$precision2 uv;");
                }
                s.AppendNewLine();
                s.AppendLine($"$precision3 GetDisplacementObjectScale()");
                using (s.BlockScope())
                {
                    s.AppendLines(@"
float3 objectScale = float3(1.0, 1.0, 1.0);
float4x4 worldTransform = GetWorldToObjectMatrix();

objectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
objectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));

return objectScale;");
                }
            });

            // Then we add the functions that are specific to this node
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine("// Required struct and function for the ParallaxOcclusionMapping function:");
                s.AppendLine($"$precision ComputePerPixelHeightDisplacement_{GetVariableNameForNode()}($precision2 texOffsetCurrent, $precision lod, PerPixelHeightDisplacementParam param, TEXTURE2D_PARAM(heightTexture, heightSampler))");
                using (s.BlockScope())
                {
                    s.AppendLine("return SAMPLE_TEXTURE2D_LOD(heightTexture, heightSampler, param.uv + texOffsetCurrent, lod).r;");
                }
                // heightmap,
                // edgesSampler.Any() ? GetSlotValue(kHeightmapSamplerSlotId, generationMode) : "sampler" + heightmap);

                s.AppendLine($"#define ComputePerPixelHeightDisplacement ComputePerPixelHeightDisplacement_{GetVariableNameForNode()}");
                s.AppendLine($"#define POM_NAME_ID {GetVariableNameForNode()}");
                s.AppendLine($"#define POM_USER_DATA_PARAMETERS , TEXTURE2D_PARAM(heightTexture, samplerState)");
                s.AppendLine($"#define POM_USER_DATA_ARGUMENTS , TEXTURE2D_ARGS(heightTexture, samplerState)");
                s.AppendLine(perPixelDisplacementInclude);
                s.AppendLine($"#undef ComputePerPixelHeightDisplacement");
                s.AppendLine($"#undef POM_NAME_ID");
                s.AppendLine($"#undef POM_USER_DATA_PARAMETERS");
                s.AppendLine($"#undef POM_USER_DATA_ARGUMENTS");
            });
        }
        public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction("randomValue", s => s.Append(@"
inline float randomValue(float3 pos)
{
    return frac(sin(dot(pos, float3(12.9898, 78.233, 125.67)))*43758.5453);
}"));

            registry.ProvideFunction("interpolate", s => s.Append(@"
inline float interpolate(float a, float b, float t)
{
    return (1.0-t)*a + (t*b);
}
"));

            registry.ProvideFunction("valueNoise3D", s => s.Append(@"
inline float valueNoise3D(float3 pos)
{
    float3 i = floor(pos);
    float3 f = frac(pos);
    f = f * f * (3.0 - 2.0 * f);

    pos = abs(frac(pos) - 0.5);
    float3 c000 = i + float3(0.0, 0.0, 0.0);
    float3 c001 = i + float3(0.0, 0.0, 1.0);
    float3 c010 = i + float3(0.0, 1.0, 0.0);
    float3 c011 = i + float3(0.0, 1.0, 1.0);
    float3 c100 = i + float3(1.0, 0.0, 0.0);
    float3 c101 = i + float3(1.0, 0.0, 1.0);
    float3 c110 = i + float3(1.0, 1.0, 0.0);
    float3 c111 = i + float3(1.0, 1.0, 1.0);
    float r000 = randomValue(c000);
    float r001 = randomValue(c001);
    float r010 = randomValue(c010);
    float r011 = randomValue(c011);
    float r100 = randomValue(c100);
    float r101 = randomValue(c101);
    float r110 = randomValue(c110);
    float r111 = randomValue(c111);

    float bottomFront = interpolate(r000, r100, f.x);
    float topFront = interpolate(r010, r110, f.x);
    float bottomBack = interpolate(r001, r101, f.x);
    float topBack = interpolate(r011, r111, f.x);
    float front = interpolate(bottomFront, topFront, f.y);
    float back = interpolate(bottomBack, topBack, f.y);
    float t = interpolate(front, back, f.z);
    return t;
}"));

            base.GenerateNodeFunction(registry, graphContext, generationMode);
        }
Пример #9
0
        void IGeneratesFunction.GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.RequiresIncludePath("Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl");

            var hashType       = this.hashType;
            var hashTypeString = hashType.ToString();
            var HashFunction   = kHashFunctionPrefix[(int)hashType];

            registry.ProvideFunction($"Unity_Voronoi_RandomVector_{hashTypeString}_$precision", s =>
            {
                s.AppendLine($"$precision2 Unity_Voronoi_RandomVector_{hashTypeString}_$precision ($precision2 UV, $precision offset)");
                using (s.BlockScope())
                {
                    s.AppendLine($"{HashFunction}$precision(UV, UV);");
                    s.AppendLine("return $precision2(sin(UV.y * offset), cos(UV.x * offset)) * 0.5 + 0.5;");
                }
            });

            registry.ProvideFunction($"Unity_Voronoi_{hashTypeString}_$precision", s =>
            {
                s.AppendLine($"void Unity_Voronoi_{hashTypeString}_$precision($precision2 UV, $precision AngleOffset, $precision CellDensity, out $precision Out, out $precision Cells)");
                using (s.BlockScope())
                {
                    s.AppendLine("$precision2 g = floor(UV * CellDensity);");
                    s.AppendLine("$precision2 f = frac(UV * CellDensity);");
                    s.AppendLine("$precision t = 8.0;");
                    s.AppendLine("$precision3 res = $precision3(8.0, 0.0, 0.0);");
                    s.AppendLine("for (int y = -1; y <= 1; y++)");
                    using (s.BlockScope())
                    {
                        s.AppendLine("for (int x = -1; x <= 1; x++)");
                        using (s.BlockScope())
                        {
                            s.AppendLine("$precision2 lattice = $precision2(x, y);");
                            s.AppendLine($"$precision2 offset = Unity_Voronoi_RandomVector_{hashTypeString}_$precision(lattice + g, AngleOffset);");
                            s.AppendLine("$precision d = distance(lattice + offset, f);");
                            s.AppendLine("if (d < res.x)");
                            using (s.BlockScope())
                            {
                                s.AppendLine("res = $precision3(d, offset.x, offset.y);");
                                s.AppendLine("Out = res.x;");
                                s.AppendLine("Cells = res.y;");
                            }
                        }
                    }
                }
            });
        }
Пример #10
0
        void IGeneratesFunction.GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.RequiresIncludePath("Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl");

            var hashType       = this.hashType;
            var hashTypeString = hashType.ToString();
            var HashFunction   = kHashFunctionPrefix[(int)hashType];

            registry.ProvideFunction($"Unity_SimpleNoise_ValueNoise_{hashTypeString}_$precision", s =>
            {
                s.AppendLine($"$precision Unity_SimpleNoise_ValueNoise_{hashTypeString}_$precision ($precision2 uv)");
                using (s.BlockScope())
                {
                    s.AppendLine("$precision2 i = floor(uv);");
                    s.AppendLine("$precision2 f = frac(uv);");
                    s.AppendLine("f = f * f * (3.0 - 2.0 * f);");
                    s.AppendLine("uv = abs(frac(uv) - 0.5);");
                    s.AppendLine("$precision2 c0 = i + $precision2(0.0, 0.0);");
                    s.AppendLine("$precision2 c1 = i + $precision2(1.0, 0.0);");
                    s.AppendLine("$precision2 c2 = i + $precision2(0.0, 1.0);");
                    s.AppendLine("$precision2 c3 = i + $precision2(1.0, 1.0);");
                    s.AppendLine($"$precision r0; {HashFunction}$precision(c0, r0);");
                    s.AppendLine($"$precision r1; {HashFunction}$precision(c1, r1);");
                    s.AppendLine($"$precision r2; {HashFunction}$precision(c2, r2);");
                    s.AppendLine($"$precision r3; {HashFunction}$precision(c3, r3);");
                    s.AppendLine("$precision bottomOfGrid = lerp(r0, r1, f.x);");
                    s.AppendLine("$precision topOfGrid = lerp(r2, r3, f.x);");
                    s.AppendLine("$precision t = lerp(bottomOfGrid, topOfGrid, f.y);");
                    s.AppendLine("return t;");
                }
            });

            registry.ProvideFunction($"Unity_SimpleNoise_" + hashTypeString + "_$precision", s =>
            {
                s.AppendLine($"void Unity_SimpleNoise_{hashTypeString}_$precision($precision2 UV, $precision Scale, out $precision Out)");
                using (s.BlockScope())
                {
                    s.AppendLine("$precision freq, amp;");
                    s.AppendLine("Out = 0.0f;");
                    for (int octave = 0; octave < 3; octave++)
                    {
                        s.AppendLine($"freq = pow(2.0, $precision({octave}));");
                        s.AppendLine($"amp = pow(0.5, $precision(3-{octave}));");
                        s.AppendLine($"Out += Unity_SimpleNoise_ValueNoise_{hashTypeString}_$precision($precision2(UV.xy*(Scale/freq)))*amp;");
                    }
                }
            });
        }
Пример #11
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine("void {0}({1} In, {2} Strength, $precision3 Position, $precision3x3 TangentMatrix, out {3} Out)",
                             GetFunctionName(),
                             FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType.ToShaderString(),
                             FindInputSlot <MaterialSlot>(StrengthSlotId).concreteValueType.ToShaderString(),
                             FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString());
                using (s.BlockScope())
                {
                    s.AppendLine("$precision3 worldDerivativeX = ddx(Position);");
                    s.AppendLine("$precision3 worldDerivativeY = ddy(Position);");
                    s.AppendNewLine();
                    s.AppendLine("$precision3 crossX = cross(TangentMatrix[2].xyz, worldDerivativeX);");
                    s.AppendLine("$precision3 crossY = cross(worldDerivativeY, TangentMatrix[2].xyz);");
                    s.AppendLine("$precision d = dot(worldDerivativeX, crossY);");
                    s.AppendLine("$precision sgn = d < 0.0 ? (-1.0f) : 1.0f;");
                    s.AppendLine("$precision surface = sgn / max(0.000000000000001192093f, abs(d));");
                    s.AppendNewLine();
                    s.AppendLine("$precision dHdx = ddx(In);");
                    s.AppendLine("$precision dHdy = ddy(In);");
                    s.AppendLine("$precision3 surfGrad = surface * (dHdx*crossY + dHdy*crossX);");
                    s.AppendLine("Out = normalize(TangentMatrix[2].xyz - (Strength * surfGrad));");

                    if (outputSpace == OutputSpace.Tangent)
                    {
                        s.AppendLine("Out = TransformWorldToTangent(Out, TangentMatrix);");
                    }
                }
            });
        }
Пример #12
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine("void {0} ({1} UV, {2} Width, {3} Height, {4} Tile, $precision2 Invert, out {5} Out)",
                             GetFunctionName(),
                             FindInputSlot <MaterialSlot>(UVSlotId).concreteValueType.ToShaderString(),
                             FindInputSlot <MaterialSlot>(WidthSlotId).concreteValueType.ToShaderString(),
                             FindInputSlot <MaterialSlot>(HeightSlotId).concreteValueType.ToShaderString(),
                             FindInputSlot <MaterialSlot>(TileSlotId).concreteValueType.ToShaderString(),
                             FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString());
                using (s.BlockScope())
                {
                    string offset;
                    if (concretePrecision == ConcretePrecision.Half)
                    {
                        offset = "0.00001h";
                    }
                    else
                    {
                        offset = "0.000001";
                    }

                    s.AppendLine("Tile = floor(fmod(Tile + " + offset + ", Width*Height));");
                    s.AppendLine("$precision2 tileCount = $precision2(1.0, 1.0) / $precision2(Width, Height);");

                    AppendInvertSpecificLines(s);

                    s.AppendLine("Out = (UV + $precision2(tileX, tileY)) * tileCount;");
                }
            });
        }
Пример #13
0
        public void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine("void {0} ({1} M0, {1} M1, {1} M2, {1} M3, out {2} Out4x4, out {3} Out3x3, out {4} Out2x2)",
                             GetFunctionName(),
                             FindInputSlot <MaterialSlot>(InputSlotM0Id).concreteValueType.ToString(precision),
                             FindOutputSlot <MaterialSlot>(Output4x4SlotId).concreteValueType.ToString(precision),
                             FindOutputSlot <MaterialSlot>(Output3x3SlotId).concreteValueType.ToString(precision),
                             FindOutputSlot <MaterialSlot>(Output2x2SlotId).concreteValueType.ToString(precision));
                using (s.BlockScope())
                {
                    switch (m_Axis)
                    {
                    case MatrixAxis.Column:
                        s.AppendLine("Out4x4 = {0}4x4(M0.x, M1.x, M2.x, M3.x, M0.y, M1.y, M2.y, M3.y, M0.z, M1.z, M2.z, M3.z, M0.w, M1.w, M2.w, M3.w);", precision);
                        s.AppendLine("Out3x3 = {0}3x3(M0.x, M1.x, M2.x, M0.y, M1.y, M2.y, M0.z, M1.z, M2.z);", precision);
                        s.AppendLine("Out2x2 = {0}2x2(M0.x, M1.x, M0.y, M1.y);", precision);
                        break;

                    default:
                        s.AppendLine("Out4x4 = {0}4x4(M0.x, M0.y, M0.z, M0.w, M1.x, M1.y, M1.z, M1.w, M2.x, M2.y, M2.z, M2.w, M3.x, M3.y, M3.z, M3.w);", precision);
                        s.AppendLine("Out3x3 = {0}3x3(M0.x, M0.y, M0.z, M1.x, M1.y, M1.z, M2.x, M2.y, M2.z);", precision);
                        s.AppendLine("Out2x2 = {0}2x2(M0.x, M0.y, M1.x, M1.y);", precision);
                        break;
                    }
                }
            });
        }
Пример #14
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine("void {0}({1} In, $precision3 Position, $precision3x3 TangentMatrix, out {2} Out)",
                             GetFunctionName(),
                             FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType.ToShaderString(),
                             FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString());
                using (s.BlockScope())
                {
                    s.AppendLine("$precision3 worldDirivativeX = ddx(Position * 100);");
                    s.AppendLine("$precision3 worldDirivativeY = ddy(Position * 100);");
                    s.AppendNewLine();
                    s.AppendLine("$precision3 crossX = cross(TangentMatrix[2].xyz, worldDirivativeX);");
                    s.AppendLine("$precision3 crossY = cross(TangentMatrix[2].xyz, worldDirivativeY);");
                    s.AppendLine("$precision3 d = abs(dot(crossY, worldDirivativeX));");
                    s.AppendLine("$precision3 inToNormal = ((((In + ddx(In)) - In) * crossY) + (((In + ddy(In)) - In) * crossX)) * sign(d);");
                    s.AppendLine("inToNormal.y *= -1.0;");
                    s.AppendNewLine();
                    s.AppendLine("Out = SafeNormalize((d * TangentMatrix[2].xyz) - inToNormal);");

                    if (outputSpace == OutputSpace.Tangent)
                    {
                        s.AppendLine("Out = TransformWorldToTangent(Out, TangentMatrix);");
                    }
                }
            });
        }
Пример #15
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            var functionName = GetFunctionName();

            registry.ProvideFunction(functionName, s =>
            {
                s.AppendLine("void {0}({1} A, {2} B, out {3} Out)",
                             functionName,
                             FindInputSlot <MaterialSlot>(Input1SlotId).concreteValueType.ToShaderString(),
                             FindInputSlot <MaterialSlot>(Input2SlotId).concreteValueType.ToShaderString(),
                             FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString()); // TODO: should this type be part of the function name?
                                                                                                              // is output concrete value type related to node's concrete precision??
                using (s.BlockScope())
                {
                    switch (m_MultiplyType)
                    {
                    case MultiplyType.Vector:
                        s.AppendLine("Out = A * B;");
                        break;

                    default:
                        s.AppendLine("Out = mul(A, B);");
                        break;
                    }
                }
            });
        }
Пример #16
0
        public void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine("void {0}({1} Texture, {2} Sampler, {3} UV, {4} Offset, {5} Strength, out {6} Out)", GetFunctionName(),
                             FindInputSlot <MaterialSlot>(TextureInputId).concreteValueType.ToString(precision),
                             FindInputSlot <MaterialSlot>(SamplerInputId).concreteValueType.ToString(precision),
                             FindInputSlot <MaterialSlot>(UVInputId).concreteValueType.ToString(precision),
                             FindInputSlot <MaterialSlot>(OffsetInputId).concreteValueType.ToString(precision),
                             FindInputSlot <MaterialSlot>(StrengthInputId).concreteValueType.ToString(precision),
                             FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
                using (s.BlockScope())
                {
                    s.AppendLine("Offset = pow(Offset, 3) * 0.1;");
                    s.AppendLine("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision);
                    s.AppendLine("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision);

                    s.AppendLine("{0} normalSample = Texture.Sample(Sampler, UV);", precision);
                    s.AppendLine("{0} uSample = Texture.Sample(Sampler, offsetU);", precision);
                    s.AppendLine("{0} vSample = Texture.Sample(Sampler, offsetV);", precision);

                    s.AppendLine("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision);
                    s.AppendLine("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision);
                    s.AppendLine("Out = normalize(cross(va, vb));");
                }
            });
        }
Пример #17
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine("void {0}(TEXTURE2D_PARAM(Texture, Sampler), {1} UV, {2} Offset, {3} Strength, out {4} Out)",
                             GetFunctionName(),
                             FindInputSlot <MaterialSlot>(UVInputId).concreteValueType.ToShaderString(),
                             FindInputSlot <MaterialSlot>(OffsetInputId).concreteValueType.ToShaderString(),
                             FindInputSlot <MaterialSlot>(StrengthInputId).concreteValueType.ToShaderString(),
                             FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString());
                using (s.BlockScope())
                {
                    s.AppendLine("Offset = pow(Offset, 3) * 0.1;");
                    s.AppendLine("$precision2 offsetU = $precision2(UV.x + Offset, UV.y);");
                    s.AppendLine("$precision2 offsetV = $precision2(UV.x, UV.y + Offset);");

                    s.AppendLine("$precision normalSample = SAMPLE_TEXTURE2D(Texture, Sampler, UV);");
                    s.AppendLine("$precision uSample = SAMPLE_TEXTURE2D(Texture, Sampler, offsetU);");
                    s.AppendLine("$precision vSample = SAMPLE_TEXTURE2D(Texture, Sampler, offsetV);");

                    s.AppendLine("$precision3 va = $precision3(1, 0, (uSample - normalSample) * Strength);");
                    s.AppendLine("$precision3 vb = $precision3(0, 1, (vSample - normalSample) * Strength);");
                    s.AppendLine("Out = normalize(cross(va, vb));");
                }
            });
        }
Пример #18
0
        public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction("Unity_SimpleNoise_RandomValue_$precision", s => s.Append(@"
inline $precision Unity_SimpleNoise_RandomValue_$precision ($precision2 uv)
{
    $precision angle = dot(uv, $precision2(12.9898, 78.233));
    #if defined(SHADER_API_MOBILE) && (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN))
        // 'sin()' has bad precision on Mali GPUs for inputs > 10000
        angle = fmod(angle, TWO_PI); // Avoid large inputs to sin()
    #endif
    return frac(sin(angle)*43758.5453);
}"));

            registry.ProvideFunction($"Unity_SimpleNnoise_Interpolate_$precision", s => s.Append(@"
inline $precision Unity_SimpleNnoise_Interpolate_$precision ($precision a, $precision b, $precision t)
{
    return (1.0-t)*a + (t*b);
}
"));

            registry.ProvideFunction($"Unity_SimpleNoise_ValueNoise_$precision", s => s.Append(@"
inline $precision Unity_SimpleNoise_ValueNoise_$precision ($precision2 uv)
{
    $precision2 i = floor(uv);
    $precision2 f = frac(uv);
    f = f * f * (3.0 - 2.0 * f);

    uv = abs(frac(uv) - 0.5);
    $precision2 c0 = i + $precision2(0.0, 0.0);
    $precision2 c1 = i + $precision2(1.0, 0.0);
    $precision2 c2 = i + $precision2(0.0, 1.0);
    $precision2 c3 = i + $precision2(1.0, 1.0);
    $precision r0 = Unity_SimpleNoise_RandomValue_$precision(c0);
    $precision r1 = Unity_SimpleNoise_RandomValue_$precision(c1);
    $precision r2 = Unity_SimpleNoise_RandomValue_$precision(c2);
    $precision r3 = Unity_SimpleNoise_RandomValue_$precision(c3);

    $precision bottomOfGrid = Unity_SimpleNnoise_Interpolate_$precision(r0, r1, f.x);
    $precision topOfGrid = Unity_SimpleNnoise_Interpolate_$precision(r2, r3, f.x);
    $precision t = Unity_SimpleNnoise_Interpolate_$precision(bottomOfGrid, topOfGrid, f.y);
    return t;
}"));

            base.GenerateNodeFunction(registry, generationMode);
        }
Пример #19
0
        public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction("sphere_distance", s => s.Append(@"
float sphere_distance(float3 position, float3 center, float radius)
{
    return distance(position, center) - radius;
}"));
            base.GenerateNodeFunction(registry, graphContext, generationMode);
        }
Пример #20
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            var perPixelDisplacementInclude = @"#include ""Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl""";

            registry.ProvideFunction(GetFunctionName(), s =>
            {
                s.AppendLine(perPixelDisplacementInclude);
            });
        }
Пример #21
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction("SkinMatrices", sb =>
            {
                sb.AppendLine("uniform StructuredBuffer<float3x4> _SkinMatrices;");
            });

            registry.ProvideFunction(GetFunctionName(), sb =>
            {
                sb.AppendLine($"void {GetFunctionName()}(" +
                              "uint4 indices, " +
                              "$precision4 weights, " +
                              "$precision3 positionIn, " +
                              "$precision3 normalIn, " +
                              "$precision3 tangentIn, " +
                              "out $precision3 positionOut, " +
                              "out $precision3 normalOut, " +
                              "out $precision3 tangentOut)");
                sb.AppendLine("{");
                using (sb.IndentScope())
                {
                    sb.AppendLine("for (int i = 0; i < 4; ++i)");
                    sb.AppendLine("{");
                    using (sb.IndentScope())
                    {
#if HYBRID_RENDERER_0_6_0_OR_NEWER
                        sb.AppendLine("$precision3x4 skinMatrix = _SkinMatrices[indices[i] + asint(_SkinMatrixIndex)];");
#else
                        sb.AppendLine("$precision3x4 skinMatrix = _SkinMatrices[indices[i] + (int)_SkinMatricesOffset];");
#endif
                        sb.AppendLine("$precision3 vtransformed = mul(skinMatrix, $precision4(positionIn, 1));");
                        sb.AppendLine("$precision3 ntransformed = mul(skinMatrix, $precision4(normalIn, 0));");
                        sb.AppendLine("$precision3 ttransformed = mul(skinMatrix, $precision4(tangentIn, 0));");
                        sb.AppendLine("");
                        sb.AppendLine("positionOut += vtransformed * weights[i];");
                        sb.AppendLine("normalOut   += ntransformed * weights[i];");
                        sb.AppendLine("tangentOut  += ttransformed * weights[i];");
                    }
                    sb.AppendLine("}");
                }
                sb.AppendLine("}");
            });
        }
Пример #22
0
        public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction("box_distance", s => s.Append(@"
float box_distance(float3 position, float3 center, float3 bounding)
{
    float3 d = abs(position - center) - bounding;
    return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}"));
            base.GenerateNodeFunction(registry, graphContext, generationMode);
        }
Пример #23
0
 public virtual void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
 {
     registry.ProvideFunction(GetFunctionName(), s =>
     {
         s.AppendLine(GetFunctionHeader());
         var functionBody = GetFunctionBody(GetFunctionToConvert());
         var lines        = functionBody.Trim('\r', '\n', '\t', ' ');
         s.AppendLines(lines);
     });
 }
Пример #24
0
        public virtual void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            if (subGraphAsset == null || referencedGraph == null)
                return;

            List<AbstractMaterialNode> nodes = new List<AbstractMaterialNode>();
            NodeUtils.DepthFirstCollectNodesFromNode(nodes, referencedGraph.outputNode);
            
            foreach (var node in nodes.OfType<AbstractMaterialNode>())
            {
                node.ValidateNode();
                if (node is IGeneratesFunction)
                    (node as IGeneratesFunction).GenerateNodeFunction(registry, graphContext, generationMode);
            }

            string functionName = SubGraphFunctionName(graphContext);
            ShaderGraphRequirements reqs = ShaderGraphRequirements.FromNodes(new List<AbstractMaterialNode> {this});
            registry.ProvideFunction(functionName, s =>
            {
                s.AppendLine("// Subgraph function");

                // Generate arguments... first INPUTS
                var arguments = new List<string>();
                foreach (var prop in referencedGraph.properties)
                    arguments.Add(string.Format("{0}", prop.GetPropertyAsArgumentString()));

                // now pass surface inputs
                arguments.Add(string.Format("{0} IN", graphContext.graphInputStructName));

                // Now generate outputs
                foreach (var slot in outputNode.graphOutputs)
                    arguments.Add(string.Format("out {0} {1}", slot.concreteValueType.ToString(referencedGraph.outputNode.precision), slot.shaderOutputName));

                // Create the function protoype from the arguments
                s.AppendLine("void {0}({1})"
                    , functionName
                    , arguments.Aggregate((current, next) => string.Format("{0}, {1}", current, next)));

                // now generate the function
                using (s.BlockScope())
                {
                    // Just grab the body from the active nodes
                    var bodyGenerator = new ShaderGenerator();
                    foreach (var node in nodes.OfType<AbstractMaterialNode>())
                    {
                        if (node is IGeneratesBodyCode)
                            (node as IGeneratesBodyCode).GenerateNodeCode(bodyGenerator, graphContext, generationMode);
                    }

                    outputNode.RemapOutputs(bodyGenerator, generationMode);

                    s.Append(bodyGenerator.GetShaderString(1));
                }
            });
        }
Пример #25
0
        public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction("SkinMatrices", sb =>
            {
                sb.AppendLine("uniform StructuredBuffer<float3x4> _SkinMatrices;");
            });

            registry.ProvideFunction(GetFunctionName(), sb =>
            {
                sb.AppendLine($"void {GetFunctionName()}(" +
                              "uint4 indices, " +
                              "$precision4 weights, " +
                              "$precision3 positionIn, " +
                              "$precision3 normalIn, " +
                              "$precision3 tangentIn, " +
                              "out $precision3 positionOut, " +
                              "out $precision3 normalOut, " +
                              "out $precision3 tangentOut)");
                sb.AppendLine("{");
                using (sb.IndentScope())
                {
                    sb.AppendLine("positionOut = 0;");
                    sb.AppendLine("normalOut = 0;");
                    sb.AppendLine("tangentOut = 0;");
                    sb.AppendLine("for (int i = 0; i < 4; ++i)");
                    sb.AppendLine("{");
                    using (sb.IndentScope())
                    {
                        sb.AppendLine("$precision3x4 skinMatrix = _SkinMatrices[indices[i] + asint(UNITY_ACCESS_HYBRID_INSTANCED_PROP(_SkinMatrixIndex,float))];");
                        sb.AppendLine("$precision3 vtransformed = mul(skinMatrix, $precision4(positionIn, 1));");
                        sb.AppendLine("$precision3 ntransformed = mul(skinMatrix, $precision4(normalIn, 0));");
                        sb.AppendLine("$precision3 ttransformed = mul(skinMatrix, $precision4(tangentIn, 0));");
                        sb.AppendLine("");
                        sb.AppendLine("positionOut += vtransformed * weights[i];");
                        sb.AppendLine("normalOut   += ntransformed * weights[i];");
                        sb.AppendLine("tangentOut  += ttransformed * weights[i];");
                    }
                    sb.AppendLine("}");
                }
                sb.AppendLine("}");
            });
        }
Пример #26
0
 public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
 {
     registry.ProvideFunction(GetFunctionName(), s =>
     {
         s.AppendLine(GetFunctionPrototype("arg1", "arg2"));
         using (s.BlockScope())
         {
             s.AppendLine("return mul(arg1, arg2);");
         }
     });
 }
Пример #27
0
        public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction("Unity_Voronoi_RandomVector_$precision", s => s.Append(@"
inline $precision2 Unity_Voronoi_RandomVector_$precision ($precision2 UV, $precision offset)
{
    $precision2x2 m = $precision2x2(15.27, 47.63, 99.41, 89.98);
    UV = frac(sin(mul(UV, m)));
    return $precision2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
}
"));
            base.GenerateNodeFunction(registry, generationMode);
        }
Пример #28
0
        public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
        {
            registry.ProvideFunction("unity_voronoi_noise_randomVector", s => s.Append(@"
inline float2 unity_voronoi_noise_randomVector (float2 UV, float offset)
{
    float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
    UV = frac(sin(mul(UV, m)) * 46839.32);
    return float2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
}
"));
            base.GenerateNodeFunction(registry, generationMode);
        }
Пример #29
0
        public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction("random_vector", s => s.Append(@"
inline float3 random_vector (float3 position)
{
    float3x3 m = float3x3(15.27, 47.63, 99.41, 89.98, 127.45, 12.84, 64.82, 158.34, 78.45);
    position = frac(sin(mul(position, m)) * 46839.32);
    return position;
}
"));
            base.GenerateNodeFunction(registry, graphContext, generationMode);
        }
        public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            registry.ProvideFunction($"Unity_Voronoi_RandomVector_{concretePrecision.ToShaderString()}", s => s.Append(@"
inline $precision2 Unity_Voronoi_RandomVector_$precision ($precision2 UV, $precision offset)
{
    $precision2x2 m = $precision2x2(15.27, 47.63, 99.41, 89.98);
    UV = frac(sin(mul(UV, m)) * 46839.32);
    return $precision2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
}
"));
            base.GenerateNodeFunction(registry, graphContext, generationMode);
        }