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("}"); }); }
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); }
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); }
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;"); } } } } }); }
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;"); } } }); }
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);"); } } }); }
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;"); } }); }
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; } } }); }
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);"); } } }); }
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; } } }); }
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));"); } }); }
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));"); } }); }
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); }
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); }
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); }); }
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("}"); }); }
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); }
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); }); }
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)); } }); }
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("}"); }); }
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);"); } }); }
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); }
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); }
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); }