123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- using System;
- using System.Collections.Generic;
- using UnityEditor.Graphing;
- using UnityEditor.ShaderGraph.Drawing.Controls;
- using UnityEditor.ShaderGraph.Internal;
- using UnityEngine;
- namespace UnityEditor.ShaderGraph
- {
- [Title("UV", "Flipbook")]
- class FlipbookNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV
- {
- public FlipbookNode()
- {
- name = "Flipbook";
- UpdateNodeAfterDeserialization();
- }
- const int UVSlotId = 0;
- const int WidthSlotId = 1;
- const int HeightSlotId = 2;
- const int TileSlotId = 3;
- const int OutputSlotId = 4;
- const string kUVSlotName = "UV";
- const string kWidthSlotName = "Width";
- const string kHeightSlotName = "Height";
- const string kTileSlotName = "Tile";
- const string kOutputSlotName = "Out";
- public override bool hasPreview
- {
- get { return true; }
- }
- string GetFunctionName()
- {
- return $"Unity_Flipbook_{concretePrecision.ToShaderString()}";
- }
- public sealed override void UpdateNodeAfterDeserialization()
- {
- AddSlot(new UVMaterialSlot(UVSlotId, kUVSlotName, kUVSlotName, UVChannel.UV0));
- AddSlot(new Vector1MaterialSlot(WidthSlotId, kWidthSlotName, kWidthSlotName, SlotType.Input, 1));
- AddSlot(new Vector1MaterialSlot(HeightSlotId, kHeightSlotName, kHeightSlotName, SlotType.Input, 1));
- AddSlot(new Vector1MaterialSlot(TileSlotId, kTileSlotName, kTileSlotName, SlotType.Input, 0));
- AddSlot(new Vector2MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector2.zero));
- RemoveSlotsNameNotMatching(new[] { UVSlotId, WidthSlotId, HeightSlotId, TileSlotId, OutputSlotId });
- }
- [SerializeField]
- private bool m_InvertX = false;
- [ToggleControl("Invert X")]
- public ToggleData invertX
- {
- get { return new ToggleData(m_InvertX); }
- set
- {
- if (m_InvertX == value.isOn)
- return;
- m_InvertX = value.isOn;
- Dirty(ModificationScope.Node);
- }
- }
- [SerializeField]
- private bool m_InvertY = true;
- [ToggleControl("Invert Y")]
- public ToggleData invertY
- {
- get { return new ToggleData(m_InvertY); }
- set
- {
- if (m_InvertY == value.isOn)
- return;
- m_InvertY = value.isOn;
- Dirty(ModificationScope.Node);
- }
- }
- public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
- {
- var uvValue = GetSlotValue(UVSlotId, generationMode);
- var widthValue = GetSlotValue(WidthSlotId, generationMode);
- var heightValue = GetSlotValue(HeightSlotId, generationMode);
- var tileValue = GetSlotValue(TileSlotId, generationMode);
- var outputValue = GetSlotValue(OutputSlotId, generationMode);
- sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString(), GetVariableNameForSlot(OutputSlotId));
- if (!generationMode.IsPreview())
- {
- sb.AppendLine("$precision2 _{0}_Invert = $precision2 ({1}, {2});", GetVariableNameForNode(), invertX.isOn ? 1 : 0, invertY.isOn ? 1 : 0);
- }
- sb.AppendLine("{0}({1}, {2}, {3}, {4}, _{5}_Invert, {6});", GetFunctionName(), uvValue, widthValue, heightValue, tileValue, GetVariableNameForNode(), outputValue);
- }
- public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
- {
- base.CollectPreviewMaterialProperties(properties);
- properties.Add(new PreviewProperty(PropertyType.Vector2)
- {
- name = string.Format("_{0}_Invert", GetVariableNameForNode()),
- vector4Value = new Vector2(invertX.isOn ? 1 : 0, invertY.isOn ? 1 : 0)
- });
- }
- public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
- {
- if (!generationMode.IsPreview())
- return;
- base.CollectShaderProperties(properties, generationMode);
- properties.AddShaderProperty(new Vector2ShaderProperty()
- {
- overrideReferenceName = string.Format("_{0}_Invert", GetVariableNameForNode()),
- generatePropertyBlock = false
- });
- }
- 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())
- {
- s.AppendLine("Tile = fmod(Tile, Width*Height);");
- s.AppendLine("$precision2 tileCount = $precision2(1.0, 1.0) / $precision2(Width, Height);");
- s.AppendLine("$precision tileY = abs(Invert.y * Height - (floor(Tile * tileCount.x) + Invert.y * 1));");
- s.AppendLine("$precision tileX = abs(Invert.x * Width - ((Tile - Width * floor(Tile * tileCount.x)) + Invert.x * 1));");
- s.AppendLine("Out = (UV + $precision2(tileX, tileY)) * tileCount;");
- }
- });
- }
- public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
- {
- using (var tempSlots = PooledList<MaterialSlot>.Get())
- {
- GetInputSlots(tempSlots);
- foreach (var slot in tempSlots)
- {
- if (slot.RequiresMeshUV(channel))
- return true;
- }
- return false;
- }
- }
- }
- }
|