Matt Dean
7 年前
当前提交
352a061a
共有 71 个文件被更改,包括 1094 次插入 和 365 次删除
-
2LICENSE
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs
-
7MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureSamplerState.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/UVMaterialSlot.cs
-
5MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/MasterNodes/UnlitMasterNode.cs
-
1MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendMode.cs
-
154MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendNode.cs
-
76MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Mask/ChannelMaskNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalCreateNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalStrengthNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs
-
19MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/CodeFunctionNode.cs
-
8MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/TimeNode.cs
-
12MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ScreenPositionNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/UVNode.cs
-
23MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/AmbientNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/CameraNode.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/FogNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ReflectionProbeNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SampleTexture2DNode.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/LogNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ModuloNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/PosterizeNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ReciprocalNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ReciprocalSquareRootNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/DivideNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/PowerNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/SubtractNode.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Interpolation/InverseLerpNode.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Interpolation/LerpNode.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Interpolation/SmoothstepNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/MinimumNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/OneMinusNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/RemapNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/StepNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Trigonometry/ArccosineNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/CrossProductNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/DotProductNode.cs
-
9MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/FresnelEffectNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/ProjectionNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/ReflectionNode.cs
-
4MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/RejectionNode.cs
-
162MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/FlipbookNode.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/TwirlNode.cs
-
32MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/GraphUtil.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs
-
8MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/UvChannel.cs
-
90MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs
-
3MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ColorControl.cs
-
51MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ToggleControl.cs
-
20MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
-
3MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots/ColorRGBSlotControlView.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots/ColorSlotControlView.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/ShaderGraphImporter.cs
-
108MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss
-
112MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightPBRExtraPasses.template
-
89MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightPBRForwardPass.template
-
5MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightUnlitPass.template
-
2MaterialGraphProject/Assets/UnityShaderEditor/LICENSE
-
8MaterialGraphProject/Assets/UnityShaderEditor/ShaderGraphLibrary/Functions.hlsl
-
8MaterialGraphProject/Assets/UnityShaderEditor/ShaderGraphLibrary/ShaderVariables.hlsl
-
2MaterialGraphProject/Assets/UnityShaderEditor/package.json
-
2MaterialGraphProject/UnityPackageManager/manifest.json
-
25README.md
-
189MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/InvertColorsNode.cs
-
11MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/InvertColorsNode.cs.meta
-
78MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelEnumMaskControl.cs
-
3MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelEnumMaskControl.cs.meta
|
|||
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 |
|||
return GetType().GetMethod("Unity_Flipbook", BindingFlags.Static | BindingFlags.NonPublic); |
|||
get { return true; } |
|||
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) |
|||
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 |
|||
Out = Vector2.zero; |
|||
get { return new Toggle(m_InvertX); } |
|||
set |
|||
{ |
|||
if (m_InvertX == value.isOn) |
|||
return; |
|||
m_InvertX = value.isOn; |
|||
Dirty(ModificationScope.Node); |
|||
} |
|||
} |
|||
return |
|||
@"
|
|||
{ |
|||
{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; |
|||
} |
|||
";
|
|||
[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) |
|||
{ |
|||
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, {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) + Invert.y * 1));", precision); |
|||
s.AppendLine("{0} tileX = abs(Invert.x * Width - ((Tile - Width * floor(Tile * tileCount.x)) + Invert.x * 1));", precision); |
|||
s.AppendLine("Out = (UV + {0}2(tileX, tileY)) * tileCount;", precision); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|
|||
Pass |
|||
{ |
|||
Tags{"LightMode" = "ShadowCaster"} |
|||
Pass |
|||
{ |
|||
Tags{"LightMode" = "ShadowCaster"} |
|||
ZWrite On ZTest LEqual |
|||
ZWrite On ZTest LEqual |
|||
HLSLPROGRAM |
|||
// Required to compile gles 2.0 with standard srp library |
|||
#pragma prefer_hlslcc gles |
|||
#pragma target 2.0 |
|||
#pragma vertex ShadowPassVertex |
|||
#pragma fragment ShadowPassFragment |
|||
HLSLPROGRAM |
|||
// Required to compile gles 2.0 with standard srp library |
|||
#pragma prefer_hlslcc gles |
|||
#pragma target 2.0 |
|||
#include "LWRP/Shaders/LightweightPassShadow.hlsl" |
|||
ENDHLSL |
|||
} |
|||
//-------------------------------------- |
|||
// GPU Instancing |
|||
#pragma multi_compile_instancing |
|||
Pass |
|||
{ |
|||
Tags{"LightMode" = "DepthOnly"} |
|||
#pragma vertex ShadowPassVertex |
|||
#pragma fragment ShadowPassFragment |
|||
ZWrite On |
|||
ColorMask 0 |
|||
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl" |
|||
ENDHLSL |
|||
} |
|||
HLSLPROGRAM |
|||
// Required to compile gles 2.0 with standard srp library |
|||
#pragma prefer_hlslcc gles |
|||
#pragma target 2.0 |
|||
#pragma vertex vert |
|||
#pragma fragment frag |
|||
Pass |
|||
{ |
|||
Tags{"LightMode" = "DepthOnly"} |
|||
#include "LWRP/Shaders/LightweightShaderLibrary/Core.hlsl" |
|||
ZWrite On |
|||
ColorMask 0 |
|||
float4 vert(float4 pos : POSITION) : SV_POSITION |
|||
{ |
|||
return TransformObjectToHClip(pos.xyz); |
|||
} |
|||
HLSLPROGRAM |
|||
// Required to compile gles 2.0 with standard srp library |
|||
#pragma prefer_hlslcc gles |
|||
#pragma target 2.0 |
|||
#pragma vertex vert |
|||
#pragma fragment frag |
|||
half4 frag() : SV_TARGET |
|||
{ |
|||
return 0; |
|||
} |
|||
ENDHLSL |
|||
} |
|||
#include "LWRP/ShaderLibrary/Core.hlsl" |
|||
// This pass it not used during regular rendering, only for lightmap baking. |
|||
Pass |
|||
{ |
|||
Tags{"LightMode" = "Meta"} |
|||
float4 vert(float4 pos : POSITION) : SV_POSITION |
|||
{ |
|||
return TransformObjectToHClip(pos.xyz); |
|||
} |
|||
Cull Off |
|||
half4 frag() : SV_TARGET |
|||
{ |
|||
return 0; |
|||
} |
|||
ENDHLSL |
|||
} |
|||
HLSLPROGRAM |
|||
// Required to compile gles 2.0 with standard srp library |
|||
#pragma prefer_hlslcc gles |
|||
// This pass it not used during regular rendering, only for lightmap baking. |
|||
Pass |
|||
{ |
|||
Tags{"LightMode" = "Meta"} |
|||
#pragma vertex LightweightVertexMeta |
|||
#pragma fragment LightweightFragmentMeta |
|||
Cull Off |
|||
#pragma shader_feature _EMISSION |
|||
#pragma shader_feature _METALLICSPECGLOSSMAP |
|||
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A |
|||
#pragma shader_feature EDITOR_VISUALIZATION |
|||
HLSLPROGRAM |
|||
// Required to compile gles 2.0 with standard srp library |
|||
#pragma prefer_hlslcc gles |
|||
#pragma shader_feature _SPECGLOSSMAP |
|||
#pragma vertex LightweightVertexMeta |
|||
#pragma fragment LightweightFragmentMeta |
|||
#include "LWRP/Shaders/LightweightPassMeta.hlsl" |
|||
ENDHLSL |
|||
} |
|||
#pragma shader_feature _SPECULAR_SETUP |
|||
#pragma shader_feature _EMISSION |
|||
#pragma shader_feature _METALLICSPECGLOSSMAP |
|||
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A |
|||
#pragma shader_feature EDITOR_VISUALIZATION |
|||
|
|||
#pragma shader_feature _SPECGLOSSMAP |
|||
|
|||
#include "LWRP/ShaderLibrary/LightweightPassMeta.hlsl" |
|||
ENDHLSL |
|||
} |
|
|||
{ |
|||
"name": "com.unity.shadergraph", |
|||
"description": "Shader Graph", |
|||
"version": "0.1.11", |
|||
"version": "0.1.13", |
|||
"unity": "2018.1", |
|||
"dependencies": { |
|||
} |
|
|||
{ |
|||
"registry": "https://staging-packages.unity.com", |
|||
"dependencies": { |
|||
"com.unity.render-pipelines.lightweight" : "0.1.23" |
|||
"com.unity.render-pipelines.lightweight" : "0.1.25" |
|||
} |
|||
} |
|
|||
# Shader graph |
|||
# Shader Graph |
|||
|
|||
![alt text](https://forum.unity.com/proxy.php?image=https%3A%2F%2Flh5.googleusercontent.com%2FUhB18UehZFk8jMo_2V3GW-hD2wARAcQWu6FGzcUvTByHNc51w_mLZBvB6Re5GcTHJQlPHOtzi14wUPvi_yUgWTAp3-HZU463JmxL9NSjJS5yALBSAj1Bdk8yL8zXkRVe-0crKz5F&hash=49458e7088a5be61b288167af65b6faf "Shader Graph") |
|||
|
|||
A Shader Graph enables you to build shaders visually. Instead of hand writing code you create and connect nodes in a graph network. The graph framework gives instant feedback on the changes, and it’s simple enough that new users can become involved in shader creation. |
|||
|
|||
### Disclaimer |
|||
This repository is under active development. Everything is subject to change. |
|||
Unity branch: `graphics/shadergraph` |
|||
## Instructions |
|||
|
|||
**Requires Unity 2018.1 Beta** |
|||
*BEFORE COMMITTING:* Run `hg format` on the repository. To run `hg format` inside of a Git repository (like we are doing here) do the following: |
|||
``` |
|||
> cd <location of ShaderGraph repository> |
|||
> perl ~/unity-meta/Tools/Format/format.pl . |
|||
warning: Not in a .hg repo (.repoconfig and other dependencies will not work) |
|||
warning: using last format version as no .repoconfig file was found. |
|||
(No files needed formatting; 316 total files were examined) |
|||
``` |
|||
* Download the beta [here](https://unity3d.com/unity/beta) |
|||
* Clone branch `master` |
|||
* Open contained folder `MaterialGraphProject` as a Unity Project |
|||
* Quickstart guide can be found [here](https://forum.unity.com/threads/feedback-wanted-shader-graph.511960/) |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UnityEditor.Graphing; |
|||
using UnityEditor.ShaderGraph.Drawing.Controls; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.ShaderGraph |
|||
{ |
|||
[Title("Artistic", "Adjustment", "Invert Colors")] |
|||
public class InvertColorsNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction |
|||
{ |
|||
public InvertColorsNode() |
|||
{ |
|||
name = "Invert Colors"; |
|||
UpdateNodeAfterDeserialization(); |
|||
} |
|||
|
|||
const int InputSlotId = 0; |
|||
const int OutputSlotId = 1; |
|||
const string kInputSlotName = "In"; |
|||
const string kOutputSlotName = "Out"; |
|||
|
|||
public override bool hasPreview |
|||
{ |
|||
get { return true; } |
|||
} |
|||
|
|||
string GetFunctionName() |
|||
{ |
|||
return "Unity_InvertColors_" + NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType); |
|||
} |
|||
|
|||
public sealed override void UpdateNodeAfterDeserialization() |
|||
{ |
|||
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero)); |
|||
AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero)); |
|||
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId }); |
|||
} |
|||
|
|||
int channelCount { get { return SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType); } } |
|||
|
|||
[SerializeField] |
|||
private bool m_RedChannel; |
|||
|
|||
[ToggleControl("Red")] |
|||
public Toggle redChannel |
|||
{ |
|||
get { return new Toggle(m_RedChannel, channelCount > 0); } |
|||
set |
|||
{ |
|||
if (m_RedChannel == value.isOn) |
|||
return; |
|||
m_RedChannel = value.isOn; |
|||
Dirty(ModificationScope.Node); |
|||
} |
|||
} |
|||
|
|||
[SerializeField] |
|||
private bool m_GreenChannel; |
|||
|
|||
[ToggleControl("Green")] |
|||
public Toggle greenChannel |
|||
{ |
|||
get { return new Toggle(m_GreenChannel, channelCount > 1); } |
|||
set |
|||
{ |
|||
if (m_GreenChannel == value.isOn) |
|||
return; |
|||
m_GreenChannel = value.isOn; |
|||
Dirty(ModificationScope.Node); |
|||
} |
|||
} |
|||
|
|||
[SerializeField] |
|||
private bool m_BlueChannel; |
|||
|
|||
[ToggleControl("Blue")] |
|||
public Toggle blueChannel |
|||
{ |
|||
get { return new Toggle(m_BlueChannel, channelCount > 2); } |
|||
set |
|||
{ |
|||
if (m_BlueChannel == value.isOn) |
|||
return; |
|||
m_BlueChannel = value.isOn; |
|||
Dirty(ModificationScope.Node); |
|||
} |
|||
} |
|||
|
|||
private bool m_AlphaChannel; |
|||
|
|||
[ToggleControl("Alpha")] |
|||
public Toggle alphaChannel |
|||
{ |
|||
get { return new Toggle(m_AlphaChannel, channelCount > 3); } |
|||
set |
|||
{ |
|||
if (m_AlphaChannel == value.isOn) |
|||
return; |
|||
m_AlphaChannel = value.isOn; |
|||
Dirty(ModificationScope.Node); |
|||
} |
|||
} |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var sb = new ShaderStringBuilder(); |
|||
|
|||
var inputValue = GetSlotValue(InputSlotId, generationMode); |
|||
var outputValue = GetSlotValue(OutputSlotId, generationMode); |
|||
sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId)); |
|||
|
|||
if (!generationMode.IsPreview()) |
|||
{ |
|||
sb.AppendLine("{0} _{1}_InvertColors = {0} ({2}", |
|||
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), |
|||
GetVariableNameForNode(), |
|||
Convert.ToInt32(m_RedChannel)); |
|||
if (channelCount > 1) |
|||
sb.Append(", {0}", Convert.ToInt32(m_GreenChannel)); |
|||
if (channelCount > 2) |
|||
sb.Append(", {0}", Convert.ToInt32(m_BlueChannel)); |
|||
if (channelCount > 3) |
|||
sb.Append(", {0}", Convert.ToInt32(m_AlphaChannel)); |
|||
sb.Append(");"); |
|||
} |
|||
|
|||
sb.AppendLine("{0}({1}, _{2}_InvertColors, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue); |
|||
|
|||
visitor.AddShaderChunk(sb.ToString(), false); |
|||
} |
|||
|
|||
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties) |
|||
{ |
|||
base.CollectPreviewMaterialProperties(properties); |
|||
|
|||
properties.Add(new PreviewProperty(PropertyType.Vector4) |
|||
{ |
|||
name = string.Format("_{0}_InvertColors", GetVariableNameForNode()), |
|||
vector4Value = new Vector4(Convert.ToInt32(m_RedChannel), Convert.ToInt32(m_GreenChannel), Convert.ToInt32(m_BlueChannel), Convert.ToInt32(m_AlphaChannel)), |
|||
}); |
|||
} |
|||
|
|||
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode) |
|||
{ |
|||
if (!generationMode.IsPreview()) |
|||
return; |
|||
|
|||
base.CollectShaderProperties(properties, generationMode); |
|||
|
|||
properties.AddShaderProperty(new Vector4ShaderProperty |
|||
{ |
|||
overrideReferenceName = string.Format("_{0}_InvertColors", GetVariableNameForNode()), |
|||
generatePropertyBlock = false |
|||
}); |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var sb = new ShaderStringBuilder(); |
|||
sb.AppendLine("void {0}({1} In, {2} InvertColors, out {3} Out)", |
|||
GetFunctionName(), |
|||
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision), |
|||
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision), |
|||
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision)); |
|||
using (sb.BlockScope()) |
|||
{ |
|||
sb.AppendLine("Out = abs(InvertColors - In);"); |
|||
} |
|||
visitor.AddShaderChunk(sb.ToString(), true); |
|||
} |
|||
|
|||
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode) |
|||
{ |
|||
registry.ProvideFunction(GetFunctionName(), s => |
|||
{ |
|||
s.AppendLine("void {0}({1} In, {2} InvertColors, out {3} Out)", |
|||
GetFunctionName(), |
|||
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision), |
|||
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision), |
|||
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision)); |
|||
using (s.BlockScope()) |
|||
{ |
|||
s.AppendLine("Out = abs(InvertColors - In);"); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 3e16bd8daac9e4e42861472225b22405 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Reflection; |
|||
using UnityEngine; |
|||
using UnityEditor.Graphing; |
|||
using UnityEngine.Experimental.UIElements; |
|||
|
|||
namespace UnityEditor.ShaderGraph.Drawing.Controls |
|||
{ |
|||
[AttributeUsage(AttributeTargets.Property)] |
|||
public class ChannelEnumMaskControlAttribute : Attribute, IControlAttribute |
|||
{ |
|||
string m_Label; |
|||
int m_SlotId; |
|||
|
|||
public ChannelEnumMaskControlAttribute(string label = null, int slotId = 0) |
|||
{ |
|||
m_Label = label; |
|||
m_SlotId = slotId; |
|||
} |
|||
|
|||
public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo) |
|||
{ |
|||
return new ChannelEnumMaskControlView(m_Label, m_SlotId, node, propertyInfo); |
|||
} |
|||
} |
|||
|
|||
public class ChannelEnumMaskControlView : VisualElement, INodeModificationListener |
|||
{ |
|||
GUIContent m_Label; |
|||
AbstractMaterialNode m_Node; |
|||
PropertyInfo m_PropertyInfo; |
|||
IMGUIContainer m_Container; |
|||
int m_SlotId; |
|||
|
|||
public ChannelEnumMaskControlView(string label, int slotId, AbstractMaterialNode node, PropertyInfo propertyInfo) |
|||
{ |
|||
m_Node = node; |
|||
m_PropertyInfo = propertyInfo; |
|||
m_SlotId = slotId; |
|||
//if (!propertyInfo.PropertyType.IsEnum)
|
|||
//throw new ArgumentException("Property must be an enum.", "propertyInfo");
|
|||
m_Label = new GUIContent(label ?? ObjectNames.NicifyVariableName(propertyInfo.Name)); |
|||
m_Container = new IMGUIContainer(OnGUIHandler); |
|||
Add(m_Container); |
|||
} |
|||
|
|||
void OnGUIHandler() |
|||
{ |
|||
UpdatePopup(); |
|||
} |
|||
|
|||
public void OnNodeModified(ModificationScope scope) |
|||
{ |
|||
if (scope == ModificationScope.Graph) |
|||
m_Container.Dirty(ChangeType.Repaint); |
|||
} |
|||
|
|||
private void UpdatePopup() |
|||
{ |
|||
var value = (int)m_PropertyInfo.GetValue(m_Node, null); |
|||
using (var changeCheckScope = new EditorGUI.ChangeCheckScope()) |
|||
{ |
|||
int channelCount = SlotValueHelper.GetChannelCount(m_Node.FindSlot<MaterialSlot>(m_SlotId).concreteValueType); |
|||
string[] enumEntryNames = Enum.GetNames(typeof(TextureChannel)); |
|||
string[] popupEntries = new string[channelCount]; |
|||
for (int i = 0; i < popupEntries.Length; i++) |
|||
popupEntries[i] = enumEntryNames[i]; |
|||
value = EditorGUILayout.MaskField(m_Label, value, popupEntries); |
|||
|
|||
if (changeCheckScope.changed) |
|||
{ |
|||
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name); |
|||
m_PropertyInfo.SetValue(m_Node, value, null); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c32d860c6f767f14fa889dffac527bc5 |
|||
timeCreated: 1507817885 |
撰写
预览
正在加载...
取消
保存
Reference in new issue