### Add Node: Simple Math Operation in ShaderGraph Source: https://context7.com/unity-technologies/shadergraph/llms.txt The Add node is a basic example of a custom math operation node in ShaderGraph. It extends CodeFunctionNode and defines its shader function logic using HLSL syntax, mapping C# method parameters to shader function slots. ```csharp // AddNode.cs - Example of a simple math node using System.Reflection; namespace UnityEditor.ShaderGraph { [Title("Math", "Basic", "Add")] public class AddNode : CodeFunctionNode { public AddNode() { name = "Add"; } public override string documentationURL { get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Add-Node"; } } protected override MethodInfo GetFunctionToConvert() { return GetType().GetMethod("Unity_Add", BindingFlags.Static | BindingFlags.NonPublic); } // Slot 0: Input A (dynamic vector type) // Slot 1: Input B (dynamic vector type) // Slot 2: Output (dynamic vector type) static string Unity_Add( [Slot(0, Binding.None)] DynamicDimensionVector A, [Slot(1, Binding.None)] DynamicDimensionVector B, [Slot(2, Binding.None)] out DynamicDimensionVector Out) { return @" { Out = A + B; }"; } } } ``` -------------------------------- ### Implement Sample Texture 2D Node in C# for Unity ShaderGraph Source: https://context7.com/unity-technologies/shadergraph/llms.txt This C# script defines the Sample Texture 2D node for Unity's ShaderGraph. It handles texture sampling, supports different texture types (Default, Normal), and allows for custom sampler states. The node exposes RGBA, R, G, B, and A output slots, along with Texture2D, UV, and SamplerState input slots. ```csharp // SampleTexture2DNode.cs - Texture sampling node using UnityEngine; using UnityEditor.Graphing; namespace UnityEditor.ShaderGraph { public enum TextureType { Default, Normal }; [Title("Input", "Texture", "Sample Texture 2D")] public class SampleTexture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV { public const int OutputSlotRGBAId = 0; public const int OutputSlotRId = 4; public const int OutputSlotGId = 5; public const int OutputSlotBId = 6; public const int OutputSlotAId = 7; public const int TextureInputId = 1; public const int UVInput = 2; public const int SamplerInput = 3; [SerializeField] private TextureType m_TextureType = TextureType.Default; public sealed override void UpdateNodeAfterDeserialization() { AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, "RGBA", "RGBA", SlotType.Output, Vector4.zero)); AddSlot(new Vector1MaterialSlot(OutputSlotRId, "R", "R", SlotType.Output, 0)); AddSlot(new Vector1MaterialSlot(OutputSlotGId, "G", "G", SlotType.Output, 0)); AddSlot(new Vector1MaterialSlot(OutputSlotBId, "B", "B", SlotType.Output, 0)); AddSlot(new Vector1MaterialSlot(OutputSlotAId, "A", "A", SlotType.Output, 0)); AddSlot(new Texture2DInputMaterialSlot(TextureInputId, "Texture", "Texture")); AddSlot(new UVMaterialSlot(UVInput, "UV", "UV", UVChannel.UV0)); AddSlot(new SamplerStateMaterialSlot(SamplerInput, "Sampler", "Sampler", SlotType.Input)); } public virtual void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) { var uvName = GetSlotValue(UVInput, generationMode); var id = GetSlotValue(TextureInputId, generationMode); var result = string.Format("{0}4 {1} = SAMPLE_TEXTURE2D({2}, {3}, {4});", precision, GetVariableNameForSlot(OutputSlotRGBAId), id, "sampler" + id, uvName); visitor.AddShaderChunk(result, true); if (textureType == TextureType.Normal) visitor.AddShaderChunk(string.Format("{0}.rgb = UnpackNormalmapRGorAG({0});", GetVariableNameForSlot(OutputSlotRGBAId)), true); } } } ``` -------------------------------- ### Implement ShaderGraph Importer in C# Source: https://context7.com/unity-technologies/shadergraph/llms.txt Provides the ShaderGraphImporter class in C# for Unity's asset pipeline. This importer handles the conversion of .shadergraph files into compiled shader code, managing asset loading, error handling, and shader property defaults. It utilizes UnityEditor.Experimental.AssetImporters and ShaderUtil. ```csharp // ShaderGraphImporter.cs - Asset import pipeline using UnityEditor.Experimental.AssetImporters; using UnityEngine; using System.IO; using System.Text; [ScriptedImporter(13, ShaderGraphImporter.ShaderGraphExtension)] public class ShaderGraphImporter : ScriptedImporter { public const string ShaderGraphExtension = "shadergraph"; public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath(ctx.assetPath); if (oldShader != null) ShaderUtil.ClearShaderErrors(oldShader); List configuredTextures; var text = GetShaderText(ctx.assetPath, out configuredTextures); var shader = ShaderUtil.CreateShaderAsset(text); EditorMaterialUtility.SetShaderDefaults(shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); } internal static string GetShaderText(string path, out List configuredTextures) { string shaderString = null; var shaderName = Path.GetFileNameWithoutExtension(path); try { var textGraph = File.ReadAllText(path, Encoding.UTF8); var graph = JsonUtility.FromJson(textGraph); graph.LoadedFromDisk(); if (!string.IsNullOrEmpty(graph.path)) shaderName = graph.path + "/" + shaderName; shaderString = graph.GetShader(shaderName, GenerationMode.ForReals, out configuredTextures); } catch (Exception) { } configuredTextures = new List(); return shaderString ?? k_ErrorShader.Replace("Hidden/GraphErrorShader2", shaderName); } } ``` -------------------------------- ### Tiling and Offset Node: UV Manipulation in ShaderGraph Source: https://context7.com/unity-technologies/shadergraph/llms.txt The Tiling and Offset node demonstrates how to create custom nodes for manipulating UV coordinates in ShaderGraph. It utilizes default mesh UV bindings and allows for adjustable tiling and offset values, outputting the modified UV coordinates. ```csharp // TilingAndOffsetNode.cs - UV manipulation node using System.Reflection; using UnityEngine; namespace UnityEditor.ShaderGraph { [Title("UV", "Tiling And Offset")] public class TilingAndOffsetNode : CodeFunctionNode { public TilingAndOffsetNode() { name = "Tiling And Offset"; } protected override MethodInfo GetFunctionToConvert() { return GetType().GetMethod("Unity_TilingAndOffset", BindingFlags.Static | BindingFlags.NonPublic); } // Slot 0: UV input with default mesh UV0 binding // Slot 1: Tiling with default (1,1,1,1) // Slot 2: Offset with default (0,0,0,0) // Slot 3: Output UV static string Unity_TilingAndOffset( [Slot(0, Binding.MeshUV0)] Vector2 UV, [Slot(1, Binding.None, 1f, 1f, 1f, 1f)] Vector2 Tiling, [Slot(2, Binding.None, 0f, 0f, 0f, 0f)] Vector2 Offset, [Slot(3, Binding.None)] out Vector2 Out) { Out = Vector2.zero; return @" { Out = UV * Tiling + Offset; }"; } } } ``` -------------------------------- ### Implement Simple Noise Node in C# Source: https://context7.com/unity-technologies/shadergraph/llms.txt This C# script defines the Simple Noise node for Unity ShaderGraph. It utilizes helper functions for procedural noise generation and registers them with the function registry. The node takes UV coordinates and a scale as input and outputs a procedural noise value. ```csharp // SimpleNoiseNode.cs - Procedural noise generation using System.Reflection; using UnityEngine; namespace UnityEditor.ShaderGraph { [Title("Procedural", "Noise", "Simple Noise")] public class NoiseNode : CodeFunctionNode { public NoiseNode() { name = "Simple Noise"; } protected override MethodInfo GetFunctionToConvert() { return GetType().GetMethod("Unity_SimpleNoise", BindingFlags.Static | BindingFlags.NonPublic); } static string Unity_SimpleNoise( [Slot(0, Binding.MeshUV0)] Vector2 UV, [Slot(1, Binding.None, 500f, 500f, 500f, 500f)] Vector1 Scale, [Slot(2, Binding.None)] out Vector1 Out) { return @" { float t = 0.0; for(int i = 0; i < 3; i++) { float freq = pow(2.0, float(i)); float amp = pow(0.5, float(3-i)); t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp; } Out = t; }"; } // Register helper functions for the noise algorithm public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode) { registry.ProvideFunction("unity_noise_randomValue", s => s.Append(@" inline float unity_noise_randomValue (float2 uv) { return frac(sin(dot(uv, float2(12.9898, 78.233)))*43758.5453); }")); registry.ProvideFunction("unity_noise_interpolate", s => s.Append(@" inline float unity_noise_interpolate (float a, float b, float t) { return (1.0-t)*a + (t*b); }")); registry.ProvideFunction("unity_valueNoise", s => s.Append(@" inline float unity_valueNoise (float2 uv) { float2 i = floor(uv); float2 f = frac(uv); f = f * f * (3.0 - 2.0 * f); float2 c0 = i + float2(0.0, 0.0); float2 c1 = i + float2(1.0, 0.0); float2 c2 = i + float2(0.0, 1.0); float2 c3 = i + float2(1.0, 1.0); float r0 = unity_noise_randomValue(c0); float r1 = unity_noise_randomValue(c1); float r2 = unity_noise_randomValue(c2); float r3 = unity_noise_randomValue(c3); float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x); float topOfGrid = unity_noise_interpolate(r2, r3, f.x); return unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y); }")); base.GenerateNodeFunction(registry, generationMode); } } } ``` -------------------------------- ### PBR Master Node Implementation in C# Source: https://context7.com/unity-technologies/shadergraph/llms.txt Defines the PBR Master Node for Unity Shader Graph, handling physically-based rendering properties. It supports both Metallic and Specular workflows and various surface types. ```csharp // PBRMasterNode.cs - Core PBR shader output node [Serializable] [Title("Master", "PBR")] public class PBRMasterNode : MasterNode, IMayRequireNormal { public const string AlbedoSlotName = "Albedo"; public const string NormalSlotName = "Normal"; public const string EmissionSlotName = "Emission"; public const string MetallicSlotName = "Metallic"; public const string SmoothnessSlotName = "Smoothness"; public const string OcclusionSlotName = "Occlusion"; public const string AlphaSlotName = "Alpha"; public enum Model { Specular, Metallic } [SerializeField] Model m_Model = Model.Metallic; public sealed override void UpdateNodeAfterDeserialization() { base.UpdateNodeAfterDeserialization(); name = "PBR Master"; AddSlot(new ColorRGBMaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, Color.grey, ShaderStage.Fragment)); AddSlot(new NormalMaterialSlot(NormalSlotId, NormalSlotName, NormalSlotName, CoordinateSpace.Tangent, ShaderStage.Fragment)); AddSlot(new ColorRGBMaterialSlot(EmissionSlotId, EmissionSlotName, EmissionSlotName, SlotType.Input, Color.black, ShaderStage.Fragment)); if (model == Model.Metallic) AddSlot(new Vector1MaterialSlot(MetallicSlotId, MetallicSlotName, MetallicSlotName, SlotType.Input, 0, ShaderStage.Fragment)); else AddSlot(new ColorRGBMaterialSlot(SpecularSlotId, SpecularSlotName, SpecularSlotName, SlotType.Input, Color.grey, ShaderStage.Fragment)); AddSlot(new Vector1MaterialSlot(SmoothnessSlotId, SmoothnessSlotName, SmoothnessSlotName, SlotType.Input, 0.5f, ShaderStage.Fragment)); AddSlot(new Vector1MaterialSlot(OcclusionSlotId, OcclusionSlotName, OcclusionSlotName, SlotType.Input, 1f, ShaderStage.Fragment)); AddSlot(new Vector1MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, 1f, ShaderStage.Fragment)); } } ``` -------------------------------- ### AbstractMaterialNode Base Class for Shader Graph Nodes (C#) Source: https://context7.com/unity-technologies/shadergraph/llms.txt The AbstractMaterialNode class is the core infrastructure for all shader graph nodes. It handles slot management, validation, and code generation. This class defines methods for adding and retrieving input/output slots, determining slot values from connected nodes or defaults, and generating variable names for HLSL code. ```csharp // AbstractMaterialNode.cs - Core node infrastructure using System; using System.Collections.Generic; using UnityEditor.Graphing; namespace UnityEditor.ShaderGraph { [Serializable] public abstract class AbstractMaterialNode : INode, ISerializationCallbackReceiver { public enum OutputPrecision { @fixed, @half, @float } [NonSerialized] private Guid m_Guid; [SerializeField] private string m_Name; [NonSerialized] private List m_Slots = new List(); public OutputPrecision precision { get; set; } public virtual bool hasPreview { get { return false; } } // Slot management methods public void GetInputSlots(List foundSlots) where T : ISlot { foreach (var slot in m_Slots) if (slot.isInputSlot && slot is T) foundSlots.Add((T)slot); } public void GetOutputSlots(List foundSlots) where T : ISlot { foreach (var slot in m_Slots) if (slot.isOutputSlot && slot is T) foundSlots.Add((T)slot); } public void AddSlot(ISlot slot) { if (!(slot is MaterialSlot)) throw new ArgumentException("Slot must be MaterialSlot"); m_Slots.RemoveAll(x => x.id == slot.id); m_Slots.Add(slot); slot.owner = this; Dirty(ModificationScope.Topological); } // Get value from connected node or default public string GetSlotValue(int inputSlotId, GenerationMode generationMode) { var inputSlot = FindSlot(inputSlotId); if (inputSlot == null) return string.Empty; var edges = owner.GetEdges(inputSlot.slotReference).ToArray(); if (edges.Any()) { var outputSlotRef = edges[0].outputSlot; var fromNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); var slot = fromNode.FindOutputSlot(outputSlotRef.slotId); return ShaderGenerator.AdaptNodeOutput(fromNode, slot.id, inputSlot.concreteValueType); } return inputSlot.GetDefaultValue(generationMode); } public virtual string GetVariableNameForSlot(int slotId) { var slot = FindSlot(slotId); return string.Format("_{0}_{1}", GetVariableNameForNode(), NodeUtils.GetHLSLSafeName(slot.shaderOutputName)); } } } ``` -------------------------------- ### Create Reusable SubGraphs in C# Source: https://context7.com/unity-technologies/shadergraph/llms.txt Defines the SubGraph class in C# for Unity ShaderGraph, enabling the creation of reusable node networks. It exposes inputs via graph properties and outputs through a SubGraphOutputNode, facilitating modular shader design. This class implements interfaces for generating shader code and functions. ```csharp // SubGraph.cs - Reusable shader graph components using System; using System.Collections.Generic; using System.Linq; using UnityEditor.Graphing; namespace UnityEditor.ShaderGraph { [Serializable] public class SubGraph : AbstractMaterialGraph, IGeneratesBodyCode, IGeneratesFunction { [NonSerialized] private SubGraphOutputNode m_OutputNode; public SubGraphOutputNode outputNode { get { if (m_OutputNode == null) m_OutputNode = GetNodes().FirstOrDefault(); return m_OutputNode; } } // Graph inputs exposed as properties public IEnumerable graphInputs { get { return properties.OrderBy(x => x.guid); } } // Graph outputs from the output node public IEnumerable graphOutputs { get { return outputNode != null ? outputNode.graphOutputs : new List(); } } public void GenerateSubGraphFunction(string functionName, FunctionRegistry registry, ShaderGraphRequirements reqs, GenerationMode generationMode) { registry.ProvideFunction(functionName, s => { s.AppendLine("// Subgraph function"); var arguments = new List(); foreach (var prop in graphInputs) arguments.Add(prop.GetPropertyAsArgumentString()); arguments.Add("SurfaceInputs IN"); foreach (var slot in graphOutputs) arguments.Add(string.Format("out {0} {1}", slot.concreteValueType.ToString(outputNode.precision), slot.shaderOutputName)); s.AppendLine("void {0}({1})", functionName, arguments.Aggregate((current, next) => string.Format("{0}, {1}", current, next))); using (s.BlockScope()) { var bodyGenerator = new ShaderGenerator(); GenerateNodeCode(bodyGenerator, GenerationMode.ForReals); if (outputNode != null) outputNode.RemapOutputs(bodyGenerator, GenerationMode.ForReals); s.Append(bodyGenerator.GetShaderString(1)); } }); } } } ``` -------------------------------- ### Implement Multi-Mode Blend Node in ShaderGraph (C#) Source: https://context7.com/unity-technologies/shadergraph/llms.txt This C# code defines a 'BlendNode' for Unity's ShaderGraph. It uses an EnumControl to allow selection of different blend modes (Overlay, Multiply, Screen) and dynamically chooses the appropriate shader function based on the selected mode. The node requires 'Base', 'Blend', and 'Opacity' inputs and outputs the blended result. ```csharp // BlendNode.cs - Multi-mode blend operations using System.Reflection; using UnityEditor.ShaderGraph.Drawing.Controls; using UnityEngine; namespace UnityEditor.ShaderGraph { [Title("Artistic", "Blend", "Blend")] public class BlendNode : CodeFunctionNode { [SerializeField] BlendMode m_BlendMode = BlendMode.Overlay; [EnumControl("Mode")] public BlendMode blendMode { get { return m_BlendMode; } set { if (m_BlendMode == value) return; m_BlendMode = value; Dirty(ModificationScope.Graph); } } protected override MethodInfo GetFunctionToConvert() { return GetType().GetMethod( string.Format("Unity_Blend_{0}", System.Enum.GetName(typeof(BlendMode), m_BlendMode)), BindingFlags.Static | BindingFlags.NonPublic); } // Example blend modes static string Unity_Blend_Overlay( [Slot(0, Binding.None)] DynamicDimensionVector Base, [Slot(1, Binding.None)] DynamicDimensionVector Blend, [Slot(3, Binding.None, 1, 1, 1, 1)] Vector1 Opacity, [Slot(2, Binding.None)] out DynamicDimensionVector Out) { return @"\n{\n {precision}{slot2dimension} result1 = 1.0 - 2.0 * (1.0 - Base) * (1.0 - Blend);\n {precision}{slot2dimension} result2 = 2.0 * Base * Blend;\n {precision}{slot2dimension} zeroOrOne = step(Base, 0.5);\n Out = result2 * zeroOrOne + (1 - zeroOrOne) * result1;\n Out = lerp(Base, Out, Opacity);\n}"; } static string Unity_Blend_Multiply( [Slot(0, Binding.None)] DynamicDimensionVector Base, [Slot(1, Binding.None)] DynamicDimensionVector Blend, [Slot(3, Binding.None, 1, 1, 1, 1)] Vector1 Opacity, [Slot(2, Binding.None)] out DynamicDimensionVector Out) { return @"\n{\n Out = Base * Blend;\n Out = lerp(Base, Out, Opacity);\n}"; } static string Unity_Blend_Screen( [Slot(0, Binding.None)] DynamicDimensionVector Base, [Slot(1, Binding.None)] DynamicDimensionVector Blend, [Slot(3, Binding.None, 1, 1, 1, 1)] Vector1 Opacity, [Slot(2, Binding.None)] out DynamicDimensionVector Out) { return @"\n{\n Out = 1.0 - (1.0 - Blend) * (1.0 - Base);\n Out = lerp(Base, Out, Opacity);\n}"; } } } ``` -------------------------------- ### CodeFunctionNode Base Class for Custom Shader Nodes Source: https://context7.com/unity-technologies/shadergraph/llms.txt The CodeFunctionNode is the abstract base class for creating custom shader nodes in Unity's ShaderGraph. It leverages reflection to automatically generate node inputs and outputs from method parameters decorated with SlotAttribute. The Binding enum facilitates automatic access to mesh data. ```csharp // CodeFunctionNode.cs - Base class for custom nodes public abstract class CodeFunctionNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction { // Type definitions for slot value types protected struct Vector1 {} protected struct DynamicDimensionVector {} protected struct ColorRGB {} protected struct Texture2D {} protected struct SamplerState {} protected struct Gradient {} // Binding options for automatic mesh data access protected enum Binding { None, ObjectSpaceNormal, ViewSpaceNormal, WorldSpaceNormal, TangentSpaceNormal, ObjectSpacePosition, ViewSpacePosition, WorldSpacePosition, TangentSpacePosition, MeshUV0, MeshUV1, MeshUV2, MeshUV3, ScreenPosition, ObjectSpaceViewDirection, ViewSpaceViewDirection, WorldSpaceViewDirection, VertexColor, } // SlotAttribute for decorating method parameters [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] protected class SlotAttribute : Attribute { public int slotId { get; private set; } public Binding binding { get; private set; } public SlotAttribute(int mSlotId, Binding mImplicitBinding) { /* ... */ } public SlotAttribute(int mSlotId, Binding mImplicitBinding, float defaultX, float defaultY, float defaultZ, float defaultW) { /* ... */ } } // Override this to provide the shader function implementation protected abstract MethodInfo GetFunctionToConvert(); } ``` -------------------------------- ### Unlit Master Node Implementation in C# Source: https://context7.com/unity-technologies/shadergraph/llms.txt Defines the Unlit Master Node for Unity Shader Graph, used for shaders not affected by lighting. It provides basic color and alpha output, suitable for UI and particle effects. ```csharp // UnlitMasterNode.cs - Unlit shader output node [Serializable] [Title("Master", "Unlit")] public class UnlitMasterNode : MasterNode { public const string ColorSlotName = "Color"; public const string AlphaSlotName = "Alpha"; public const string AlphaClipThresholdSlotName = "AlphaClipThreshold"; public const int ColorSlotId = 0; public const int AlphaSlotId = 7; public const int AlphaThresholdSlotId = 8; [SerializeField] SurfaceType m_SurfaceType; [SerializeField] AlphaMode m_AlphaMode; public sealed override void UpdateNodeAfterDeserialization() { base.UpdateNodeAfterDeserialization(); name = "Unlit Master"; AddSlot(new ColorRGBMaterialSlot(ColorSlotId, ColorSlotName, ColorSlotName, SlotType.Input, Color.grey, ShaderStage.Fragment)); AddSlot(new Vector1MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, 1, ShaderStage.Fragment)); AddSlot(new Vector1MaterialSlot(AlphaThresholdSlotId, AlphaClipThresholdSlotName, AlphaClipThresholdSlotName, SlotType.Input, 0f, ShaderStage.Fragment)); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.