浏览代码

Recode Flipbook node

- From Abstract
- Add Invert X and Y controls
/main
Matt Dean 7 年前
当前提交
76783350
共有 1 个文件被更改,包括 141 次插入22 次删除
  1. 163
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/FlipbookNode.cs

163
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/FlipbookNode.cs


using System.Reflection;
using UnityEngine;
using System;
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
public class FlipbookNode : CodeFunctionNode
public class FlipbookNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV
UpdateNodeAfterDeserialization();
protected override MethodInfo GetFunctionToConvert()
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_" + precision;
}
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 Toggle invertX
{
get { return new Toggle(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 Toggle invertY
{
get { return new Toggle(m_InvertY); }
set
{
if (m_InvertY == value.isOn)
return;
m_InvertY = value.isOn;
Dirty(ModificationScope.Node);
}
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var sb = new ShaderStringBuilder();
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};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId));
if (!generationMode.IsPreview())
{
sb.AppendLine("{0}2 _{1}_Invert = {0}2 ({2}, {3});", precision, 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);
visitor.AddShaderChunk(sb.ToString(), false);
}
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)
return GetType().GetMethod("Unity_Flipbook", BindingFlags.Static | BindingFlags.NonPublic);
if (!generationMode.IsPreview())
return;
base.CollectShaderProperties(properties, generationMode);
properties.AddShaderProperty(new Vector2ShaderProperty()
{
overrideReferenceName = string.Format("_{0}_Invert", GetVariableNameForNode()),
generatePropertyBlock = false
});
static string Unity_Flipbook(
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None, 1, 1, 1, 1)] Vector1 Width,
[Slot(2, Binding.None, 1, 1, 1, 1)] Vector1 Height,
[Slot(3, Binding.None)] Vector1 Tile,
[Slot(4, Binding.None)] out Vector2 Out)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
Out = Vector2.zero;
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0} ({1} UV, {2} Width, {3} Height, {4} Tile, {5}2 Invert, out {6} Out)",
GetFunctionName(),
FindInputSlot<MaterialSlot>(UVSlotId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(WidthSlotId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(HeightSlotId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(TileSlotId).concreteValueType.ToString(precision),
precision,
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Tile = fmod(Tile, Width*Height);");
s.AppendLine("{0}2 tileCount = {0}2(1.0, 1.0) / {0}2(Width, Height);", precision);
s.AppendLine("{0} tileY = abs((Invert.y * Height) - floor(Tile * tileCount.x));", precision);
s.AppendLine("{0} tileX = Tile - Width * floor(Tile * tileCount.x);", precision);
s.AppendLine("Out = (UV + {0}2(abs((Width - 1) * Invert.x - tileX), tileY)) * tileCount;", precision);
}
});
}
return
@"
{
Tile = fmod(Tile, Width*Height);
{precision}2 tileCount = {precision}2(1.0, 1.0) / {precision}2(Width, Height);
{precision} tileY = floor(Tile * tileCount.x);
{precision} tileX = Tile - Width * tileY;
Out = (UV + {precision}2(tileX, tileY)) * tileCount;
}
";
public bool RequiresMeshUV(UVChannel channel)
{
s_TempSlots.Clear();
GetInputSlots(s_TempSlots);
foreach (var slot in s_TempSlots)
{
if (slot.RequiresMeshUV(channel))
return true;
}
return false;
}
}
}
正在加载...
取消
保存