testss
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Struct)]
|
||||
class GenerateBlocksAttribute : Attribute
|
||||
{
|
||||
internal string path { get; set; }
|
||||
|
||||
public GenerateBlocksAttribute(string path = "")
|
||||
{
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
// this class is used to track asset dependencies in shadergraphs and subgraphs
|
||||
// that is: it tracks files that the shadergraph or subgraph must access to generate the shader
|
||||
// this data is used to automatically re-import the shadergraphs or subgraphs when any of the tracked files change
|
||||
[GenerationAPI]
|
||||
internal class AssetCollection
|
||||
{
|
||||
[Flags]
|
||||
public enum Flags
|
||||
{
|
||||
SourceDependency = 1 << 0, // ShaderGraph directly reads the source file in the Assets directory
|
||||
ArtifactDependency = 1 << 1, // ShaderGraph reads the import result artifact (i.e. subgraph import)
|
||||
IsSubGraph = 1 << 2, // This asset is a SubGraph (used when we need to get multiple levels of dependencies)
|
||||
IncludeInExportPackage = 1 << 3 // This asset should be pulled into any .unitypackages built via "Export Package.."
|
||||
}
|
||||
|
||||
internal Dictionary<GUID, Flags> assets = new Dictionary<GUID, Flags>();
|
||||
|
||||
internal IEnumerable<GUID> assetGUIDs { get { return assets.Keys; } }
|
||||
|
||||
public AssetCollection()
|
||||
{
|
||||
}
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
assets.Clear();
|
||||
}
|
||||
|
||||
// these are assets that we read the source files directly (directly reading the file out of the Assets directory)
|
||||
public void AddAssetDependency(GUID assetGUID, Flags flags)
|
||||
{
|
||||
if (assets.TryGetValue(assetGUID, out Flags existingFlags))
|
||||
{
|
||||
assets[assetGUID] = existingFlags | flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
assets.Add(assetGUID, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class DefineCollection : IEnumerable<DefineCollection.Item>
|
||||
{
|
||||
public class Item : IConditional, IShaderString
|
||||
{
|
||||
public KeywordDescriptor descriptor { get; }
|
||||
public FieldCondition[] fieldConditions { get; }
|
||||
public string value => descriptor.ToDefineString(index);
|
||||
// KeywordType.Boolean, index 0: disable, 1: enable
|
||||
// KeywordType.Enum, index into enum entries
|
||||
public int index { get; }
|
||||
|
||||
public Item(KeywordDescriptor descriptor, int index, FieldCondition[] fieldConditions)
|
||||
{
|
||||
this.descriptor = descriptor;
|
||||
this.fieldConditions = fieldConditions;
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<Item> m_Items;
|
||||
|
||||
public DefineCollection()
|
||||
{
|
||||
m_Items = new List<Item>();
|
||||
}
|
||||
|
||||
public DefineCollection Add(DefineCollection defines)
|
||||
{
|
||||
foreach (DefineCollection.Item item in defines)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefineCollection Add(KeywordDescriptor descriptor, int index)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, index, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefineCollection Add(KeywordDescriptor descriptor, int index, FieldCondition fieldCondition)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, index, new FieldCondition[] { fieldCondition }));
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefineCollection Add(KeywordDescriptor descriptor, int index, FieldCondition[] fieldConditions)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, index, fieldConditions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class DependencyCollection : IEnumerable<DependencyCollection.Item>
|
||||
{
|
||||
public class Item
|
||||
{
|
||||
public FieldDependency dependency { get; }
|
||||
|
||||
public Item(FieldDependency dependency)
|
||||
{
|
||||
this.dependency = dependency;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<DependencyCollection.Item> m_Items;
|
||||
|
||||
public DependencyCollection()
|
||||
{
|
||||
m_Items = new List<DependencyCollection.Item>();
|
||||
}
|
||||
|
||||
public DependencyCollection Add(DependencyCollection dependencies)
|
||||
{
|
||||
foreach (DependencyCollection.Item item in dependencies)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public DependencyCollection Add(FieldDependency dependency)
|
||||
{
|
||||
m_Items.Add(new Item(dependency));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<DependencyCollection.Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class FieldCollection : IEnumerable<FieldCollection.Item>
|
||||
{
|
||||
public class Item
|
||||
{
|
||||
public FieldDescriptor field { get; }
|
||||
|
||||
public Item(FieldDescriptor field)
|
||||
{
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<FieldCollection.Item> m_Items;
|
||||
|
||||
public FieldCollection()
|
||||
{
|
||||
m_Items = new List<FieldCollection.Item>();
|
||||
}
|
||||
|
||||
public FieldCollection Add(FieldCollection fields)
|
||||
{
|
||||
foreach (FieldCollection.Item item in fields)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCollection Add(FieldDescriptor field)
|
||||
{
|
||||
m_Items.Add(new Item(field));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<FieldCollection.Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class IncludeCollection : IEnumerable<IncludeCollection.Item>
|
||||
{
|
||||
public class Item : IConditional, IShaderString
|
||||
{
|
||||
public IncludeDescriptor descriptor { get; }
|
||||
public FieldCondition[] fieldConditions { get; }
|
||||
public string value => $"#include \"{descriptor.value}\"";
|
||||
|
||||
public Item(IncludeDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
this.descriptor = descriptor;
|
||||
this.fieldConditions = fieldConditions;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<Item> m_Items;
|
||||
|
||||
public IncludeCollection()
|
||||
{
|
||||
m_Items = new List<Item>();
|
||||
}
|
||||
|
||||
public IncludeCollection Add(IncludeCollection includes)
|
||||
{
|
||||
foreach (IncludeCollection.Item item in includes)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public IncludeCollection Add(string include, IncludeLocation location)
|
||||
{
|
||||
m_Items.Add(new Item(new IncludeDescriptor() { value = include, location = location }, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IncludeCollection Add(string include, IncludeLocation location, FieldCondition fieldCondition)
|
||||
{
|
||||
m_Items.Add(new Item(new IncludeDescriptor() { value = include, location = location }, new FieldCondition[] { fieldCondition }));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IncludeCollection Add(string include, IncludeLocation location, FieldCondition[] fieldConditions)
|
||||
{
|
||||
m_Items.Add(new Item(new IncludeDescriptor() { value = include, location = location }, fieldConditions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class KeywordCollection : IEnumerable<KeywordCollection.Item>
|
||||
{
|
||||
public class Item : IConditional, IShaderString
|
||||
{
|
||||
public KeywordDescriptor descriptor { get; }
|
||||
public FieldCondition[] fieldConditions { get; }
|
||||
public string value => descriptor.ToDeclarationString();
|
||||
|
||||
public Item(KeywordDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
this.descriptor = descriptor;
|
||||
this.fieldConditions = fieldConditions;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<Item> m_Items;
|
||||
|
||||
public KeywordCollection()
|
||||
{
|
||||
m_Items = new List<Item>();
|
||||
}
|
||||
|
||||
public KeywordCollection Add(KeywordCollection keywords)
|
||||
{
|
||||
foreach (KeywordCollection.Item item in keywords)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public KeywordCollection Add(KeywordDescriptor descriptor)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public KeywordCollection Add(KeywordDescriptor descriptor, FieldCondition fieldCondition)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, new FieldCondition[] { fieldCondition }));
|
||||
return this;
|
||||
}
|
||||
|
||||
public KeywordCollection Add(KeywordDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, fieldConditions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class PassCollection : IEnumerable<PassCollection.Item>
|
||||
{
|
||||
public class Item : IConditional
|
||||
{
|
||||
public PassDescriptor descriptor { get; }
|
||||
public FieldCondition[] fieldConditions { get; }
|
||||
|
||||
public Item(PassDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
this.descriptor = descriptor;
|
||||
this.fieldConditions = fieldConditions;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<Item> m_Items;
|
||||
|
||||
public PassCollection()
|
||||
{
|
||||
m_Items = new List<Item>();
|
||||
}
|
||||
|
||||
public PassCollection Add(PassCollection passes)
|
||||
{
|
||||
foreach (PassCollection.Item item in passes)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public PassCollection Add(PassDescriptor descriptor)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PassCollection Add(PassDescriptor descriptor, FieldCondition fieldCondition)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, new FieldCondition[] { fieldCondition }));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PassCollection Add(PassDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, fieldConditions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class PragmaCollection : IEnumerable<PragmaCollection.Item>
|
||||
{
|
||||
public class Item : IConditional, IShaderString
|
||||
{
|
||||
public PragmaDescriptor descriptor { get; }
|
||||
public FieldCondition[] fieldConditions { get; }
|
||||
public string value => $"#pragma {descriptor.value}";
|
||||
|
||||
public Item(PragmaDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
this.descriptor = descriptor;
|
||||
this.fieldConditions = fieldConditions;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<Item> m_Items;
|
||||
|
||||
public PragmaCollection()
|
||||
{
|
||||
m_Items = new List<Item>();
|
||||
}
|
||||
|
||||
public PragmaCollection Add(PragmaCollection pragmas)
|
||||
{
|
||||
foreach (PragmaCollection.Item item in pragmas)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public PragmaCollection Add(PragmaDescriptor descriptor)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PragmaCollection Add(PragmaDescriptor descriptor, FieldCondition fieldCondition)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, new FieldCondition[] { fieldCondition }));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PragmaCollection Add(PragmaDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, fieldConditions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class RenderStateCollection : IEnumerable<RenderStateCollection.Item>
|
||||
{
|
||||
public class Item : IConditional, IShaderString
|
||||
{
|
||||
public RenderStateDescriptor descriptor { get; }
|
||||
public FieldCondition[] fieldConditions { get; }
|
||||
public string value => descriptor.value;
|
||||
|
||||
public Item(RenderStateDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
this.descriptor = descriptor;
|
||||
this.fieldConditions = fieldConditions;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<Item> m_Items;
|
||||
|
||||
public RenderStateCollection()
|
||||
{
|
||||
m_Items = new List<Item>();
|
||||
}
|
||||
|
||||
public RenderStateCollection Add(RenderStateCollection renderStates)
|
||||
{
|
||||
foreach (RenderStateCollection.Item item in renderStates)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderStateCollection Add(RenderStateDescriptor descriptor)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderStateCollection Add(RenderStateDescriptor descriptor, FieldCondition fieldCondition)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, new FieldCondition[] { fieldCondition }));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderStateCollection Add(RenderStateDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
m_Items.Add(new Item(descriptor, fieldConditions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class StructCollection : IEnumerable<StructCollection.Item>
|
||||
{
|
||||
public class Item : IConditional
|
||||
{
|
||||
public StructDescriptor descriptor { get; }
|
||||
public FieldCondition[] fieldConditions { get; }
|
||||
|
||||
public Item(StructDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
this.descriptor = descriptor;
|
||||
this.fieldConditions = fieldConditions;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<StructCollection.Item> m_Items;
|
||||
|
||||
public StructCollection()
|
||||
{
|
||||
m_Items = new List<StructCollection.Item>();
|
||||
}
|
||||
|
||||
public StructCollection Add(StructCollection structs)
|
||||
{
|
||||
foreach (StructCollection.Item item in structs)
|
||||
{
|
||||
m_Items.Add(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StructCollection Add(StructDescriptor descriptor)
|
||||
{
|
||||
m_Items.Add(new StructCollection.Item(descriptor, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public StructCollection Add(StructDescriptor descriptor, FieldCondition fieldCondition)
|
||||
{
|
||||
m_Items.Add(new StructCollection.Item(descriptor, new FieldCondition[] { fieldCondition }));
|
||||
return this;
|
||||
}
|
||||
|
||||
public StructCollection Add(StructDescriptor descriptor, FieldCondition[] fieldConditions)
|
||||
{
|
||||
m_Items.Add(new StructCollection.Item(descriptor, fieldConditions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<StructCollection.Item> GetEnumerator()
|
||||
{
|
||||
return m_Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class TargetActiveBlockContext
|
||||
{
|
||||
public List<BlockFieldDescriptor> activeBlocks { get; private set; }
|
||||
public List<BlockFieldDescriptor> currentBlocks { get; private set; }
|
||||
public PassDescriptor? pass { get; private set; }
|
||||
|
||||
public TargetActiveBlockContext(List<BlockFieldDescriptor> currentBlocks, PassDescriptor? pass)
|
||||
{
|
||||
activeBlocks = new List<BlockFieldDescriptor>();
|
||||
this.currentBlocks = currentBlocks;
|
||||
this.pass = pass;
|
||||
}
|
||||
|
||||
public void AddBlock(BlockFieldDescriptor block, bool conditional = true)
|
||||
{
|
||||
if (conditional == true)
|
||||
{
|
||||
activeBlocks.Add(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class TargetFieldContext
|
||||
{
|
||||
public List<ConditionalField> conditionalFields { get; private set; }
|
||||
public PassDescriptor pass { get; private set; }
|
||||
public List<(BlockFieldDescriptor descriptor, bool isDefaultValue)> blocks { get; private set; }
|
||||
public List<BlockFieldDescriptor> connectedBlocks { get; private set; }
|
||||
public bool hasDotsProperties { get; private set; }
|
||||
|
||||
// NOTE: active blocks (and connectedBlocks) do not include temporarily added default blocks
|
||||
public TargetFieldContext(PassDescriptor pass, List<(BlockFieldDescriptor descriptor, bool isDefaultValue)> activeBlocks, List<BlockFieldDescriptor> connectedBlocks, bool hasDotsProperties)
|
||||
{
|
||||
conditionalFields = new List<ConditionalField>();
|
||||
this.pass = pass;
|
||||
this.blocks = activeBlocks;
|
||||
this.connectedBlocks = connectedBlocks;
|
||||
this.hasDotsProperties = hasDotsProperties;
|
||||
}
|
||||
|
||||
public void AddField(FieldDescriptor field, bool conditional = true)
|
||||
{
|
||||
conditionalFields.Add(new ConditionalField(field, conditional));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.Graphing.Util;
|
||||
using UnityEditor.ShaderGraph.Drawing;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class TargetPropertyGUIContext : VisualElement
|
||||
{
|
||||
const int kIndentWidthInPixel = 15;
|
||||
|
||||
public int globalIndentLevel {get; set;} = 0;
|
||||
|
||||
public TargetPropertyGUIContext()
|
||||
{
|
||||
}
|
||||
|
||||
public void AddProperty<T>(string label, BaseField<T> field, bool condition, EventCallback<ChangeEvent<T>> evt)
|
||||
{
|
||||
if (condition == true)
|
||||
{
|
||||
AddProperty<T>(label, field, evt);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddProperty<T>(string label, int indentLevel, BaseField<T> field, bool condition, EventCallback<ChangeEvent<T>> evt)
|
||||
{
|
||||
if (condition == true)
|
||||
{
|
||||
AddProperty<T>(label, indentLevel, field, evt);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddProperty<T>(string label, BaseField<T> field, EventCallback<ChangeEvent<T>> evt)
|
||||
{
|
||||
AddProperty<T>(label, 0, field, evt);
|
||||
}
|
||||
|
||||
public void AddProperty<T>(string label, int indentLevel, BaseField<T> field, EventCallback<ChangeEvent<T>> evt)
|
||||
{
|
||||
if (field is INotifyValueChanged<T> notifyValueChanged)
|
||||
{
|
||||
notifyValueChanged.RegisterValueChangedCallback(evt);
|
||||
}
|
||||
|
||||
var propertyRow = new PropertyRow(new Label(label));
|
||||
ApplyPadding(propertyRow, indentLevel);
|
||||
propertyRow.Add(field);
|
||||
this.hierarchy.Add(propertyRow);
|
||||
}
|
||||
|
||||
public void AddLabel(string label, int indentLevel)
|
||||
{
|
||||
var propertyRow = new PropertyRow(new Label(label));
|
||||
ApplyPadding(propertyRow, indentLevel);
|
||||
this.hierarchy.Add(propertyRow);
|
||||
}
|
||||
|
||||
public void AddHelpBox(MessageType messageType, string messageText)
|
||||
{
|
||||
var helpBox = new HelpBoxRow(messageType);
|
||||
helpBox.Add(new Label(messageText));
|
||||
this.hierarchy.Add(helpBox);
|
||||
}
|
||||
|
||||
void ApplyPadding(PropertyRow row, int indentLevel)
|
||||
{
|
||||
row.Q(className: "unity-label").style.marginLeft = (globalIndentLevel + indentLevel) * kIndentWidthInPixel;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class TargetSetupContext
|
||||
{
|
||||
public List<SubShaderDescriptor> subShaders { get; private set; }
|
||||
public List<(string shaderGUI, string renderPipelineAssetType)> customEditorForRenderPipelines { get; private set; }
|
||||
public AssetCollection assetCollection { get; private set; }
|
||||
public string defaultShaderGUI { get; private set; }
|
||||
|
||||
// pass a HashSet to the constructor to have it gather asset dependency GUIDs
|
||||
public TargetSetupContext(AssetCollection assetCollection = null)
|
||||
{
|
||||
subShaders = new List<SubShaderDescriptor>();
|
||||
this.customEditorForRenderPipelines = new List<(string shaderGUI, string renderPipelineAssetType)>();
|
||||
this.assetCollection = assetCollection;
|
||||
}
|
||||
|
||||
public void AddSubShader(SubShaderDescriptor subShader)
|
||||
{
|
||||
subShaders.Add(subShader);
|
||||
}
|
||||
|
||||
public void AddAssetDependency(GUID guid, AssetCollection.Flags flags)
|
||||
{
|
||||
assetCollection?.AddAssetDependency(guid, flags);
|
||||
}
|
||||
|
||||
public void SetDefaultShaderGUI(string defaultShaderGUI)
|
||||
{
|
||||
this.defaultShaderGUI = defaultShaderGUI;
|
||||
}
|
||||
|
||||
public void AddCustomEditorForRenderPipeline(string shaderGUI, Type renderPipelineAssetType)
|
||||
{
|
||||
this.customEditorForRenderPipelines.Add((shaderGUI, renderPipelineAssetType.FullName));
|
||||
}
|
||||
|
||||
public bool HasCustomEditorForRenderPipeline(Type renderPipelineAssetType)
|
||||
=> this.customEditorForRenderPipelines.Any(c => c.renderPipelineAssetType == renderPipelineAssetType.FullName);
|
||||
}
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
// This whole file is regrettable.
|
||||
// However, right now we need an abstraction for MaterialSlot for use with BlockFieldDescriptors.
|
||||
// MaterialSlot is very leaky, so we cant make it public but we need BlockFieldDescriptor to be public.
|
||||
// All MaterialSlot types required by a BlockFieldDescriptor need a matching Control here.
|
||||
// We also need a corresponding case in BlockNode.AddSlot for each control.
|
||||
|
||||
public interface IControl
|
||||
{
|
||||
ShaderGraphRequirements GetRequirements();
|
||||
}
|
||||
|
||||
public class PositionControl : IControl
|
||||
{
|
||||
public CoordinateSpace space { get; private set; }
|
||||
|
||||
public PositionControl(CoordinateSpace space)
|
||||
{
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return new ShaderGraphRequirements() { requiresPosition = space.ToNeededCoordinateSpace() };
|
||||
}
|
||||
}
|
||||
|
||||
public class NormalControl : IControl
|
||||
{
|
||||
public CoordinateSpace space { get; private set; }
|
||||
|
||||
public NormalControl(CoordinateSpace space)
|
||||
{
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return new ShaderGraphRequirements() { requiresNormal = space.ToNeededCoordinateSpace() };
|
||||
}
|
||||
}
|
||||
|
||||
public class TangentControl : IControl
|
||||
{
|
||||
public CoordinateSpace space { get; private set; }
|
||||
|
||||
public TangentControl(CoordinateSpace space)
|
||||
{
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return new ShaderGraphRequirements() { requiresTangent = space.ToNeededCoordinateSpace() };
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorControl : IControl
|
||||
{
|
||||
public Color value { get; private set; }
|
||||
public bool hdr { get; private set; }
|
||||
|
||||
public ColorControl(Color value, bool hdr)
|
||||
{
|
||||
this.value = value;
|
||||
this.hdr = hdr;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return ShaderGraphRequirements.none;
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorRGBAControl : IControl
|
||||
{
|
||||
public Color value { get; private set; }
|
||||
|
||||
public ColorRGBAControl(Color value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return ShaderGraphRequirements.none;
|
||||
}
|
||||
}
|
||||
|
||||
public class FloatControl : IControl
|
||||
{
|
||||
public float value { get; private set; }
|
||||
|
||||
public FloatControl(float value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return ShaderGraphRequirements.none;
|
||||
}
|
||||
}
|
||||
|
||||
public class Vector2Control : IControl
|
||||
{
|
||||
public Vector2 value { get; private set; }
|
||||
|
||||
public Vector2Control(Vector2 value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return ShaderGraphRequirements.none;
|
||||
}
|
||||
}
|
||||
|
||||
public class Vector3Control : IControl
|
||||
{
|
||||
public Vector3 value { get; private set; }
|
||||
|
||||
public Vector3Control(Vector3 value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ShaderGraphRequirements GetRequirements()
|
||||
{
|
||||
return ShaderGraphRequirements.none;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct ConditionalField
|
||||
{
|
||||
public FieldDescriptor field { get; }
|
||||
public bool condition { get; }
|
||||
|
||||
public ConditionalField(FieldDescriptor field, bool condition)
|
||||
{
|
||||
this.field = field;
|
||||
this.condition = condition;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class FieldCondition
|
||||
{
|
||||
public FieldDescriptor field { get; }
|
||||
public bool condition { get; }
|
||||
|
||||
public FieldCondition(FieldDescriptor field, bool condition)
|
||||
{
|
||||
this.field = field;
|
||||
this.condition = condition;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct FieldDependency
|
||||
{
|
||||
public FieldDescriptor field;
|
||||
public FieldDescriptor dependsOn;
|
||||
|
||||
public FieldDependency(FieldDescriptor field, FieldDescriptor dependsOn)
|
||||
{
|
||||
this.field = field;
|
||||
this.dependsOn = dependsOn;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable][GenerationAPI]
|
||||
internal struct KeywordEntry
|
||||
{
|
||||
public int id; // Used to determine what MaterialSlot an entry belongs to
|
||||
public string displayName;
|
||||
public string referenceName;
|
||||
|
||||
// In this case, we will handle the actual IDs later
|
||||
public KeywordEntry(string displayName, string referenceName)
|
||||
{
|
||||
this.id = -1;
|
||||
this.displayName = displayName;
|
||||
this.referenceName = referenceName;
|
||||
}
|
||||
|
||||
internal KeywordEntry(int id, string displayName, string referenceName)
|
||||
{
|
||||
this.id = id;
|
||||
this.displayName = displayName;
|
||||
this.referenceName = referenceName;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
internal class BlockFieldDescriptor : FieldDescriptor
|
||||
{
|
||||
public string displayName { get; }
|
||||
public IControl control { get; }
|
||||
public ShaderStage shaderStage { get; }
|
||||
public bool isHidden { get; }
|
||||
public bool isUnknown { get; }
|
||||
|
||||
internal string path { get; set; }
|
||||
|
||||
public BlockFieldDescriptor(string tag, string referenceName, string define, IControl control, ShaderStage shaderStage, bool isHidden = false, bool isUnknown = false)
|
||||
: base(tag, referenceName, define)
|
||||
{
|
||||
this.displayName = referenceName;
|
||||
this.control = control;
|
||||
this.shaderStage = shaderStage;
|
||||
this.isHidden = isHidden;
|
||||
this.isUnknown = isUnknown;
|
||||
}
|
||||
|
||||
public BlockFieldDescriptor(string tag, string referenceName, string displayName, string define, IControl control, ShaderStage shaderStage, bool isHidden = false, bool isUnknown = false)
|
||||
: base(tag, referenceName, define)
|
||||
{
|
||||
this.displayName = displayName;
|
||||
this.control = control;
|
||||
this.shaderStage = shaderStage;
|
||||
this.isHidden = isHidden;
|
||||
this.isUnknown = isUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This exposes the MaterialSlot API
|
||||
// TODO: This needs to be removed but is currently required by HDRP for DiffusionProfileInputMaterialSlot
|
||||
internal class CustomSlotBlockFieldDescriptor : BlockFieldDescriptor
|
||||
{
|
||||
public Func<MaterialSlot> createSlot;
|
||||
|
||||
public CustomSlotBlockFieldDescriptor(string tag, string referenceName, string define, Func<MaterialSlot> createSlot)
|
||||
: base(tag, referenceName, define, null, ShaderStage.Fragment)
|
||||
{
|
||||
this.createSlot = createSlot;
|
||||
}
|
||||
|
||||
public CustomSlotBlockFieldDescriptor(string tag, string referenceName, string displayName, string define, Func<MaterialSlot> createSlot)
|
||||
: base(tag, referenceName, displayName, define, null, ShaderStage.Fragment)
|
||||
{
|
||||
this.createSlot = createSlot;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class FieldDescriptor
|
||||
{
|
||||
// Default
|
||||
public string tag { get; }
|
||||
public string name { get; }
|
||||
public string define { get; }
|
||||
|
||||
// StructField
|
||||
public string type { get; }
|
||||
public int vectorCount { get; }
|
||||
public string semantic { get; }
|
||||
public string preprocessor { get; }
|
||||
public StructFieldOptions subscriptOptions { get; }
|
||||
|
||||
public FieldDescriptor(string tag, string name, string define)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.name = name;
|
||||
this.define = define;
|
||||
}
|
||||
|
||||
public FieldDescriptor(string tag, string name, string define, ShaderValueType type,
|
||||
string semantic = "", string preprocessor = "", StructFieldOptions subscriptOptions = StructFieldOptions.Static)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.name = name;
|
||||
this.define = define;
|
||||
this.type = type.ToShaderString();
|
||||
this.vectorCount = type.GetVectorCount();
|
||||
this.semantic = semantic;
|
||||
this.preprocessor = preprocessor;
|
||||
this.subscriptOptions = subscriptOptions;
|
||||
}
|
||||
|
||||
public FieldDescriptor(string tag, string name, string define, string type,
|
||||
string semantic = "", string preprocessor = "", StructFieldOptions subscriptOptions = StructFieldOptions.Static)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.name = name;
|
||||
this.define = define;
|
||||
this.type = type;
|
||||
this.vectorCount = 0;
|
||||
this.semantic = semantic;
|
||||
this.preprocessor = preprocessor;
|
||||
this.subscriptOptions = subscriptOptions;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal class IncludeDescriptor
|
||||
{
|
||||
public string value;
|
||||
public IncludeLocation location;
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct KeywordDescriptor
|
||||
{
|
||||
public string displayName;
|
||||
public string referenceName;
|
||||
public KeywordType type;
|
||||
public KeywordDefinition definition;
|
||||
public KeywordScope scope;
|
||||
public int value;
|
||||
public KeywordEntry[] entries;
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct PassDescriptor
|
||||
{
|
||||
// Definition
|
||||
public string displayName;
|
||||
public string referenceName;
|
||||
public string lightMode;
|
||||
public bool useInPreview;
|
||||
public bool virtualTextureFeedback;
|
||||
|
||||
// Templates
|
||||
public string passTemplatePath;
|
||||
public string[] sharedTemplateDirectories;
|
||||
|
||||
// Port mask
|
||||
public BlockFieldDescriptor[] validVertexBlocks;
|
||||
public BlockFieldDescriptor[] validPixelBlocks;
|
||||
|
||||
// Collections
|
||||
public StructCollection structs;
|
||||
public FieldCollection requiredFields;
|
||||
public DependencyCollection fieldDependencies;
|
||||
public RenderStateCollection renderStates;
|
||||
public PragmaCollection pragmas;
|
||||
public DefineCollection defines;
|
||||
public KeywordCollection keywords;
|
||||
public IncludeCollection includes;
|
||||
|
||||
// Methods
|
||||
public bool Equals(PassDescriptor other)
|
||||
{
|
||||
return referenceName == other.referenceName;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct PragmaDescriptor
|
||||
{
|
||||
public string value;
|
||||
}
|
||||
|
||||
[GenerationAPI]
|
||||
internal static class Pragma
|
||||
{
|
||||
static string GetPlatformList(Platform[] platforms)
|
||||
{
|
||||
var rendererStrings = platforms.Select(x => x.ToShaderString());
|
||||
return string.Join(" ", rendererStrings);
|
||||
}
|
||||
|
||||
public static PragmaDescriptor Target(ShaderModel value) => new PragmaDescriptor { value = $"target {value.ToShaderString()}" };
|
||||
public static PragmaDescriptor Vertex(string value) => new PragmaDescriptor { value = $"vertex {value}" };
|
||||
public static PragmaDescriptor Fragment(string value) => new PragmaDescriptor { value = $"fragment {value}" };
|
||||
public static PragmaDescriptor Geometry(string value) => new PragmaDescriptor { value = $"geometry {value}" };
|
||||
public static PragmaDescriptor Hull(string value) => new PragmaDescriptor { value = $"hull {value}" };
|
||||
public static PragmaDescriptor Domain(string value) => new PragmaDescriptor { value = $"domain {value}" };
|
||||
public static PragmaDescriptor Raytracing(string value) => new PragmaDescriptor { value = $"raytracing {value}" };
|
||||
public static PragmaDescriptor OnlyRenderers(Platform[] renderers) => new PragmaDescriptor { value = $"only_renderers {GetPlatformList(renderers)}" };
|
||||
public static PragmaDescriptor ExcludeRenderers(Platform[] renderers) => new PragmaDescriptor { value = $"exclude_renderers {GetPlatformList(renderers)}" };
|
||||
public static PragmaDescriptor PreferHlslCC(Platform[] renderers) => new PragmaDescriptor { value = $"prefer_hlslcc {GetPlatformList(renderers)}" };
|
||||
public static PragmaDescriptor InstancingOptions(InstancingOptions value) => new PragmaDescriptor { value = $"instancing_options {value.ToShaderString()}" };
|
||||
public static PragmaDescriptor MultiCompileInstancing => new PragmaDescriptor { value = "multi_compile_instancing" };
|
||||
public static PragmaDescriptor DOTSInstancing => new PragmaDescriptor { value = "multi_compile _ DOTS_INSTANCING_ON" };
|
||||
public static PragmaDescriptor MultiCompileFog => new PragmaDescriptor { value = "multi_compile_fog" };
|
||||
public static PragmaDescriptor EditorSyncCompilation => new PragmaDescriptor { value = "editor_sync_compilation" };
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum RenderStateType
|
||||
{
|
||||
Cull,
|
||||
Blend,
|
||||
BlendOp,
|
||||
ZTest,
|
||||
ZWrite,
|
||||
ColorMask,
|
||||
ZClip,
|
||||
Stencil,
|
||||
AlphaToMask,
|
||||
}
|
||||
|
||||
[GenerationAPI]
|
||||
internal struct RenderStateDescriptor
|
||||
{
|
||||
public string value;
|
||||
public RenderStateType type;
|
||||
}
|
||||
|
||||
[GenerationAPI]
|
||||
internal static class RenderState
|
||||
{
|
||||
public static RenderStateDescriptor Cull(Cull value) => new RenderStateDescriptor { type = RenderStateType.Cull, value = $"Cull {value}" };
|
||||
public static RenderStateDescriptor Cull(string value) => new RenderStateDescriptor { type = RenderStateType.Cull, value = $"Cull {value}" };
|
||||
public static RenderStateDescriptor Blend(Blend src, Blend dst) => new RenderStateDescriptor { type = RenderStateType.Blend, value = $"Blend {src} {dst}" };
|
||||
public static RenderStateDescriptor Blend(string src, string dst) => new RenderStateDescriptor { type = RenderStateType.Blend, value = $"Blend {src} {dst}" };
|
||||
public static RenderStateDescriptor Blend(Blend src, Blend dst, Blend alphaSrc, Blend alphaDst) => new RenderStateDescriptor { type = RenderStateType.Blend, value = $"Blend {src} {dst}, {alphaSrc} {alphaDst}" };
|
||||
public static RenderStateDescriptor Blend(string src, string dst, string alphaSrc, string alphaDst) => new RenderStateDescriptor { type = RenderStateType.Blend, value = $"Blend {src} {dst}, {alphaSrc} {alphaDst}" };
|
||||
public static RenderStateDescriptor Blend(string value) => new RenderStateDescriptor { type = RenderStateType.Blend, value = value };
|
||||
public static RenderStateDescriptor BlendOp(BlendOp op) => new RenderStateDescriptor { type = RenderStateType.BlendOp, value = $"BlendOp {op}" };
|
||||
public static RenderStateDescriptor BlendOp(string op) => new RenderStateDescriptor { type = RenderStateType.BlendOp, value = $"BlendOp {op}" };
|
||||
public static RenderStateDescriptor BlendOp(BlendOp op, BlendOp opAlpha) => new RenderStateDescriptor { type = RenderStateType.BlendOp, value = $"BlendOp {op}, {opAlpha}" };
|
||||
public static RenderStateDescriptor BlendOp(string op, string opAlpha) => new RenderStateDescriptor { type = RenderStateType.BlendOp, value = $"BlendOp {op}, {opAlpha}" };
|
||||
public static RenderStateDescriptor ZTest(ZTest value) => new RenderStateDescriptor { type = RenderStateType.ZTest, value = $"ZTest {value}" };
|
||||
public static RenderStateDescriptor ZTest(string value) => new RenderStateDescriptor { type = RenderStateType.ZTest, value = $"ZTest {value}" };
|
||||
public static RenderStateDescriptor ZWrite(ZWrite value) => new RenderStateDescriptor { type = RenderStateType.ZWrite, value = $"ZWrite {value}" };
|
||||
public static RenderStateDescriptor ZWrite(string value) => new RenderStateDescriptor { type = RenderStateType.ZWrite, value = $"ZWrite {value}" };
|
||||
public static RenderStateDescriptor ZClip(string value) => new RenderStateDescriptor { type = RenderStateType.ZClip, value = $"ZClip {value}" };
|
||||
public static RenderStateDescriptor ColorMask(string value) => new RenderStateDescriptor { type = RenderStateType.ColorMask, value = $"{value}" };
|
||||
public static RenderStateDescriptor AlphaToMask(string value) => new RenderStateDescriptor { type = RenderStateType.AlphaToMask, value = $"AlphaToMask {value}" };
|
||||
public static RenderStateDescriptor Stencil(StencilDescriptor value) => new RenderStateDescriptor { type = RenderStateType.Stencil, value = value.ToShaderString() };
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct StencilDescriptor
|
||||
{
|
||||
public string WriteMask;
|
||||
public string Ref;
|
||||
public string Comp;
|
||||
public string ZFail;
|
||||
public string Fail;
|
||||
public string Pass;
|
||||
public string CompBack;
|
||||
public string ZFailBack;
|
||||
public string FailBack;
|
||||
public string PassBack;
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct StructDescriptor
|
||||
{
|
||||
public string name;
|
||||
public bool packFields;
|
||||
public FieldDescriptor[] fields;
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal struct SubShaderDescriptor
|
||||
{
|
||||
public string pipelineTag;
|
||||
public string customTags;
|
||||
public string renderType;
|
||||
public string renderQueue;
|
||||
public bool generatesPreview;
|
||||
public PassCollection passes;
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum Blend
|
||||
{
|
||||
One,
|
||||
Zero,
|
||||
SrcColor,
|
||||
SrcAlpha,
|
||||
DstColor,
|
||||
DstAlpha,
|
||||
OneMinusSrcColor,
|
||||
OneMinusSrcAlpha,
|
||||
OneMinusDstColor,
|
||||
OneMinusDstAlpha,
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum BlendOp
|
||||
{
|
||||
Add,
|
||||
Sub,
|
||||
RevSub,
|
||||
Min,
|
||||
Max,
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum Cull
|
||||
{
|
||||
Back,
|
||||
Front,
|
||||
Off,
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum IncludeLocation
|
||||
{
|
||||
Pregraph,
|
||||
Postgraph
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum InstancingOptions
|
||||
{
|
||||
RenderingLayer,
|
||||
NoLightProbe,
|
||||
NoLodFade,
|
||||
}
|
||||
|
||||
[GenerationAPI]
|
||||
internal static class InstancingOptionsExtensions
|
||||
{
|
||||
public static string ToShaderString(this InstancingOptions options)
|
||||
{
|
||||
switch (options)
|
||||
{
|
||||
case InstancingOptions.RenderingLayer:
|
||||
return "renderinglayer";
|
||||
case InstancingOptions.NoLightProbe:
|
||||
return "nolightprobe";
|
||||
case InstancingOptions.NoLodFade:
|
||||
return "nolodfade";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum KeywordDefinition
|
||||
{
|
||||
ShaderFeature, // adds #pragma shaderfeature for the keyword
|
||||
MultiCompile, // adds #pragma multicompile for the keyword
|
||||
Predefined // does not add ShaderFeature or MultiCompile pragmas, and is forced to be !exposed
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum KeywordScope
|
||||
{
|
||||
Local,
|
||||
Global
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum KeywordType
|
||||
{
|
||||
Boolean,
|
||||
Enum
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum NormalDropOffSpace
|
||||
{
|
||||
Tangent,
|
||||
Object,
|
||||
World
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum Platform
|
||||
{
|
||||
D3D11,
|
||||
GLCore,
|
||||
GLES,
|
||||
GLES3,
|
||||
Metal,
|
||||
Vulkan,
|
||||
D3D9,
|
||||
XboxOne,
|
||||
GameCoreXboxOne,
|
||||
GameCoreXboxSeries,
|
||||
Playstation,
|
||||
Switch,
|
||||
}
|
||||
|
||||
[GenerationAPI]
|
||||
internal static class PlatformExtensions
|
||||
{
|
||||
public static string ToShaderString(this Platform platform)
|
||||
{
|
||||
switch (platform)
|
||||
{
|
||||
case Platform.D3D11:
|
||||
return "d3d11";
|
||||
case Platform.GLCore:
|
||||
return "glcore";
|
||||
case Platform.GLES:
|
||||
return "gles";
|
||||
case Platform.GLES3:
|
||||
return "gles3";
|
||||
case Platform.Metal:
|
||||
return "metal";
|
||||
case Platform.Vulkan:
|
||||
return "vulkan";
|
||||
case Platform.D3D9:
|
||||
return "d3d11_9x";
|
||||
case Platform.XboxOne:
|
||||
return "xboxone";
|
||||
case Platform.GameCoreXboxOne:
|
||||
return "xboxone";
|
||||
case Platform.GameCoreXboxSeries:
|
||||
return "xboxseries";
|
||||
case Platform.Playstation:
|
||||
return "playstation";
|
||||
case Platform.Switch:
|
||||
return "switch";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class PragmaRenderers
|
||||
{
|
||||
// Return high end platform list for the only renderer directive (The list use by HDRP)
|
||||
internal static Platform[] GetHighEndPlatformArray()
|
||||
{
|
||||
return new Platform[] { Platform.D3D11, Platform.Playstation, Platform.XboxOne, Platform.GameCoreXboxSeries, Platform.Vulkan, Platform.Metal, Platform.Switch };
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[GenerationAPI]
|
||||
public enum PropertyType
|
||||
{
|
||||
Color,
|
||||
Texture2D,
|
||||
Texture2DArray,
|
||||
Texture3D,
|
||||
Cubemap,
|
||||
Gradient,
|
||||
Boolean,
|
||||
Float,
|
||||
Vector2,
|
||||
Vector3,
|
||||
Vector4,
|
||||
Matrix2,
|
||||
Matrix3,
|
||||
Matrix4,
|
||||
SamplerState,
|
||||
VirtualTexture
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum RenderQueue
|
||||
{
|
||||
Background,
|
||||
Geometry,
|
||||
Transparent,
|
||||
Overlay,
|
||||
AlphaTest
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum RenderType
|
||||
{
|
||||
Opaque,
|
||||
Transparent,
|
||||
TransparentCutout,
|
||||
Background,
|
||||
Overlay
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum ShaderModel
|
||||
{
|
||||
Target20,
|
||||
Target25,
|
||||
Target30,
|
||||
Target35,
|
||||
Target40,
|
||||
Target45,
|
||||
Target46,
|
||||
Target50
|
||||
}
|
||||
|
||||
[GenerationAPI]
|
||||
internal static class ShaderModelExtensions
|
||||
{
|
||||
public static string ToShaderString(this ShaderModel shaderModel)
|
||||
{
|
||||
switch (shaderModel)
|
||||
{
|
||||
case ShaderModel.Target20:
|
||||
return "2.0";
|
||||
case ShaderModel.Target25:
|
||||
return "2.5";
|
||||
case ShaderModel.Target30:
|
||||
return "3.0";
|
||||
case ShaderModel.Target35:
|
||||
return "3.5";
|
||||
case ShaderModel.Target40:
|
||||
return "4.0";
|
||||
case ShaderModel.Target45:
|
||||
return "4.5";
|
||||
case ShaderModel.Target46:
|
||||
return "4.6";
|
||||
case ShaderModel.Target50:
|
||||
return "5.0";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum ShaderValueType
|
||||
{
|
||||
Boolean,
|
||||
Float,
|
||||
Float2,
|
||||
Float3,
|
||||
Float4,
|
||||
Matrix2,
|
||||
Matrix3,
|
||||
Matrix4,
|
||||
Integer,
|
||||
Uint,
|
||||
Uint4,
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum StructFieldOptions
|
||||
{
|
||||
Static = 0,
|
||||
Optional = 1 << 0,
|
||||
Generated = 1 << 1
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum ZTest
|
||||
{
|
||||
Less,
|
||||
Greater,
|
||||
LEqual,
|
||||
GEqual,
|
||||
Equal,
|
||||
NotEqual,
|
||||
Always,
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal enum ZWrite
|
||||
{
|
||||
On,
|
||||
Off,
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
public struct GraphCode
|
||||
{
|
||||
public string code { get; internal set; }
|
||||
public ShaderGraphRequirements requirements { get; internal set; }
|
||||
public IEnumerable<AbstractShaderProperty> properties;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
interface IHasMetadata
|
||||
{
|
||||
string identifier { get; }
|
||||
ScriptableObject GetMetadataObject();
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public struct OutputMetadata
|
||||
{
|
||||
[SerializeField]
|
||||
int m_Index;
|
||||
|
||||
[SerializeField]
|
||||
string m_ReferenceName;
|
||||
|
||||
[SerializeField]
|
||||
int m_Id;
|
||||
|
||||
internal OutputMetadata(int index, string referenceName, int id)
|
||||
{
|
||||
m_Index = index;
|
||||
m_ReferenceName = referenceName;
|
||||
m_Id = id;
|
||||
}
|
||||
|
||||
public int index => m_Index;
|
||||
|
||||
public int id => m_Id;
|
||||
|
||||
public string referenceName => m_ReferenceName;
|
||||
|
||||
internal bool isValid => referenceName != null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,165 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
internal interface IActiveFields : KeywordDependentCollection.IInstance, KeywordDependentCollection.ISet<IActiveFields>
|
||||
{
|
||||
IEnumerable<FieldDescriptor> fields { get; }
|
||||
|
||||
bool Add(FieldDescriptor field);
|
||||
bool Contains(FieldDescriptor field);
|
||||
bool Contains(string value);
|
||||
}
|
||||
|
||||
internal interface IActiveFieldsSet : KeywordDependentCollection.ISet<IActiveFields>
|
||||
{
|
||||
void AddAll(FieldDescriptor field);
|
||||
}
|
||||
|
||||
internal sealed class ActiveFields : KeywordDependentCollection<
|
||||
HashSet<FieldDescriptor>,
|
||||
ActiveFields.All,
|
||||
ActiveFields.AllPermutations,
|
||||
ActiveFields.ForPermutationIndex,
|
||||
ActiveFields.Base,
|
||||
IActiveFields,
|
||||
IActiveFieldsSet
|
||||
>
|
||||
{
|
||||
public struct ForPermutationIndex : IActiveFields, IActiveFieldsSet
|
||||
{
|
||||
private ActiveFields m_Source;
|
||||
private int m_PermutationIndex;
|
||||
|
||||
public KeywordDependentCollection.KeywordPermutationInstanceType type => KeywordDependentCollection.KeywordPermutationInstanceType.Permutation;
|
||||
public IEnumerable<IActiveFields> instances => Enumerable.Repeat<IActiveFields>(this, 1);
|
||||
public IEnumerable<FieldDescriptor> fields =>
|
||||
m_Source.baseStorage.Union(m_Source.GetOrCreateForPermutationIndex(m_PermutationIndex));
|
||||
public int instanceCount => 1;
|
||||
public int permutationIndex => m_PermutationIndex;
|
||||
|
||||
internal ForPermutationIndex(ActiveFields source, int index)
|
||||
{
|
||||
m_Source = source;
|
||||
m_PermutationIndex = index;
|
||||
}
|
||||
|
||||
public bool Add(FieldDescriptor field)
|
||||
=> m_Source.GetOrCreateForPermutationIndex(m_PermutationIndex).Add(field);
|
||||
|
||||
public bool Contains(FieldDescriptor field) =>
|
||||
m_Source.baseStorage.Contains(field)
|
||||
|| m_Source.GetOrCreateForPermutationIndex(m_PermutationIndex).Contains(field);
|
||||
|
||||
public bool Contains(string value) => m_Source.baseStorage.Where(x => x.ToFieldString() == value).Any()
|
||||
|| m_Source.GetOrCreateForPermutationIndex(m_PermutationIndex).Where(x => x.ToFieldString() == value).Any();
|
||||
public void AddAll(FieldDescriptor field) => Add(field);
|
||||
}
|
||||
|
||||
public struct Base : IActiveFields, IActiveFieldsSet
|
||||
{
|
||||
private ActiveFields m_Source;
|
||||
|
||||
public IEnumerable<FieldDescriptor> fields => m_Source.baseStorage;
|
||||
public int instanceCount => 1;
|
||||
public int permutationIndex => - 1;
|
||||
public KeywordDependentCollection.KeywordPermutationInstanceType type => KeywordDependentCollection.KeywordPermutationInstanceType.Base;
|
||||
public IEnumerable<IActiveFields> instances => Enumerable.Repeat<IActiveFields>(this, 1);
|
||||
|
||||
internal Base(ActiveFields source)
|
||||
{
|
||||
m_Source = source;
|
||||
}
|
||||
|
||||
public bool Add(FieldDescriptor field) => m_Source.baseStorage.Add(field);
|
||||
public bool Contains(FieldDescriptor field) => m_Source.baseStorage.Contains(field);
|
||||
public bool Contains(string value) => m_Source.baseStorage.Where(x => x.ToFieldString() == value).Any();
|
||||
public void AddAll(FieldDescriptor field) => Add(field);
|
||||
}
|
||||
|
||||
public struct All : IActiveFieldsSet
|
||||
{
|
||||
private ActiveFields m_Source;
|
||||
public int instanceCount => m_Source.permutationCount + 1;
|
||||
|
||||
internal All(ActiveFields source)
|
||||
{
|
||||
m_Source = source;
|
||||
}
|
||||
|
||||
public void AddAll(FieldDescriptor field)
|
||||
{
|
||||
m_Source.baseInstance.Add(field);
|
||||
for (var i = 0; i < m_Source.permutationCount; ++i)
|
||||
m_Source.GetOrCreateForPermutationIndex(i).Add(field);
|
||||
}
|
||||
|
||||
public IEnumerable<IActiveFields> instances
|
||||
{
|
||||
get
|
||||
{
|
||||
var self = this;
|
||||
return m_Source.permutationStorages
|
||||
.Select((v, i) => new ForPermutationIndex(self.m_Source, i) as IActiveFields)
|
||||
.Union(Enumerable.Repeat((IActiveFields)m_Source.baseInstance, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct AllPermutations : IActiveFieldsSet
|
||||
{
|
||||
private ActiveFields m_Source;
|
||||
public int instanceCount => m_Source.permutationCount;
|
||||
|
||||
internal AllPermutations(ActiveFields source)
|
||||
{
|
||||
m_Source = source;
|
||||
}
|
||||
|
||||
public void AddAll(FieldDescriptor field)
|
||||
{
|
||||
for (var i = 0; i < m_Source.permutationCount; ++i)
|
||||
m_Source.GetOrCreateForPermutationIndex(i).Add(field);
|
||||
}
|
||||
|
||||
public IEnumerable<IActiveFields> instances
|
||||
{
|
||||
get
|
||||
{
|
||||
var self = this;
|
||||
return m_Source.permutationStorages
|
||||
.Select((v, i) => new ForPermutationIndex(self.m_Source, i) as IActiveFields);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct NoPermutation : IActiveFields, IActiveFieldsSet
|
||||
{
|
||||
private ActiveFields m_Source;
|
||||
|
||||
public IEnumerable<FieldDescriptor> fields => m_Source.baseStorage;
|
||||
public int instanceCount => 1;
|
||||
public int permutationIndex => - 1;
|
||||
public KeywordDependentCollection.KeywordPermutationInstanceType type => KeywordDependentCollection.KeywordPermutationInstanceType.Base;
|
||||
|
||||
internal NoPermutation(ActiveFields source)
|
||||
{
|
||||
m_Source = source;
|
||||
}
|
||||
|
||||
public bool Add(FieldDescriptor field) => m_Source.baseInstance.Add(field);
|
||||
public bool Contains(FieldDescriptor field) => m_Source.baseStorage.Contains(field);
|
||||
public bool Contains(string value) => m_Source.baseStorage.Where(x => x.ToFieldString() == value).Any();
|
||||
public void AddAll(FieldDescriptor field) => Add(field);
|
||||
public IEnumerable<IActiveFields> instances => Enumerable.Repeat<IActiveFields>(this, 1);
|
||||
}
|
||||
|
||||
protected override All CreateAllSmartPointer() => new All(this);
|
||||
protected override AllPermutations CreateAllPermutationsSmartPointer() => new AllPermutations(this);
|
||||
protected override ForPermutationIndex CreateForPermutationSmartPointer(int index) => new ForPermutationIndex(this, index);
|
||||
protected override Base CreateBaseSmartPointer() => new Base(this);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,886 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Drawing;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Assertions;
|
||||
using Pool = UnityEngine.Pool;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class Generator
|
||||
{
|
||||
const string kDebugSymbol = "SHADERGRAPH_DEBUG";
|
||||
|
||||
GraphData m_GraphData;
|
||||
AbstractMaterialNode m_OutputNode;
|
||||
Target[] m_Targets;
|
||||
List<BlockNode> m_ActiveBlocks;
|
||||
List<BlockNode> m_TemporaryBlocks;
|
||||
GenerationMode m_Mode;
|
||||
string m_Name;
|
||||
|
||||
ShaderStringBuilder m_Builder;
|
||||
List<PropertyCollector.TextureInfo> m_ConfiguredTextures;
|
||||
AssetCollection m_assetCollection;
|
||||
|
||||
public string generatedShader => m_Builder.ToCodeBlock();
|
||||
public List<PropertyCollector.TextureInfo> configuredTextures => m_ConfiguredTextures;
|
||||
public List<BlockNode> temporaryBlocks => m_TemporaryBlocks;
|
||||
|
||||
public Generator(GraphData graphData, AbstractMaterialNode outputNode, GenerationMode mode, string name, AssetCollection assetCollection)
|
||||
{
|
||||
m_GraphData = graphData;
|
||||
m_OutputNode = outputNode;
|
||||
m_Mode = mode;
|
||||
m_Name = name;
|
||||
|
||||
m_Builder = new ShaderStringBuilder();
|
||||
m_ConfiguredTextures = new List<PropertyCollector.TextureInfo>();
|
||||
m_assetCollection = assetCollection;
|
||||
|
||||
m_ActiveBlocks = graphData.GetNodes<BlockNode>().ToList();
|
||||
m_TemporaryBlocks = new List<BlockNode>();
|
||||
GetTargetImplementations();
|
||||
BuildShader();
|
||||
}
|
||||
|
||||
void GetTargetImplementations()
|
||||
{
|
||||
if (m_OutputNode == null)
|
||||
{
|
||||
m_Targets = m_GraphData.activeTargets.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Targets = new Target[] { new PreviewTarget() };
|
||||
}
|
||||
}
|
||||
|
||||
public ActiveFields GatherActiveFieldsFromNode(AbstractMaterialNode outputNode, PassDescriptor pass, List<(BlockFieldDescriptor descriptor, bool isDefaultValue)> activeBlocks, List<BlockFieldDescriptor> connectedBlocks, Target target)
|
||||
{
|
||||
var activeFields = new ActiveFields();
|
||||
if (outputNode == null)
|
||||
{
|
||||
bool hasDotsProperties = false;
|
||||
m_GraphData.ForeachHLSLProperty(h =>
|
||||
{
|
||||
if (h.declaration == HLSLDeclaration.HybridPerInstance)
|
||||
hasDotsProperties = true;
|
||||
});
|
||||
|
||||
var context = new TargetFieldContext(pass, activeBlocks, connectedBlocks, hasDotsProperties);
|
||||
target.GetFields(ref context);
|
||||
var fields = GenerationUtils.GetActiveFieldsFromConditionals(context.conditionalFields.ToArray());
|
||||
foreach (FieldDescriptor field in fields)
|
||||
activeFields.baseInstance.Add(field);
|
||||
}
|
||||
// Preview shader
|
||||
else
|
||||
{
|
||||
activeFields.baseInstance.Add(Fields.GraphPixel);
|
||||
}
|
||||
return activeFields;
|
||||
}
|
||||
|
||||
void BuildShader()
|
||||
{
|
||||
var activeNodeList = Pool.ListPool<AbstractMaterialNode>.Get();
|
||||
bool ignoreActiveState = (m_Mode == GenerationMode.Preview); // for previews, we ignore node active state
|
||||
if (m_OutputNode == null)
|
||||
{
|
||||
foreach (var block in m_ActiveBlocks)
|
||||
{
|
||||
// IsActive is equal to if any active implementation has set active blocks
|
||||
// This avoids another call to SetActiveBlocks on each TargetImplementation
|
||||
if (!block.isActive)
|
||||
continue;
|
||||
|
||||
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, block, NodeUtils.IncludeSelf.Include, ignoreActiveState: ignoreActiveState);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, m_OutputNode, ignoreActiveState: ignoreActiveState);
|
||||
}
|
||||
|
||||
var shaderProperties = new PropertyCollector();
|
||||
var shaderKeywords = new KeywordCollector();
|
||||
m_GraphData.CollectShaderProperties(shaderProperties, m_Mode);
|
||||
m_GraphData.CollectShaderKeywords(shaderKeywords, m_Mode);
|
||||
|
||||
if (m_GraphData.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit)
|
||||
{
|
||||
m_GraphData.AddValidationError(m_OutputNode.objectId, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error);
|
||||
|
||||
m_ConfiguredTextures = shaderProperties.GetConfiguredTextures();
|
||||
m_Builder.AppendLines(ShaderGraphImporter.k_ErrorShader);
|
||||
}
|
||||
|
||||
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
|
||||
activeNode.CollectShaderProperties(shaderProperties, m_Mode);
|
||||
|
||||
// Collect excess shader properties from the TargetImplementation
|
||||
foreach (var target in m_Targets)
|
||||
{
|
||||
// TODO: Setup is required to ensure all Targets are initialized
|
||||
// TODO: Find a way to only require this once
|
||||
TargetSetupContext context = new TargetSetupContext();
|
||||
target.Setup(ref context);
|
||||
|
||||
target.CollectShaderProperties(shaderProperties, m_Mode);
|
||||
}
|
||||
|
||||
// set the property collector to read only
|
||||
// (to ensure no rogue target or pass starts adding more properties later..)
|
||||
shaderProperties.SetReadOnly();
|
||||
|
||||
m_Builder.AppendLine(@"Shader ""{0}""", m_Name);
|
||||
using (m_Builder.BlockScope())
|
||||
{
|
||||
GenerationUtils.GeneratePropertiesBlock(m_Builder, shaderProperties, shaderKeywords, m_Mode);
|
||||
|
||||
for (int i = 0; i < m_Targets.Length; i++)
|
||||
{
|
||||
TargetSetupContext context = new TargetSetupContext(m_assetCollection);
|
||||
|
||||
// Instead of setup target, we can also just do get context
|
||||
m_Targets[i].Setup(ref context);
|
||||
|
||||
var subShaderProperties = GetSubShaderPropertiesForTarget(m_Targets[i], m_GraphData, m_Mode, m_OutputNode, m_TemporaryBlocks);
|
||||
foreach (var subShader in context.subShaders)
|
||||
{
|
||||
GenerateSubShader(i, subShader, subShaderProperties);
|
||||
}
|
||||
|
||||
var customEditor = context.defaultShaderGUI;
|
||||
if (customEditor != null && m_Targets[i].WorksWithSRP(GraphicsSettings.currentRenderPipeline))
|
||||
{
|
||||
m_Builder.AppendLine("CustomEditor \"" + customEditor + "\"");
|
||||
}
|
||||
|
||||
foreach (var rpCustomEditor in context.customEditorForRenderPipelines)
|
||||
{
|
||||
m_Builder.AppendLine($"CustomEditorForRenderPipeline \"{rpCustomEditor.shaderGUI}\" \"{rpCustomEditor.renderPipelineAssetType}\"");
|
||||
}
|
||||
}
|
||||
|
||||
m_Builder.AppendLine(@"FallBack ""Hidden/Shader Graph/FallbackError""");
|
||||
}
|
||||
|
||||
m_ConfiguredTextures = shaderProperties.GetConfiguredTextures();
|
||||
}
|
||||
|
||||
void GenerateSubShader(int targetIndex, SubShaderDescriptor descriptor, PropertyCollector subShaderProperties)
|
||||
{
|
||||
if (descriptor.passes == null)
|
||||
return;
|
||||
|
||||
// Early out of preview generation if no passes are used in preview
|
||||
if (m_Mode == GenerationMode.Preview && descriptor.generatesPreview == false)
|
||||
return;
|
||||
|
||||
m_Builder.AppendLine("SubShader");
|
||||
using (m_Builder.BlockScope())
|
||||
{
|
||||
GenerationUtils.GenerateSubShaderTags(m_Targets[targetIndex], descriptor, m_Builder);
|
||||
|
||||
// Get block descriptor list here (from ALL active blocks)
|
||||
List<(BlockFieldDescriptor descriptor, bool isDefaultValue)> activeBlockDescriptors = m_ActiveBlocks.Select(x => (x.descriptor, x.GetInputSlots<MaterialSlot>().FirstOrDefault().IsUsingDefaultValue())).ToList();
|
||||
var connectedBlockDescriptors = m_ActiveBlocks.Where(x => x.IsSlotConnected(0)).Select(x => x.descriptor).ToList();
|
||||
|
||||
foreach (PassCollection.Item pass in descriptor.passes)
|
||||
{
|
||||
var activeFields = GatherActiveFieldsFromNode(m_OutputNode, pass.descriptor, activeBlockDescriptors, connectedBlockDescriptors, m_Targets[targetIndex]);
|
||||
|
||||
// TODO: cleanup this preview check, needed for HD decal preview pass
|
||||
if (m_Mode == GenerationMode.Preview)
|
||||
activeFields.baseInstance.Add(Fields.IsPreview);
|
||||
|
||||
// Check masternode fields for valid passes
|
||||
if (pass.TestActive(activeFields))
|
||||
GenerateShaderPass(targetIndex, pass.descriptor, activeFields, activeBlockDescriptors.Select(x => x.descriptor).ToList(), subShaderProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this builds the list of properties for a Target / Graph combination
|
||||
static PropertyCollector GetSubShaderPropertiesForTarget(Target target, GraphData graph, GenerationMode generationMode, AbstractMaterialNode outputNode, List<BlockNode> outTemporaryBlockNodes)
|
||||
{
|
||||
PropertyCollector subshaderProperties = new PropertyCollector();
|
||||
|
||||
// Collect shader properties declared by active nodes
|
||||
using (var activeNodes = PooledHashSet<AbstractMaterialNode>.Get())
|
||||
{
|
||||
if (outputNode == null)
|
||||
{
|
||||
// shader graph builds active nodes starting from the set of active blocks
|
||||
var currentBlocks = graph.GetNodes<BlockNode>();
|
||||
var activeBlockContext = new TargetActiveBlockContext(currentBlocks.Select(x => x.descriptor).ToList(), null);
|
||||
target.GetActiveBlocks(ref activeBlockContext);
|
||||
|
||||
foreach (var blockFieldDesc in activeBlockContext.activeBlocks)
|
||||
{
|
||||
bool foundBlock = false;
|
||||
|
||||
// attempt to get BlockNode(s) from the stack
|
||||
var vertBlockNode = graph.vertexContext.blocks.FirstOrDefault(x => x.value.descriptor == blockFieldDesc).value;
|
||||
if (vertBlockNode != null)
|
||||
{
|
||||
activeNodes.Add(vertBlockNode);
|
||||
foundBlock = true;
|
||||
}
|
||||
|
||||
var fragBlockNode = graph.fragmentContext.blocks.FirstOrDefault(x => x.value.descriptor == blockFieldDesc).value;
|
||||
if (fragBlockNode != null)
|
||||
{
|
||||
activeNodes.Add(fragBlockNode);
|
||||
foundBlock = true;
|
||||
}
|
||||
|
||||
if (!foundBlock)
|
||||
{
|
||||
// block doesn't exist (user deleted it)
|
||||
// create a temporary block -- don't add to graph, but use it to gather properties
|
||||
var block = new BlockNode();
|
||||
block.Init(blockFieldDesc);
|
||||
block.owner = graph;
|
||||
activeNodes.Add(block);
|
||||
|
||||
// We need to make a list of all of the temporary blocks added
|
||||
// (This is used by the PreviewManager to generate a PreviewProperty)
|
||||
outTemporaryBlockNodes.Add(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// preview and/or subgraphs build their active node set based on the single output node
|
||||
activeNodes.Add(outputNode);
|
||||
}
|
||||
|
||||
PreviewManager.PropagateNodes(activeNodes, PreviewManager.PropagationDirection.Upstream, activeNodes);
|
||||
|
||||
// NOTE: this is NOT a deterministic ordering
|
||||
foreach (var node in activeNodes)
|
||||
node.CollectShaderProperties(subshaderProperties, generationMode);
|
||||
|
||||
// So we sort the properties after
|
||||
subshaderProperties.Sort();
|
||||
}
|
||||
|
||||
// Collect graph properties
|
||||
{
|
||||
graph.CollectShaderProperties(subshaderProperties, generationMode);
|
||||
}
|
||||
|
||||
// Collect shader properties declared by the Target
|
||||
{
|
||||
target.CollectShaderProperties(subshaderProperties, generationMode);
|
||||
}
|
||||
|
||||
subshaderProperties.SetReadOnly();
|
||||
|
||||
return subshaderProperties;
|
||||
}
|
||||
|
||||
void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activeFields, List<BlockFieldDescriptor> currentBlockDescriptors, PropertyCollector subShaderProperties)
|
||||
{
|
||||
// Early exit if pass is not used in preview
|
||||
if (m_Mode == GenerationMode.Preview && !pass.useInPreview)
|
||||
return;
|
||||
|
||||
// --------------------------------------------------
|
||||
// Debug
|
||||
|
||||
// Get scripting symbols
|
||||
BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
|
||||
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
|
||||
|
||||
bool isDebug = defines.Contains(kDebugSymbol);
|
||||
|
||||
// --------------------------------------------------
|
||||
// Setup
|
||||
|
||||
// Initiailize Collectors
|
||||
var propertyCollector = new PropertyCollector();
|
||||
var keywordCollector = new KeywordCollector();
|
||||
m_GraphData.CollectShaderKeywords(keywordCollector, m_Mode);
|
||||
|
||||
// Get upstream nodes from ShaderPass port mask
|
||||
List<AbstractMaterialNode> vertexNodes;
|
||||
List<AbstractMaterialNode> pixelNodes;
|
||||
|
||||
// Get Port references from ShaderPass
|
||||
var pixelSlots = new List<MaterialSlot>();
|
||||
var vertexSlots = new List<MaterialSlot>();
|
||||
|
||||
if (m_OutputNode == null)
|
||||
{
|
||||
// Update supported block list for current target implementation
|
||||
var activeBlockContext = new TargetActiveBlockContext(currentBlockDescriptors, pass);
|
||||
m_Targets[targetIndex].GetActiveBlocks(ref activeBlockContext);
|
||||
|
||||
void ProcessStackForPass(ContextData contextData, BlockFieldDescriptor[] passBlockMask,
|
||||
List<AbstractMaterialNode> nodeList, List<MaterialSlot> slotList)
|
||||
{
|
||||
if (passBlockMask == null)
|
||||
return;
|
||||
|
||||
foreach (var blockFieldDescriptor in passBlockMask)
|
||||
{
|
||||
// Mask blocks on active state
|
||||
// TODO: Can we merge these?
|
||||
if (!activeBlockContext.activeBlocks.Contains(blockFieldDescriptor))
|
||||
continue;
|
||||
|
||||
// Attempt to get BlockNode from the stack
|
||||
var block = contextData.blocks.FirstOrDefault(x => x.value.descriptor == blockFieldDescriptor).value;
|
||||
|
||||
// If the BlockNode doesnt exist in the stack we need to create one
|
||||
// TODO: Can we do the code gen without a node instance?
|
||||
if (block == null)
|
||||
{
|
||||
block = new BlockNode();
|
||||
block.Init(blockFieldDescriptor);
|
||||
block.owner = m_GraphData;
|
||||
}
|
||||
// Dont collect properties from temp nodes
|
||||
else
|
||||
{
|
||||
block.CollectShaderProperties(propertyCollector, m_Mode);
|
||||
}
|
||||
|
||||
// Add nodes and slots from supported vertex blocks
|
||||
NodeUtils.DepthFirstCollectNodesFromNode(nodeList, block, NodeUtils.IncludeSelf.Include);
|
||||
slotList.Add(block.FindSlot<MaterialSlot>(0));
|
||||
activeFields.baseInstance.Add(block.descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
// Mask blocks per pass
|
||||
vertexNodes = Pool.ListPool<AbstractMaterialNode>.Get();
|
||||
pixelNodes = Pool.ListPool<AbstractMaterialNode>.Get();
|
||||
|
||||
// Process stack for vertex and fragment
|
||||
ProcessStackForPass(m_GraphData.vertexContext, pass.validVertexBlocks, vertexNodes, vertexSlots);
|
||||
ProcessStackForPass(m_GraphData.fragmentContext, pass.validPixelBlocks, pixelNodes, pixelSlots);
|
||||
|
||||
// Collect excess shader properties from the TargetImplementation
|
||||
m_Targets[targetIndex].CollectShaderProperties(propertyCollector, m_Mode);
|
||||
}
|
||||
else if (m_OutputNode is SubGraphOutputNode)
|
||||
{
|
||||
GenerationUtils.GetUpstreamNodesForShaderPass(m_OutputNode, pass, out vertexNodes, out pixelNodes);
|
||||
var slot = m_OutputNode.GetInputSlots<MaterialSlot>().FirstOrDefault();
|
||||
if (slot != null)
|
||||
pixelSlots = new List<MaterialSlot>() { slot };
|
||||
else
|
||||
pixelSlots = new List<MaterialSlot>();
|
||||
vertexSlots = new List<MaterialSlot>();
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerationUtils.GetUpstreamNodesForShaderPass(m_OutputNode, pass, out vertexNodes, out pixelNodes);
|
||||
pixelSlots = new List<MaterialSlot>()
|
||||
{
|
||||
new Vector4MaterialSlot(0, "Out", "Out", SlotType.Output, Vector4.zero) { owner = m_OutputNode },
|
||||
};
|
||||
vertexSlots = new List<MaterialSlot>();
|
||||
}
|
||||
|
||||
// Track permutation indices for all nodes
|
||||
List<int>[] vertexNodePermutations = new List<int>[vertexNodes.Count];
|
||||
List<int>[] pixelNodePermutations = new List<int>[pixelNodes.Count];
|
||||
|
||||
// Get active fields from upstream Node requirements
|
||||
ShaderGraphRequirementsPerKeyword graphRequirements;
|
||||
GenerationUtils.GetActiveFieldsAndPermutationsForNodes(pass, keywordCollector, vertexNodes, pixelNodes,
|
||||
vertexNodePermutations, pixelNodePermutations, activeFields, out graphRequirements);
|
||||
|
||||
// GET CUSTOM ACTIVE FIELDS HERE!
|
||||
|
||||
// Get active fields from ShaderPass
|
||||
GenerationUtils.AddRequiredFields(pass.requiredFields, activeFields.baseInstance);
|
||||
|
||||
// Function Registry
|
||||
var functionBuilder = new ShaderStringBuilder();
|
||||
var functionRegistry = new FunctionRegistry(functionBuilder);
|
||||
|
||||
// Hash table of named $splice(name) commands
|
||||
// Key: splice token
|
||||
// Value: string to splice
|
||||
Dictionary<string, string> spliceCommands = new Dictionary<string, string>();
|
||||
|
||||
// --------------------------------------------------
|
||||
// Dependencies
|
||||
|
||||
// Propagate active field requirements using dependencies
|
||||
// Must be executed before types are built
|
||||
foreach (var instance in activeFields.all.instances)
|
||||
{
|
||||
GenerationUtils.ApplyFieldDependencies(instance, pass.fieldDependencies);
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Pass Setup
|
||||
|
||||
// Name
|
||||
if (!string.IsNullOrEmpty(pass.displayName))
|
||||
{
|
||||
spliceCommands.Add("PassName", $"Name \"{pass.displayName}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
spliceCommands.Add("PassName", "// Name: <None>");
|
||||
}
|
||||
|
||||
// Tags
|
||||
if (!string.IsNullOrEmpty(pass.lightMode))
|
||||
{
|
||||
spliceCommands.Add("LightMode", $"\"LightMode\" = \"{pass.lightMode}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
spliceCommands.Add("LightMode", "// LightMode: <None>");
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Pass Code
|
||||
|
||||
// Render State
|
||||
using (var renderStateBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
// Render states need to be separated by RenderState.Type
|
||||
// The first passing ConditionalRenderState of each type is inserted
|
||||
foreach (RenderStateType type in Enum.GetValues(typeof(RenderStateType)))
|
||||
{
|
||||
var renderStates = pass.renderStates?.Where(x => x.descriptor.type == type);
|
||||
if (renderStates != null)
|
||||
{
|
||||
foreach (RenderStateCollection.Item renderState in renderStates)
|
||||
{
|
||||
if (renderState.TestActive(activeFields))
|
||||
{
|
||||
renderStateBuilder.AppendLine(renderState.value);
|
||||
|
||||
// Cull is the only render state type that causes a compilation error
|
||||
// when there are multiple Cull directive with different values in a pass.
|
||||
if (type == RenderStateType.Cull)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string command = GenerationUtils.GetSpliceCommand(renderStateBuilder.ToCodeBlock(), "RenderState");
|
||||
spliceCommands.Add("RenderState", command);
|
||||
}
|
||||
|
||||
// Pragmas
|
||||
using (var passPragmaBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
if (pass.pragmas != null)
|
||||
{
|
||||
foreach (PragmaCollection.Item pragma in pass.pragmas)
|
||||
{
|
||||
if (pragma.TestActive(activeFields))
|
||||
passPragmaBuilder.AppendLine(pragma.value);
|
||||
}
|
||||
}
|
||||
|
||||
string command = GenerationUtils.GetSpliceCommand(passPragmaBuilder.ToCodeBlock(), "PassPragmas");
|
||||
spliceCommands.Add("PassPragmas", command);
|
||||
}
|
||||
|
||||
// Includes
|
||||
using (var preGraphIncludeBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
if (pass.includes != null)
|
||||
{
|
||||
foreach (IncludeCollection.Item include in pass.includes.Where(x => x.descriptor.location == IncludeLocation.Pregraph))
|
||||
{
|
||||
if (include.TestActive(activeFields))
|
||||
preGraphIncludeBuilder.AppendLine(include.value);
|
||||
}
|
||||
}
|
||||
|
||||
string command = GenerationUtils.GetSpliceCommand(preGraphIncludeBuilder.ToCodeBlock(), "PreGraphIncludes");
|
||||
spliceCommands.Add("PreGraphIncludes", command);
|
||||
}
|
||||
using (var postGraphIncludeBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
if (pass.includes != null)
|
||||
{
|
||||
foreach (IncludeCollection.Item include in pass.includes.Where(x => x.descriptor.location == IncludeLocation.Postgraph))
|
||||
{
|
||||
if (include.TestActive(activeFields))
|
||||
postGraphIncludeBuilder.AppendLine(include.value);
|
||||
}
|
||||
}
|
||||
|
||||
string command = GenerationUtils.GetSpliceCommand(postGraphIncludeBuilder.ToCodeBlock(), "PostGraphIncludes");
|
||||
spliceCommands.Add("PostGraphIncludes", command);
|
||||
}
|
||||
|
||||
// Keywords
|
||||
using (var passKeywordBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
if (pass.keywords != null)
|
||||
{
|
||||
foreach (KeywordCollection.Item keyword in pass.keywords)
|
||||
{
|
||||
if (keyword.TestActive(activeFields))
|
||||
passKeywordBuilder.AppendLine(keyword.value);
|
||||
}
|
||||
}
|
||||
|
||||
string command = GenerationUtils.GetSpliceCommand(passKeywordBuilder.ToCodeBlock(), "PassKeywords");
|
||||
spliceCommands.Add("PassKeywords", command);
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// Generated structs and Packing code
|
||||
var interpolatorBuilder = new ShaderStringBuilder();
|
||||
var passStructs = new List<StructDescriptor>();
|
||||
|
||||
if (pass.structs != null)
|
||||
{
|
||||
passStructs.AddRange(pass.structs.Select(x => x.descriptor));
|
||||
|
||||
foreach (StructCollection.Item shaderStruct in pass.structs)
|
||||
{
|
||||
if (shaderStruct.descriptor.packFields == false)
|
||||
continue; //skip structs that do not need interpolator packs
|
||||
|
||||
List<int> packedCounts = new List<int>();
|
||||
var packStruct = new StructDescriptor();
|
||||
|
||||
//generate packed functions
|
||||
if (activeFields.permutationCount > 0)
|
||||
{
|
||||
var generatedPackedTypes = new Dictionary<string, (ShaderStringBuilder, List<int>)>();
|
||||
foreach (var instance in activeFields.allPermutations.instances)
|
||||
{
|
||||
var instanceGenerator = new ShaderStringBuilder();
|
||||
GenerationUtils.GenerateInterpolatorFunctions(shaderStruct.descriptor, instance, out instanceGenerator);
|
||||
var key = instanceGenerator.ToCodeBlock();
|
||||
if (generatedPackedTypes.TryGetValue(key, out var value))
|
||||
value.Item2.Add(instance.permutationIndex);
|
||||
else
|
||||
generatedPackedTypes.Add(key, (instanceGenerator, new List<int> { instance.permutationIndex }));
|
||||
}
|
||||
|
||||
var isFirst = true;
|
||||
foreach (var generated in generatedPackedTypes)
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
interpolatorBuilder.AppendLine(KeywordUtil.GetKeywordPermutationSetConditional(generated.Value.Item2));
|
||||
}
|
||||
else
|
||||
interpolatorBuilder.AppendLine(KeywordUtil.GetKeywordPermutationSetConditional(generated.Value.Item2).Replace("#if", "#elif"));
|
||||
|
||||
//interpolatorBuilder.Concat(generated.Value.Item1);
|
||||
interpolatorBuilder.AppendLines(generated.Value.Item1.ToString());
|
||||
}
|
||||
if (generatedPackedTypes.Count > 0)
|
||||
interpolatorBuilder.AppendLine("#endif");
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerationUtils.GenerateInterpolatorFunctions(shaderStruct.descriptor, activeFields.baseInstance, out interpolatorBuilder);
|
||||
}
|
||||
//using interp index from functions, generate packed struct descriptor
|
||||
GenerationUtils.GeneratePackedStruct(shaderStruct.descriptor, activeFields, out packStruct);
|
||||
passStructs.Add(packStruct);
|
||||
}
|
||||
}
|
||||
if (interpolatorBuilder.length != 0) //hard code interpolators to float, TODO: proper handle precision
|
||||
interpolatorBuilder.ReplaceInCurrentMapping(PrecisionUtil.Token, ConcretePrecision.Single.ToShaderString());
|
||||
else
|
||||
interpolatorBuilder.AppendLine("//Interpolator Packs: <None>");
|
||||
spliceCommands.Add("InterpolatorPack", interpolatorBuilder.ToCodeBlock());
|
||||
|
||||
// Generated String Builders for all struct types
|
||||
var passStructBuilder = new ShaderStringBuilder();
|
||||
if (passStructs != null)
|
||||
{
|
||||
var structBuilder = new ShaderStringBuilder();
|
||||
foreach (StructDescriptor shaderStruct in passStructs)
|
||||
{
|
||||
GenerationUtils.GenerateShaderStruct(shaderStruct, activeFields, out structBuilder);
|
||||
structBuilder.ReplaceInCurrentMapping(PrecisionUtil.Token, ConcretePrecision.Single.ToShaderString()); //hard code structs to float, TODO: proper handle precision
|
||||
passStructBuilder.Concat(structBuilder);
|
||||
}
|
||||
}
|
||||
if (passStructBuilder.length == 0)
|
||||
passStructBuilder.AppendLine("//Pass Structs: <None>");
|
||||
spliceCommands.Add("PassStructs", passStructBuilder.ToCodeBlock());
|
||||
|
||||
// --------------------------------------------------
|
||||
// Graph Vertex
|
||||
|
||||
var vertexBuilder = new ShaderStringBuilder();
|
||||
|
||||
// If vertex modification enabled
|
||||
if (activeFields.baseInstance.Contains(Fields.GraphVertex) && vertexSlots != null)
|
||||
{
|
||||
// Setup
|
||||
string vertexGraphInputName = "VertexDescriptionInputs";
|
||||
string vertexGraphOutputName = "VertexDescription";
|
||||
string vertexGraphFunctionName = "VertexDescriptionFunction";
|
||||
var vertexGraphFunctionBuilder = new ShaderStringBuilder();
|
||||
var vertexGraphOutputBuilder = new ShaderStringBuilder();
|
||||
|
||||
// Build vertex graph outputs
|
||||
// Add struct fields to active fields
|
||||
GenerationUtils.GenerateVertexDescriptionStruct(vertexGraphOutputBuilder, vertexSlots, vertexGraphOutputName, activeFields.baseInstance);
|
||||
|
||||
// Build vertex graph functions from ShaderPass vertex port mask
|
||||
GenerationUtils.GenerateVertexDescriptionFunction(
|
||||
m_GraphData,
|
||||
vertexGraphFunctionBuilder,
|
||||
functionRegistry,
|
||||
propertyCollector,
|
||||
keywordCollector,
|
||||
m_Mode,
|
||||
m_OutputNode,
|
||||
vertexNodes,
|
||||
vertexNodePermutations,
|
||||
vertexSlots,
|
||||
vertexGraphInputName,
|
||||
vertexGraphFunctionName,
|
||||
vertexGraphOutputName);
|
||||
|
||||
// Generate final shader strings
|
||||
vertexBuilder.AppendLines(vertexGraphOutputBuilder.ToString());
|
||||
vertexBuilder.AppendNewLine();
|
||||
vertexBuilder.AppendLines(vertexGraphFunctionBuilder.ToString());
|
||||
}
|
||||
|
||||
// Add to splice commands
|
||||
if (vertexBuilder.length == 0)
|
||||
vertexBuilder.AppendLine("// GraphVertex: <None>");
|
||||
spliceCommands.Add("GraphVertex", vertexBuilder.ToCodeBlock());
|
||||
|
||||
// --------------------------------------------------
|
||||
// Graph Pixel
|
||||
|
||||
// Setup
|
||||
string pixelGraphInputName = "SurfaceDescriptionInputs";
|
||||
string pixelGraphOutputName = "SurfaceDescription";
|
||||
string pixelGraphFunctionName = "SurfaceDescriptionFunction";
|
||||
var pixelGraphOutputBuilder = new ShaderStringBuilder();
|
||||
var pixelGraphFunctionBuilder = new ShaderStringBuilder();
|
||||
|
||||
// Build pixel graph outputs
|
||||
// Add struct fields to active fields
|
||||
GenerationUtils.GenerateSurfaceDescriptionStruct(pixelGraphOutputBuilder, pixelSlots, pixelGraphOutputName, activeFields.baseInstance, m_OutputNode is SubGraphOutputNode, pass.virtualTextureFeedback);
|
||||
|
||||
// Build pixel graph functions from ShaderPass pixel port mask
|
||||
GenerationUtils.GenerateSurfaceDescriptionFunction(
|
||||
pixelNodes,
|
||||
pixelNodePermutations,
|
||||
m_OutputNode,
|
||||
m_GraphData,
|
||||
pixelGraphFunctionBuilder,
|
||||
functionRegistry,
|
||||
propertyCollector,
|
||||
keywordCollector,
|
||||
m_Mode,
|
||||
pixelGraphFunctionName,
|
||||
pixelGraphOutputName,
|
||||
null,
|
||||
pixelSlots,
|
||||
pixelGraphInputName,
|
||||
pass.virtualTextureFeedback);
|
||||
|
||||
using (var pixelBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
// Generate final shader strings
|
||||
pixelBuilder.AppendLines(pixelGraphOutputBuilder.ToString());
|
||||
pixelBuilder.AppendNewLine();
|
||||
pixelBuilder.AppendLines(pixelGraphFunctionBuilder.ToString());
|
||||
|
||||
// Add to splice commands
|
||||
if (pixelBuilder.length == 0)
|
||||
pixelBuilder.AppendLine("// GraphPixel: <None>");
|
||||
spliceCommands.Add("GraphPixel", pixelBuilder.ToCodeBlock());
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Graph Functions
|
||||
|
||||
if (functionBuilder.length == 0)
|
||||
functionBuilder.AppendLine("// GraphFunctions: <None>");
|
||||
spliceCommands.Add("GraphFunctions", functionBuilder.ToCodeBlock());
|
||||
|
||||
// --------------------------------------------------
|
||||
// Graph Keywords
|
||||
|
||||
using (var keywordBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
keywordCollector.GetKeywordsDeclaration(keywordBuilder, m_Mode);
|
||||
if (keywordBuilder.length == 0)
|
||||
keywordBuilder.AppendLine("// GraphKeywords: <None>");
|
||||
spliceCommands.Add("GraphKeywords", keywordBuilder.ToCodeBlock());
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Graph Properties
|
||||
|
||||
using (var propertyBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
subShaderProperties.GetPropertiesDeclaration(propertyBuilder, m_Mode, m_GraphData.concretePrecision);
|
||||
if (propertyBuilder.length == 0)
|
||||
propertyBuilder.AppendLine("// GraphProperties: <None>");
|
||||
spliceCommands.Add("GraphProperties", propertyBuilder.ToCodeBlock());
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Dots Instanced Graph Properties
|
||||
|
||||
bool hasDotsProperties = subShaderProperties.HasDotsProperties();
|
||||
|
||||
using (var dotsInstancedPropertyBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
if (hasDotsProperties)
|
||||
dotsInstancedPropertyBuilder.AppendLines(subShaderProperties.GetDotsInstancingPropertiesDeclaration(m_Mode));
|
||||
else
|
||||
dotsInstancedPropertyBuilder.AppendLine("// HybridV1InjectedBuiltinProperties: <None>");
|
||||
spliceCommands.Add("HybridV1InjectedBuiltinProperties", dotsInstancedPropertyBuilder.ToCodeBlock());
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Dots Instancing Options
|
||||
|
||||
using (var dotsInstancingOptionsBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
// Hybrid Renderer V1 requires some magic defines to work, which we enable
|
||||
// if the shader graph has a nonzero amount of DOTS instanced properties.
|
||||
// This can be removed once Hybrid V1 is removed.
|
||||
#if !ENABLE_HYBRID_RENDERER_V2
|
||||
if (hasDotsProperties)
|
||||
{
|
||||
dotsInstancingOptionsBuilder.AppendLine("#if SHADER_TARGET >= 35 && (defined(SHADER_API_D3D11) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) || defined(SHADER_API_XBOXONE) || defined(SHADER_API_GAMECORE) || defined(SHADER_API_PSSL) || defined(SHADER_API_VULKAN) || defined(SHADER_API_METAL))");
|
||||
dotsInstancingOptionsBuilder.AppendLine(" #define UNITY_SUPPORT_INSTANCING");
|
||||
dotsInstancingOptionsBuilder.AppendLine("#endif");
|
||||
dotsInstancingOptionsBuilder.AppendLine("#if defined(UNITY_SUPPORT_INSTANCING) && defined(INSTANCING_ON)");
|
||||
dotsInstancingOptionsBuilder.AppendLine(" #define UNITY_HYBRID_V1_INSTANCING_ENABLED");
|
||||
dotsInstancingOptionsBuilder.AppendLine("#endif");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dotsInstancingOptionsBuilder.length == 0)
|
||||
dotsInstancingOptionsBuilder.AppendLine("// DotsInstancingOptions: <None>");
|
||||
spliceCommands.Add("DotsInstancingOptions", dotsInstancingOptionsBuilder.ToCodeBlock());
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Graph Defines
|
||||
|
||||
using (var graphDefines = new ShaderStringBuilder())
|
||||
{
|
||||
graphDefines.AppendLine("#define SHADERPASS {0}", pass.referenceName);
|
||||
|
||||
if (pass.defines != null)
|
||||
{
|
||||
foreach (DefineCollection.Item define in pass.defines)
|
||||
{
|
||||
if (define.TestActive(activeFields))
|
||||
graphDefines.AppendLine(define.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (graphRequirements.permutationCount > 0)
|
||||
{
|
||||
List<int> activePermutationIndices;
|
||||
|
||||
// Depth Texture
|
||||
activePermutationIndices = graphRequirements.allPermutations.instances
|
||||
.Where(p => p.requirements.requiresDepthTexture)
|
||||
.Select(p => p.permutationIndex)
|
||||
.ToList();
|
||||
if (activePermutationIndices.Count > 0)
|
||||
{
|
||||
graphDefines.AppendLine(KeywordUtil.GetKeywordPermutationSetConditional(activePermutationIndices));
|
||||
graphDefines.AppendLine("#define REQUIRE_DEPTH_TEXTURE");
|
||||
graphDefines.AppendLine("#endif");
|
||||
}
|
||||
|
||||
// Opaque Texture
|
||||
activePermutationIndices = graphRequirements.allPermutations.instances
|
||||
.Where(p => p.requirements.requiresCameraOpaqueTexture)
|
||||
.Select(p => p.permutationIndex)
|
||||
.ToList();
|
||||
if (activePermutationIndices.Count > 0)
|
||||
{
|
||||
graphDefines.AppendLine(KeywordUtil.GetKeywordPermutationSetConditional(activePermutationIndices));
|
||||
graphDefines.AppendLine("#define REQUIRE_OPAQUE_TEXTURE");
|
||||
graphDefines.AppendLine("#endif");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth Texture
|
||||
if (graphRequirements.baseInstance.requirements.requiresDepthTexture)
|
||||
graphDefines.AppendLine("#define REQUIRE_DEPTH_TEXTURE");
|
||||
|
||||
// Opaque Texture
|
||||
if (graphRequirements.baseInstance.requirements.requiresCameraOpaqueTexture)
|
||||
graphDefines.AppendLine("#define REQUIRE_OPAQUE_TEXTURE");
|
||||
}
|
||||
|
||||
// Add to splice commands
|
||||
spliceCommands.Add("GraphDefines", graphDefines.ToCodeBlock());
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Debug
|
||||
|
||||
// Debug output all active fields
|
||||
|
||||
using (var debugBuilder = new ShaderStringBuilder())
|
||||
{
|
||||
if (isDebug)
|
||||
{
|
||||
// Active fields
|
||||
debugBuilder.AppendLine("// ACTIVE FIELDS:");
|
||||
foreach (FieldDescriptor field in activeFields.baseInstance.fields)
|
||||
{
|
||||
debugBuilder.AppendLine($"//{field.tag}.{field.name}");
|
||||
}
|
||||
}
|
||||
if (debugBuilder.length == 0)
|
||||
debugBuilder.AppendLine("// <None>");
|
||||
|
||||
// Add to splice commands
|
||||
spliceCommands.Add("Debug", debugBuilder.ToCodeBlock());
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Finalize
|
||||
|
||||
// Pass Template
|
||||
string passTemplatePath = pass.passTemplatePath;
|
||||
|
||||
// Shared Templates
|
||||
string[] sharedTemplateDirectories = pass.sharedTemplateDirectories;
|
||||
|
||||
if (!File.Exists(passTemplatePath))
|
||||
return;
|
||||
|
||||
// Process Template
|
||||
var templatePreprocessor = new ShaderSpliceUtil.TemplatePreprocessor(activeFields, spliceCommands,
|
||||
isDebug, sharedTemplateDirectories, m_assetCollection);
|
||||
templatePreprocessor.ProcessTemplateFile(passTemplatePath);
|
||||
m_Builder.Concat(templatePreprocessor.GetShaderCode());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
// Required for Unity to handle nested array serialization
|
||||
[Serializable]
|
||||
struct IntArray
|
||||
{
|
||||
public int[] array;
|
||||
|
||||
public int this[int i]
|
||||
{
|
||||
get => array[i];
|
||||
set => array[i] = value;
|
||||
}
|
||||
|
||||
public static implicit operator IntArray(int[] array)
|
||||
{
|
||||
return new IntArray { array = array };
|
||||
}
|
||||
|
||||
public static implicit operator int[](IntArray array)
|
||||
{
|
||||
return array.array;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class GraphCompilationResult
|
||||
{
|
||||
public string[] codeSnippets;
|
||||
|
||||
public int[] sharedCodeIndices;
|
||||
|
||||
public IntArray[] outputCodeIndices;
|
||||
|
||||
public string GenerateCode(int[] outputIndices)
|
||||
{
|
||||
var codeIndexSet = new HashSet<int>();
|
||||
|
||||
foreach (var codeIndex in sharedCodeIndices)
|
||||
{
|
||||
codeIndexSet.Add(codeIndex);
|
||||
}
|
||||
|
||||
foreach (var outputIndex in outputIndices)
|
||||
{
|
||||
foreach (var codeIndex in outputCodeIndices[outputIndex].array)
|
||||
{
|
||||
codeIndexSet.Add(codeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
var codeIndices = new int[codeIndexSet.Count];
|
||||
codeIndexSet.CopyTo(codeIndices);
|
||||
Array.Sort(codeIndices);
|
||||
|
||||
var charCount = 0;
|
||||
foreach (var codeIndex in codeIndices)
|
||||
{
|
||||
charCount += codeSnippets[codeIndex].Length;
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.EnsureCapacity(charCount);
|
||||
|
||||
foreach (var codeIndex in codeIndices)
|
||||
{
|
||||
sb.Append(codeSnippets[codeIndex]);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
struct MatrixNames
|
||||
{
|
||||
public const string Model = "UNITY_MATRIX_M";
|
||||
public const string ModelInverse = "UNITY_MATRIX_I_M";
|
||||
public const string View = "UNITY_MATRIX_V";
|
||||
public const string ViewInverse = "UNITY_MATRIX_I_V";
|
||||
public const string Projection = "UNITY_MATRIX_P";
|
||||
public const string ProjectionInverse = "UNITY_MATRIX_I_P";
|
||||
public const string ViewProjection = "UNITY_MATRIX_VP";
|
||||
public const string ViewProjectionInverse = "UNITY_MATRIX_I_VP";
|
||||
}
|
||||
}
|
@@ -0,0 +1,399 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using TextureDimension = UnityEngine.Rendering.TextureDimension;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class PropertyCollector
|
||||
{
|
||||
public struct TextureInfo
|
||||
{
|
||||
public string name;
|
||||
public int textureId;
|
||||
public TextureDimension dimension;
|
||||
public bool modifiable;
|
||||
}
|
||||
|
||||
bool m_ReadOnly;
|
||||
List<HLSLProperty> m_HLSLProperties = null;
|
||||
|
||||
// reference name ==> property index in list
|
||||
Dictionary<string, int> m_ReferenceNames = new Dictionary<string, int>();
|
||||
|
||||
// list of properties (kept in a list to maintain deterministic declaration order)
|
||||
List<AbstractShaderProperty> m_Properties = new List<AbstractShaderProperty>();
|
||||
|
||||
public int propertyCount => m_Properties.Count;
|
||||
public IEnumerable<AbstractShaderProperty> properties => m_Properties;
|
||||
public AbstractShaderProperty GetProperty(int index) { return m_Properties[index]; }
|
||||
|
||||
public void Sort()
|
||||
{
|
||||
if (m_ReadOnly)
|
||||
{
|
||||
Debug.LogError("Cannot sort the properties when the PropertyCollector is already marked ReadOnly");
|
||||
return;
|
||||
}
|
||||
|
||||
m_Properties.Sort((a, b) => String.CompareOrdinal(a.referenceName, b.referenceName));
|
||||
|
||||
// reference name indices are now messed up, rebuild them
|
||||
m_ReferenceNames.Clear();
|
||||
for (int i = 0; i < m_Properties.Count; i++)
|
||||
m_ReferenceNames.Add(m_Properties[i].referenceName, i);
|
||||
}
|
||||
|
||||
public void SetReadOnly()
|
||||
{
|
||||
m_ReadOnly = true;
|
||||
}
|
||||
|
||||
private static bool EquivalentHLSLProperties(AbstractShaderProperty a, AbstractShaderProperty b)
|
||||
{
|
||||
bool equivalent = true;
|
||||
var bHLSLProps = new List<HLSLProperty>();
|
||||
b.ForeachHLSLProperty(bh => bHLSLProps.Add(bh));
|
||||
a.ForeachHLSLProperty(ah =>
|
||||
{
|
||||
var i = bHLSLProps.FindIndex(bh => bh.name == ah.name);
|
||||
if (i < 0)
|
||||
equivalent = false;
|
||||
else
|
||||
{
|
||||
var bh = bHLSLProps[i];
|
||||
if ((ah.name != bh.name) ||
|
||||
(ah.type != bh.type) ||
|
||||
(ah.precision != bh.precision) ||
|
||||
(ah.declaration != bh.declaration) ||
|
||||
((ah.customDeclaration == null) != (bh.customDeclaration == null)))
|
||||
{
|
||||
equivalent = false;
|
||||
}
|
||||
else if (ah.customDeclaration != null)
|
||||
{
|
||||
var ssba = new ShaderStringBuilder();
|
||||
var ssbb = new ShaderStringBuilder();
|
||||
ah.customDeclaration(ssba);
|
||||
bh.customDeclaration(ssbb);
|
||||
if (ssba.ToCodeBlock() != ssbb.ToCodeBlock())
|
||||
equivalent = false;
|
||||
}
|
||||
bHLSLProps.RemoveAt(i);
|
||||
}
|
||||
});
|
||||
return equivalent && (bHLSLProps.Count == 0);
|
||||
}
|
||||
|
||||
public void AddShaderProperty(AbstractShaderProperty prop)
|
||||
{
|
||||
if (m_ReadOnly)
|
||||
{
|
||||
Debug.LogError("ERROR attempting to add property to readonly collection");
|
||||
return;
|
||||
}
|
||||
|
||||
int propIndex = -1;
|
||||
if (m_ReferenceNames.TryGetValue(prop.referenceName, out propIndex))
|
||||
{
|
||||
// existing referenceName
|
||||
var existingProp = m_Properties[propIndex];
|
||||
if (existingProp != prop)
|
||||
{
|
||||
// duplicate reference name, but different property instances
|
||||
if (existingProp.GetType() != prop.GetType())
|
||||
{
|
||||
Debug.LogError("Two properties with the same reference name (" + prop.referenceName + ") using different types");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!EquivalentHLSLProperties(existingProp, prop))
|
||||
Debug.LogError("Two properties with the same reference name (" + prop.referenceName + ") produce different HLSL properties");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// new referenceName, new property
|
||||
propIndex = m_Properties.Count;
|
||||
m_Properties.Add(prop);
|
||||
m_ReferenceNames.Add(prop.referenceName, propIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<HLSLProperty> BuildHLSLPropertyList()
|
||||
{
|
||||
SetReadOnly();
|
||||
if (m_HLSLProperties == null)
|
||||
{
|
||||
m_HLSLProperties = new List<HLSLProperty>();
|
||||
foreach (var p in m_Properties)
|
||||
p.ForeachHLSLProperty(h => m_HLSLProperties.Add(h));
|
||||
}
|
||||
return m_HLSLProperties;
|
||||
}
|
||||
|
||||
public void GetPropertiesDeclaration(ShaderStringBuilder builder, GenerationMode mode, ConcretePrecision inheritedPrecision)
|
||||
{
|
||||
foreach (var prop in properties)
|
||||
{
|
||||
prop.ValidateConcretePrecision(inheritedPrecision);
|
||||
}
|
||||
|
||||
// build a list of all HLSL properties
|
||||
var hlslProps = BuildHLSLPropertyList();
|
||||
|
||||
if (mode == GenerationMode.Preview)
|
||||
{
|
||||
builder.AppendLine("CBUFFER_START(UnityPerMaterial)");
|
||||
|
||||
// all non-gpu instanced properties (even non-batchable ones!)
|
||||
// this is because for preview we convert all properties to UnityPerMaterial properties
|
||||
// as we will be submitting the default preview values via the Material.. :)
|
||||
foreach (var h in hlslProps)
|
||||
{
|
||||
if ((h.declaration == HLSLDeclaration.UnityPerMaterial) ||
|
||||
(h.declaration == HLSLDeclaration.Global))
|
||||
{
|
||||
h.AppendTo(builder);
|
||||
}
|
||||
}
|
||||
|
||||
// gpu-instanced properties
|
||||
var gpuInstancedProps = hlslProps.Where(h => h.declaration == HLSLDeclaration.HybridPerInstance);
|
||||
if (gpuInstancedProps.Any())
|
||||
{
|
||||
builder.AppendLine("#ifdef UNITY_HYBRID_V1_INSTANCING_ENABLED");
|
||||
foreach (var h in gpuInstancedProps)
|
||||
{
|
||||
h.AppendTo(builder, name => name + "_dummy");
|
||||
}
|
||||
builder.AppendLine("#else // V2");
|
||||
foreach (var h in gpuInstancedProps)
|
||||
{
|
||||
h.AppendTo(builder);
|
||||
}
|
||||
builder.AppendLine("#endif");
|
||||
}
|
||||
builder.AppendLine("CBUFFER_END");
|
||||
return;
|
||||
}
|
||||
|
||||
// Hybrid V1 generates a special version of UnityPerMaterial, which has dummy constants for
|
||||
// instanced properties, and regular constants for other properties.
|
||||
// Hybrid V2 generates a perfectly normal UnityPerMaterial, but needs to append
|
||||
// a UNITY_DOTS_INSTANCING_START/END block after it that contains the instanced properties.
|
||||
|
||||
#if !ENABLE_HYBRID_RENDERER_V2
|
||||
builder.AppendLine("CBUFFER_START(UnityPerMaterial)");
|
||||
|
||||
// non-GPU-instanced batchable properties go first in the UnityPerMaterial cbuffer
|
||||
foreach (var h in hlslProps)
|
||||
if (h.declaration == HLSLDeclaration.UnityPerMaterial)
|
||||
h.AppendTo(builder);
|
||||
|
||||
// followed by GPU-instanced batchable properties
|
||||
var gpuInstancedProperties = hlslProps.Where(h => h.declaration == HLSLDeclaration.HybridPerInstance);
|
||||
if (gpuInstancedProperties.Any())
|
||||
{
|
||||
builder.AppendLine("#ifdef UNITY_HYBRID_V1_INSTANCING_ENABLED");
|
||||
foreach (var hlslProp in gpuInstancedProperties)
|
||||
hlslProp.AppendTo(builder, name => name + "_dummy");
|
||||
builder.AppendLine("#else");
|
||||
foreach (var hlslProp in gpuInstancedProperties)
|
||||
hlslProp.AppendTo(builder);
|
||||
builder.AppendLine("#endif");
|
||||
}
|
||||
builder.AppendLine("CBUFFER_END");
|
||||
#else
|
||||
// TODO: need to test this path with HYBRID_RENDERER_V2 ...
|
||||
|
||||
builder.AppendLine("CBUFFER_START(UnityPerMaterial)");
|
||||
|
||||
int instancedCount = 0;
|
||||
foreach (var h in hlslProps)
|
||||
{
|
||||
if (h.declaration == HLSLDeclaration.UnityPerMaterial)
|
||||
h.AppendTo(builder);
|
||||
else if (h.declaration == HLSLDeclaration.HybridPerInstance)
|
||||
instancedCount++;
|
||||
}
|
||||
|
||||
if (instancedCount > 0)
|
||||
{
|
||||
builder.AppendLine("// Hybrid instanced properties");
|
||||
foreach (var h in hlslProps.Where(h => h.declaration == HLSLDeclaration.HybridPerInstance))
|
||||
h.AppendTo(builder);
|
||||
}
|
||||
builder.AppendLine("CBUFFER_END");
|
||||
|
||||
if (instancedCount > 0)
|
||||
{
|
||||
builder.AppendLine("#if defined(UNITY_DOTS_INSTANCING_ENABLED)");
|
||||
|
||||
builder.AppendLine("// DOTS instancing definitions");
|
||||
builder.AppendLine("UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)");
|
||||
foreach (var h in hlslProps.Where(h => h.declaration == HLSLDeclaration.HybridPerInstance))
|
||||
{
|
||||
var n = h.name;
|
||||
string type = h.GetValueTypeString();
|
||||
builder.AppendLine($" UNITY_DOTS_INSTANCED_PROP({type}, {n})");
|
||||
}
|
||||
builder.AppendLine("UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)");
|
||||
|
||||
builder.AppendLine("// DOTS instancing usage macros");
|
||||
foreach (var h in hlslProps.Where(h => h.declaration == HLSLDeclaration.HybridPerInstance))
|
||||
{
|
||||
var n = h.name;
|
||||
string type = h.GetValueTypeString();
|
||||
builder.AppendLine($"#define {n} UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO({type}, Metadata_{n})");
|
||||
}
|
||||
builder.AppendLine("#endif");
|
||||
}
|
||||
#endif
|
||||
|
||||
builder.AppendNewLine();
|
||||
builder.AppendLine("// Object and Global properties");
|
||||
foreach (var h in hlslProps)
|
||||
if (h.declaration == HLSLDeclaration.Global)
|
||||
h.AppendTo(builder);
|
||||
}
|
||||
|
||||
public bool HasDotsProperties()
|
||||
{
|
||||
var hlslProps = BuildHLSLPropertyList();
|
||||
bool hasDotsProperties = false;
|
||||
foreach (var h in hlslProps)
|
||||
{
|
||||
if (h.declaration == HLSLDeclaration.HybridPerInstance)
|
||||
hasDotsProperties = true;
|
||||
}
|
||||
return hasDotsProperties;
|
||||
}
|
||||
|
||||
public string GetDotsInstancingPropertiesDeclaration(GenerationMode mode)
|
||||
{
|
||||
// Hybrid V1 needs to declare a special macro to that is injected into
|
||||
// builtin instancing variables.
|
||||
// Hybrid V2 does not need it.
|
||||
#if !ENABLE_HYBRID_RENDERER_V2
|
||||
var builder = new ShaderStringBuilder();
|
||||
var batchAll = (mode == GenerationMode.Preview);
|
||||
|
||||
// build a list of all HLSL properties
|
||||
var hybridHLSLProps = BuildHLSLPropertyList().Where(h => h.declaration == HLSLDeclaration.HybridPerInstance);
|
||||
|
||||
if (hybridHLSLProps.Any())
|
||||
{
|
||||
builder.AppendLine("#if defined(UNITY_HYBRID_V1_INSTANCING_ENABLED)");
|
||||
builder.AppendLine("#define HYBRID_V1_CUSTOM_ADDITIONAL_MATERIAL_VARS \\");
|
||||
|
||||
int count = 0;
|
||||
foreach (var prop in hybridHLSLProps)
|
||||
{
|
||||
// Combine multiple UNITY_DEFINE_INSTANCED_PROP lines with \ so the generated
|
||||
// macro expands into multiple definitions if there are more than one.
|
||||
if (count > 0)
|
||||
{
|
||||
builder.Append("\\");
|
||||
builder.AppendNewLine();
|
||||
}
|
||||
builder.Append("UNITY_DEFINE_INSTANCED_PROP(");
|
||||
builder.Append(prop.GetValueTypeString());
|
||||
builder.Append(", ");
|
||||
builder.Append(prop.name);
|
||||
builder.Append("_Array)");
|
||||
count++;
|
||||
}
|
||||
builder.AppendNewLine();
|
||||
|
||||
foreach (var prop in hybridHLSLProps)
|
||||
{
|
||||
string varName = $"{prop.name}_Array";
|
||||
builder.AppendLine("#define {0} UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, {1})", prop.name, varName);
|
||||
}
|
||||
}
|
||||
builder.AppendLine("#endif");
|
||||
return builder.ToString();
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
public List<TextureInfo> GetConfiguredTextures()
|
||||
{
|
||||
var result = new List<TextureInfo>();
|
||||
|
||||
// TODO: this should be interface based instead of looking for hard coded types
|
||||
|
||||
foreach (var prop in properties.OfType<Texture2DShaderProperty>())
|
||||
{
|
||||
if (prop.referenceName != null)
|
||||
{
|
||||
var textureInfo = new TextureInfo
|
||||
{
|
||||
name = prop.referenceName,
|
||||
textureId = prop.value.texture != null ? prop.value.texture.GetInstanceID() : 0,
|
||||
dimension = TextureDimension.Tex2D,
|
||||
modifiable = prop.modifiable
|
||||
};
|
||||
result.Add(textureInfo);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var prop in properties.OfType<Texture2DArrayShaderProperty>())
|
||||
{
|
||||
if (prop.referenceName != null)
|
||||
{
|
||||
var textureInfo = new TextureInfo
|
||||
{
|
||||
name = prop.referenceName,
|
||||
textureId = prop.value.textureArray != null ? prop.value.textureArray.GetInstanceID() : 0,
|
||||
dimension = TextureDimension.Tex2DArray,
|
||||
modifiable = prop.modifiable
|
||||
};
|
||||
result.Add(textureInfo);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var prop in properties.OfType<Texture3DShaderProperty>())
|
||||
{
|
||||
if (prop.referenceName != null)
|
||||
{
|
||||
var textureInfo = new TextureInfo
|
||||
{
|
||||
name = prop.referenceName,
|
||||
textureId = prop.value.texture != null ? prop.value.texture.GetInstanceID() : 0,
|
||||
dimension = TextureDimension.Tex3D,
|
||||
modifiable = prop.modifiable
|
||||
};
|
||||
result.Add(textureInfo);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var prop in properties.OfType<CubemapShaderProperty>())
|
||||
{
|
||||
if (prop.referenceName != null)
|
||||
{
|
||||
var textureInfo = new TextureInfo
|
||||
{
|
||||
name = prop.referenceName,
|
||||
textureId = prop.value.cubemap != null ? prop.value.cubemap.GetInstanceID() : 0,
|
||||
dimension = TextureDimension.Cube,
|
||||
modifiable = prop.modifiable
|
||||
};
|
||||
result.Add(textureInfo);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var prop in properties.OfType<VirtualTextureShaderProperty>().Where(p => p.referenceName != null))
|
||||
{
|
||||
prop.AddTextureInfo(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class ShaderGeneratorNames
|
||||
{
|
||||
private static string[] UV = {"uv0", "uv1", "uv2", "uv3"};
|
||||
public static int UVCount = 4;
|
||||
|
||||
public const string ScreenPosition = "ScreenPosition";
|
||||
public const string VertexColor = "VertexColor";
|
||||
public const string FaceSign = "FaceSign";
|
||||
public const string TimeParameters = "TimeParameters";
|
||||
public const string BoneWeights = "BoneWeights";
|
||||
public const string BoneIndices = "BoneIndices";
|
||||
public const string VertexID = "VertexID";
|
||||
|
||||
public static string GetUVName(this UVChannel channel)
|
||||
{
|
||||
return UV[(int)channel];
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,474 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class ShaderSpliceUtil
|
||||
{
|
||||
private static char[] channelNames =
|
||||
{ 'x', 'y', 'z', 'w' };
|
||||
|
||||
public static string GetChannelSwizzle(int firstChannel, int channelCount)
|
||||
{
|
||||
System.Text.StringBuilder result = new System.Text.StringBuilder();
|
||||
int lastChannel = System.Math.Min(firstChannel + channelCount - 1, 4);
|
||||
for (int index = firstChannel; index <= lastChannel; index++)
|
||||
{
|
||||
result.Append(channelNames[index]);
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
// returns the offset of the first non-whitespace character, in the range [start, end] inclusive ... will return end if none found
|
||||
private static int SkipWhitespace(string str, int start, int end)
|
||||
{
|
||||
int index = start;
|
||||
|
||||
while (index < end)
|
||||
{
|
||||
char c = str[index];
|
||||
if (!Char.IsWhiteSpace(c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public class TemplatePreprocessor
|
||||
{
|
||||
// inputs
|
||||
ActiveFields activeFields;
|
||||
Dictionary<string, string> namedFragments;
|
||||
string[] templatePaths;
|
||||
bool isDebug;
|
||||
|
||||
// intermediates
|
||||
HashSet<string> includedFiles;
|
||||
|
||||
// outputs
|
||||
ShaderStringBuilder result;
|
||||
AssetCollection assetCollection;
|
||||
|
||||
public TemplatePreprocessor(ActiveFields activeFields, Dictionary<string, string> namedFragments, bool isDebug, string[] templatePaths, AssetCollection assetCollection, ShaderStringBuilder outShaderCodeResult = null)
|
||||
{
|
||||
this.activeFields = activeFields;
|
||||
this.namedFragments = namedFragments;
|
||||
this.isDebug = isDebug;
|
||||
this.templatePaths = templatePaths;
|
||||
this.assetCollection = assetCollection;
|
||||
this.result = outShaderCodeResult ?? new ShaderStringBuilder();
|
||||
includedFiles = new HashSet<string>();
|
||||
}
|
||||
|
||||
public ShaderStringBuilder GetShaderCode()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ProcessTemplateFile(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath) &&
|
||||
!includedFiles.Contains(filePath))
|
||||
{
|
||||
includedFiles.Add(filePath);
|
||||
|
||||
if (assetCollection != null)
|
||||
{
|
||||
GUID guid = AssetDatabase.GUIDFromAssetPath(filePath);
|
||||
if (!guid.Empty())
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.SourceDependency);
|
||||
}
|
||||
|
||||
string[] templateLines = File.ReadAllLines(filePath);
|
||||
foreach (string line in templateLines)
|
||||
{
|
||||
ProcessTemplateLine(line, 0, line.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct Token
|
||||
{
|
||||
public string s;
|
||||
public int start;
|
||||
public int end;
|
||||
|
||||
public Token(string s, int start, int end)
|
||||
{
|
||||
this.s = s;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public static Token Invalid()
|
||||
{
|
||||
return new Token(null, 0, 0);
|
||||
}
|
||||
|
||||
public bool IsValid()
|
||||
{
|
||||
return (s != null);
|
||||
}
|
||||
|
||||
public bool Is(string other)
|
||||
{
|
||||
int len = end - start;
|
||||
return (other.Length == len) && (0 == string.Compare(s, start, other, 0, len));
|
||||
}
|
||||
|
||||
public string GetString()
|
||||
{
|
||||
int len = end - start;
|
||||
if (len > 0)
|
||||
{
|
||||
return s.Substring(start, end - start);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessTemplateLine(string line, int start, int end)
|
||||
{
|
||||
bool appendEndln = true;
|
||||
|
||||
int cur = start;
|
||||
while (cur < end)
|
||||
{
|
||||
// find an escape code '$'
|
||||
int dollar = line.IndexOf('$', cur, end - cur);
|
||||
if (dollar < 0)
|
||||
{
|
||||
// no escape code found in the remaining code -- just append the rest verbatim
|
||||
AppendSubstring(line, cur, true, end, false);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// found $ escape sequence
|
||||
Token command = ParseIdentifier(line, dollar + 1, end);
|
||||
if (!command.IsValid())
|
||||
{
|
||||
Error("ERROR: $ must be followed by a command string (if, splice, or include)", line, dollar + 1);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (command.Is("include"))
|
||||
{
|
||||
ProcessIncludeCommand(command, end);
|
||||
appendEndln = false;
|
||||
break; // include command always ignores the rest of the line, error or not
|
||||
}
|
||||
else if (command.Is("splice"))
|
||||
{
|
||||
if (!ProcessSpliceCommand(command, end, ref cur))
|
||||
{
|
||||
// error, skip the rest of the line
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// let's see if it is a predicate
|
||||
Token predicate = ParseUntil(line, dollar + 1, end, ':');
|
||||
if (!predicate.IsValid())
|
||||
{
|
||||
Error("ERROR: unrecognized command: " + command.GetString(), line, command.start);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ProcessPredicate(predicate, end, ref cur, ref appendEndln))
|
||||
{
|
||||
break; // skip the rest of the line
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (appendEndln)
|
||||
{
|
||||
result.AppendNewLine();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessIncludeCommand(Token includeCommand, int lineEnd)
|
||||
{
|
||||
if (Expect(includeCommand.s, includeCommand.end, '('))
|
||||
{
|
||||
Token param = ParseString(includeCommand.s, includeCommand.end + 1, lineEnd);
|
||||
|
||||
if (!param.IsValid())
|
||||
{
|
||||
Error("ERROR: $include expected a string file path parameter", includeCommand.s, includeCommand.end + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool found = false;
|
||||
string includeLocation = null;
|
||||
|
||||
// Use reverse order in the array, higher number element have higher priority in case $include exist in several directories
|
||||
for (int i = templatePaths.Length - 1; i >= 0; i--)
|
||||
{
|
||||
string templatePath = templatePaths[i];
|
||||
includeLocation = Path.Combine(templatePath, param.GetString());
|
||||
if (File.Exists(includeLocation))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
string errorStr = "ERROR: $include cannot find file : " + param.GetString() + ". Looked into:\n";
|
||||
|
||||
foreach (string templatePath in templatePaths)
|
||||
{
|
||||
errorStr += "// " + templatePath + "\n";
|
||||
}
|
||||
|
||||
Error(errorStr, includeCommand.s, param.start);
|
||||
}
|
||||
else
|
||||
{
|
||||
int endIndex = result.length;
|
||||
using (var temp = new ShaderStringBuilder())
|
||||
{
|
||||
// Wrap in debug mode
|
||||
if (isDebug)
|
||||
{
|
||||
result.AppendLine("//-------------------------------------------------------------------------------------");
|
||||
result.AppendLine("// TEMPLATE INCLUDE : " + param.GetString());
|
||||
result.AppendLine("//-------------------------------------------------------------------------------------");
|
||||
result.AppendNewLine();
|
||||
}
|
||||
|
||||
// Recursively process templates
|
||||
ProcessTemplateFile(includeLocation);
|
||||
|
||||
// Wrap in debug mode
|
||||
if (isDebug)
|
||||
{
|
||||
result.AppendNewLine();
|
||||
result.AppendLine("//-------------------------------------------------------------------------------------");
|
||||
result.AppendLine("// END TEMPLATE INCLUDE : " + param.GetString());
|
||||
result.AppendLine("//-------------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
result.AppendNewLine();
|
||||
|
||||
// Required to enforce indentation rules
|
||||
// Append lines from this include into temporary StringBuilder
|
||||
// Reduce result length to remove this include
|
||||
temp.AppendLines(result.ToString(endIndex, result.length - endIndex));
|
||||
result.length = endIndex;
|
||||
result.AppendLines(temp.ToCodeBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ProcessSpliceCommand(Token spliceCommand, int lineEnd, ref int cur)
|
||||
{
|
||||
if (!Expect(spliceCommand.s, spliceCommand.end, '('))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Token param = ParseUntil(spliceCommand.s, spliceCommand.end + 1, lineEnd, ')');
|
||||
if (!param.IsValid())
|
||||
{
|
||||
Error("ERROR: splice command is missing a ')'", spliceCommand.s, spliceCommand.start);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// append everything before the beginning of the escape sequence
|
||||
AppendSubstring(spliceCommand.s, cur, true, spliceCommand.start - 1, false);
|
||||
|
||||
// find the named fragment
|
||||
string name = param.GetString(); // unfortunately this allocates a new string
|
||||
string fragment;
|
||||
if ((namedFragments != null) && namedFragments.TryGetValue(name, out fragment))
|
||||
{
|
||||
// splice the fragment
|
||||
result.Append(fragment);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no named fragment found
|
||||
result.Append("/* WARNING: $splice Could not find named fragment '{0}' */", name);
|
||||
}
|
||||
|
||||
// advance to just after the ')' and continue parsing
|
||||
cur = param.end + 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessPredicate(Token predicate, int endLine, ref int cur, ref bool appendEndln)
|
||||
{
|
||||
// eval if(param)
|
||||
var fieldName = predicate.GetString();
|
||||
var nonwhitespace = SkipWhitespace(predicate.s, predicate.end + 1, endLine);
|
||||
|
||||
if (!fieldName.StartsWith("features") && activeFields.permutationCount > 0)
|
||||
{
|
||||
var passedPermutations = activeFields.allPermutations.instances.Where(i => i.Contains(fieldName)).ToList();
|
||||
|
||||
if (passedPermutations.Count > 0)
|
||||
{
|
||||
var ifdefs = KeywordUtil.GetKeywordPermutationSetConditional(
|
||||
passedPermutations.Select(i => i.permutationIndex).ToList()
|
||||
);
|
||||
result.AppendLine(ifdefs);
|
||||
//Append the rest of the line
|
||||
AppendSubstring(predicate.s, nonwhitespace, true, endLine, false);
|
||||
result.AppendNewLine();
|
||||
result.AppendLine("#endif");
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
appendEndln = false; //if line isn't active, remove whitespace
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// eval if(param)
|
||||
if (activeFields.baseInstance.Contains(fieldName))
|
||||
{
|
||||
// predicate is active
|
||||
// append everything before the beginning of the escape sequence
|
||||
AppendSubstring(predicate.s, cur, true, predicate.start - 1, false);
|
||||
|
||||
// continue parsing the rest of the line, starting with the first nonwhitespace character
|
||||
cur = nonwhitespace;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// predicate is not active
|
||||
if (isDebug)
|
||||
{
|
||||
// append everything before the beginning of the escape sequence
|
||||
AppendSubstring(predicate.s, cur, true, predicate.start - 1, false);
|
||||
// append the rest of the line, commented out
|
||||
result.Append("// ");
|
||||
AppendSubstring(predicate.s, nonwhitespace, true, endLine, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't append anything
|
||||
appendEndln = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Token ParseIdentifier(string code, int start, int end)
|
||||
{
|
||||
if (start < end)
|
||||
{
|
||||
char c = code[start];
|
||||
if (Char.IsLetter(c) || (c == '_'))
|
||||
{
|
||||
int cur = start + 1;
|
||||
while (cur < end)
|
||||
{
|
||||
c = code[cur];
|
||||
if (!(Char.IsLetterOrDigit(c) || (c == '_')))
|
||||
break;
|
||||
cur++;
|
||||
}
|
||||
return new Token(code, start, cur);
|
||||
}
|
||||
}
|
||||
return Token.Invalid();
|
||||
}
|
||||
|
||||
private Token ParseString(string line, int start, int end)
|
||||
{
|
||||
if (Expect(line, start, '"'))
|
||||
{
|
||||
return ParseUntil(line, start + 1, end, '"');
|
||||
}
|
||||
return Token.Invalid();
|
||||
}
|
||||
|
||||
private Token ParseUntil(string line, int start, int end, char endChar)
|
||||
{
|
||||
int cur = start;
|
||||
while (cur < end)
|
||||
{
|
||||
if (line[cur] == endChar)
|
||||
{
|
||||
return new Token(line, start, cur);
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
return Token.Invalid();
|
||||
}
|
||||
|
||||
private bool Expect(string line, int location, char expected)
|
||||
{
|
||||
if ((location < line.Length) && (line[location] == expected))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Error("Expected '" + expected + "'", line, location);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Error(string error, string line, int location)
|
||||
{
|
||||
// append the line for context
|
||||
result.Append("\n");
|
||||
result.Append("// ");
|
||||
AppendSubstring(line, 0, true, line.Length, false);
|
||||
result.Append("\n");
|
||||
|
||||
// append the location marker, and error description
|
||||
result.Append("// ");
|
||||
result.AppendSpaces(location);
|
||||
result.Append("^ ");
|
||||
result.Append(error);
|
||||
result.Append("\n");
|
||||
}
|
||||
|
||||
// an easier to use version of substring Append() -- explicit inclusion on each end, and checks for positive length
|
||||
private void AppendSubstring(string str, int start, bool includeStart, int end, bool includeEnd)
|
||||
{
|
||||
if (!includeStart)
|
||||
{
|
||||
start++;
|
||||
}
|
||||
if (!includeEnd)
|
||||
{
|
||||
end--;
|
||||
}
|
||||
int count = end - start + 1;
|
||||
if (count > 0)
|
||||
{
|
||||
result.Append(str, start, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEditor.Graphing;
|
||||
using System.Globalization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
struct ShaderStringMapping
|
||||
{
|
||||
public AbstractMaterialNode node { get; set; }
|
||||
// public List<AbstractMaterialNode> nodes { get; set; }
|
||||
public int startIndex { get; set; }
|
||||
public int count { get; set; }
|
||||
}
|
||||
|
||||
class ShaderStringBuilder : IDisposable
|
||||
{
|
||||
enum ScopeType
|
||||
{
|
||||
Indent,
|
||||
Block,
|
||||
BlockSemicolon
|
||||
}
|
||||
|
||||
StringBuilder m_StringBuilder;
|
||||
Stack<ScopeType> m_ScopeStack;
|
||||
int m_IndentationLevel;
|
||||
ShaderStringMapping m_CurrentMapping;
|
||||
List<ShaderStringMapping> m_Mappings;
|
||||
|
||||
const string k_IndentationString = " ";
|
||||
const string k_NewLineString = "\n";
|
||||
|
||||
internal AbstractMaterialNode currentNode
|
||||
{
|
||||
get { return m_CurrentMapping.node; }
|
||||
set
|
||||
{
|
||||
m_CurrentMapping.count = m_StringBuilder.Length - m_CurrentMapping.startIndex;
|
||||
if (m_CurrentMapping.count > 0)
|
||||
m_Mappings.Add(m_CurrentMapping);
|
||||
m_CurrentMapping.node = value;
|
||||
m_CurrentMapping.startIndex = m_StringBuilder.Length;
|
||||
m_CurrentMapping.count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal List<ShaderStringMapping> mappings
|
||||
{
|
||||
get { return m_Mappings; }
|
||||
}
|
||||
|
||||
public ShaderStringBuilder()
|
||||
{
|
||||
m_StringBuilder = new StringBuilder();
|
||||
m_ScopeStack = new Stack<ScopeType>();
|
||||
m_Mappings = new List<ShaderStringMapping>();
|
||||
m_CurrentMapping = new ShaderStringMapping();
|
||||
}
|
||||
|
||||
public ShaderStringBuilder(int indentationLevel)
|
||||
: this()
|
||||
{
|
||||
IncreaseIndent(indentationLevel);
|
||||
}
|
||||
|
||||
public void AppendNewLine()
|
||||
{
|
||||
m_StringBuilder.Append(k_NewLineString);
|
||||
}
|
||||
|
||||
public void AppendLine(string value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
AppendIndentation();
|
||||
m_StringBuilder.Append(value);
|
||||
}
|
||||
AppendNewLine();
|
||||
}
|
||||
|
||||
[StringFormatMethod("formatString")]
|
||||
public void AppendLine(string formatString, params object[] args)
|
||||
{
|
||||
AppendIndentation();
|
||||
m_StringBuilder.AppendFormat(CultureInfo.InvariantCulture, formatString, args);
|
||||
AppendNewLine();
|
||||
}
|
||||
|
||||
public void AppendLines(string lines)
|
||||
{
|
||||
if (string.IsNullOrEmpty(lines))
|
||||
return;
|
||||
var splitLines = lines.Split('\n');
|
||||
var lineCount = splitLines.Length;
|
||||
var lastLine = splitLines[lineCount - 1];
|
||||
if (string.IsNullOrEmpty(lastLine) || lastLine == "\r")
|
||||
lineCount--;
|
||||
for (var i = 0; i < lineCount; i++)
|
||||
AppendLine(splitLines[i].Trim('\r'));
|
||||
}
|
||||
|
||||
public void Append(string value)
|
||||
{
|
||||
m_StringBuilder.Append(value);
|
||||
}
|
||||
|
||||
public void Append(string value, int start, int count)
|
||||
{
|
||||
m_StringBuilder.Append(value, start, count);
|
||||
}
|
||||
|
||||
[StringFormatMethod("formatString")]
|
||||
public void Append(string formatString, params object[] args)
|
||||
{
|
||||
m_StringBuilder.AppendFormat(formatString, args);
|
||||
}
|
||||
|
||||
public void AppendSpaces(int count)
|
||||
{
|
||||
m_StringBuilder.Append(' ', count);
|
||||
}
|
||||
|
||||
public void AppendIndentation()
|
||||
{
|
||||
for (var i = 0; i < m_IndentationLevel; i++)
|
||||
m_StringBuilder.Append(k_IndentationString);
|
||||
}
|
||||
|
||||
public IDisposable IndentScope()
|
||||
{
|
||||
m_ScopeStack.Push(ScopeType.Indent);
|
||||
IncreaseIndent();
|
||||
return this;
|
||||
}
|
||||
|
||||
public IDisposable BlockScope()
|
||||
{
|
||||
AppendLine("{");
|
||||
IncreaseIndent();
|
||||
m_ScopeStack.Push(ScopeType.Block);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IDisposable BlockSemicolonScope()
|
||||
{
|
||||
AppendLine("{");
|
||||
IncreaseIndent();
|
||||
m_ScopeStack.Push(ScopeType.BlockSemicolon);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void IncreaseIndent()
|
||||
{
|
||||
m_IndentationLevel++;
|
||||
}
|
||||
|
||||
public void IncreaseIndent(int level)
|
||||
{
|
||||
for (var i = 0; i < level; i++)
|
||||
IncreaseIndent();
|
||||
}
|
||||
|
||||
public void DecreaseIndent()
|
||||
{
|
||||
m_IndentationLevel--;
|
||||
}
|
||||
|
||||
public void DecreaseIndent(int level)
|
||||
{
|
||||
for (var i = 0; i < level; i++)
|
||||
DecreaseIndent();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_ScopeStack.Count == 0)
|
||||
return;
|
||||
|
||||
switch (m_ScopeStack.Pop())
|
||||
{
|
||||
case ScopeType.Indent:
|
||||
DecreaseIndent();
|
||||
break;
|
||||
case ScopeType.Block:
|
||||
DecreaseIndent();
|
||||
AppendLine("}");
|
||||
break;
|
||||
case ScopeType.BlockSemicolon:
|
||||
DecreaseIndent();
|
||||
AppendLine("};");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Concat(ShaderStringBuilder other)
|
||||
{
|
||||
// First re-add all the mappings from `other`, such that their mappings are transformed.
|
||||
foreach (var mapping in other.m_Mappings)
|
||||
{
|
||||
currentNode = mapping.node;
|
||||
|
||||
// Use `AppendLines` to indent according to the current indentation.
|
||||
AppendLines(other.ToString(mapping.startIndex, mapping.count));
|
||||
}
|
||||
currentNode = other.currentNode;
|
||||
AppendLines(other.ToString(other.m_CurrentMapping.startIndex, other.length - other.m_CurrentMapping.startIndex));
|
||||
}
|
||||
|
||||
public void ReplaceInCurrentMapping(string oldValue, string newValue)
|
||||
{
|
||||
int start = m_CurrentMapping.startIndex;
|
||||
int end = m_StringBuilder.Length - start;
|
||||
m_StringBuilder.Replace(oldValue, newValue, start, end);
|
||||
}
|
||||
|
||||
public string ToCodeBlock()
|
||||
{
|
||||
// Remove new line
|
||||
if (m_StringBuilder.Length > 0)
|
||||
m_StringBuilder.Length = m_StringBuilder.Length - 1;
|
||||
|
||||
// Set indentations
|
||||
m_StringBuilder.Replace(Environment.NewLine, Environment.NewLine + k_IndentationString);
|
||||
|
||||
return m_StringBuilder.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return m_StringBuilder.ToString();
|
||||
}
|
||||
|
||||
public string ToString(int startIndex, int length)
|
||||
{
|
||||
return m_StringBuilder.ToString(startIndex, length);
|
||||
}
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
m_StringBuilder.Length = 0;
|
||||
}
|
||||
|
||||
internal int length
|
||||
{
|
||||
get { return m_StringBuilder.Length; }
|
||||
set { m_StringBuilder.Length = value; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
using TextureDimension = UnityEngine.Rendering.TextureDimension;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public struct TextureInfo
|
||||
{
|
||||
public TextureInfo(string name, Texture texture, TextureDimension dimension)
|
||||
{
|
||||
this.name = name;
|
||||
this.texture = texture;
|
||||
this.dimension = dimension;
|
||||
Debug.Assert(texture == null || texture.dimension == dimension);
|
||||
}
|
||||
|
||||
public string name;
|
||||
public Texture texture;
|
||||
public TextureDimension dimension;
|
||||
|
||||
public int instanceID => texture != null ? texture.GetInstanceID() : 0;
|
||||
}
|
||||
|
||||
public sealed class ShaderGraphVfxAsset : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
private class ShaderGraphVfxAssetData : JsonObject
|
||||
{
|
||||
public List<JsonData<AbstractShaderProperty>> m_Properties = new List<JsonData<AbstractShaderProperty>>();
|
||||
}
|
||||
|
||||
public const int BaseColorSlotId = 1;
|
||||
public const int MetallicSlotId = 2;
|
||||
public const int SmoothnessSlotId = 3;
|
||||
public const int NormalSlotId = 8;
|
||||
public const int AlphaSlotId = 4;
|
||||
public const int EmissiveSlotId = 5;
|
||||
public const int ColorSlotId = 6;
|
||||
public const int AlphaThresholdSlotId = 7;
|
||||
|
||||
[SerializeField]
|
||||
public bool lit;
|
||||
|
||||
[SerializeField]
|
||||
public bool alphaClipping;
|
||||
|
||||
[SerializeField]
|
||||
internal GraphCompilationResult compilationResult;
|
||||
|
||||
[SerializeField]
|
||||
internal ShaderGraphRequirements[] portRequirements;
|
||||
|
||||
[SerializeField]
|
||||
string m_EvaluationFunctionName;
|
||||
|
||||
[SerializeField]
|
||||
string m_InputStructName;
|
||||
|
||||
[SerializeField]
|
||||
string m_OutputStructName;
|
||||
|
||||
[SerializeField]
|
||||
ConcretePrecision m_ConcretePrecision = ConcretePrecision.Single;
|
||||
|
||||
ShaderGraphVfxAssetData m_Data = new ShaderGraphVfxAssetData();
|
||||
|
||||
[SerializeField]
|
||||
private SerializationHelper.JSONSerializedElement m_SerializedVfxAssetData;
|
||||
|
||||
[SerializeField]
|
||||
internal IntArray[] outputPropertyIndices;
|
||||
|
||||
internal ConcretePrecision concretePrecision
|
||||
{
|
||||
get => m_ConcretePrecision;
|
||||
set => m_ConcretePrecision = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
OutputMetadata[] m_Outputs;
|
||||
|
||||
[SerializeField]
|
||||
TextureInfo[] m_TextureInfos;
|
||||
|
||||
public IEnumerable<TextureInfo> textureInfos { get => m_TextureInfos; }
|
||||
|
||||
internal void SetTextureInfos(IList<PropertyCollector.TextureInfo> textures)
|
||||
{
|
||||
m_TextureInfos = textures.Select(t => new TextureInfo(t.name, EditorUtility.InstanceIDToObject(t.textureId) as Texture, t.dimension)).ToArray();
|
||||
}
|
||||
|
||||
internal void SetOutputs(OutputMetadata[] outputs)
|
||||
{
|
||||
m_Outputs = outputs;
|
||||
}
|
||||
|
||||
public OutputMetadata GetOutput(int id)
|
||||
{
|
||||
return m_Outputs.FirstOrDefault(t => t.id == id);
|
||||
}
|
||||
|
||||
public bool HasOutput(int id)
|
||||
{
|
||||
return m_Outputs.Any(t => t.id == id);
|
||||
}
|
||||
|
||||
public string evaluationFunctionName
|
||||
{
|
||||
get { return m_EvaluationFunctionName; }
|
||||
internal set { m_EvaluationFunctionName = value; }
|
||||
}
|
||||
|
||||
public string inputStructName
|
||||
{
|
||||
get { return m_InputStructName; }
|
||||
internal set { m_InputStructName = value; }
|
||||
}
|
||||
|
||||
public string outputStructName
|
||||
{
|
||||
get { return m_OutputStructName; }
|
||||
internal set { m_OutputStructName = value; }
|
||||
}
|
||||
|
||||
public List<AbstractShaderProperty> properties
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureProperties();
|
||||
return m_Data.m_Properties.SelectValue().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetProperties(List<AbstractShaderProperty> propertiesList)
|
||||
{
|
||||
m_Data.m_Properties.Clear();
|
||||
foreach (var property in propertiesList)
|
||||
{
|
||||
m_Data.m_Properties.Add(property);
|
||||
}
|
||||
|
||||
var json = MultiJson.Serialize(m_Data);
|
||||
m_SerializedVfxAssetData = new SerializationHelper.JSONSerializedElement() { JSONnodeData = json };
|
||||
m_Data = null;
|
||||
}
|
||||
|
||||
void EnsureProperties()
|
||||
{
|
||||
if ((m_Data == null || m_Data.m_Properties == null || !m_Data.m_Properties.Any()) && !String.IsNullOrEmpty(m_SerializedVfxAssetData.JSONnodeData))
|
||||
{
|
||||
m_Data = new ShaderGraphVfxAssetData();
|
||||
MultiJson.Deserialize(m_Data , m_SerializedVfxAssetData.JSONnodeData);
|
||||
}
|
||||
|
||||
foreach (var property in m_Data.m_Properties.SelectValue())
|
||||
{
|
||||
property.ValidateConcretePrecision(m_ConcretePrecision);
|
||||
}
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
m_Data = null;
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize() {}
|
||||
|
||||
public GraphCode GetCode(OutputMetadata[] outputs)
|
||||
{
|
||||
var graphCode = new GraphCode();
|
||||
|
||||
graphCode.requirements = ShaderGraphRequirements.none;
|
||||
var outputIndices = new int[outputs.Length];
|
||||
for (var i = 0; i < outputs.Length; i++)
|
||||
{
|
||||
if (!outputs[i].isValid)
|
||||
{
|
||||
throw new ArgumentException($"Invalid {nameof(OutputMetadata)} at index {i}.", nameof(outputs));
|
||||
}
|
||||
|
||||
outputIndices[i] = outputs[i].index;
|
||||
graphCode.requirements = graphCode.requirements.Union(portRequirements[outputs[i].index]);
|
||||
}
|
||||
|
||||
graphCode.code = compilationResult.GenerateCode(outputIndices);
|
||||
|
||||
var propertyIndexSet = new HashSet<int>();
|
||||
foreach (var outputIndex in outputIndices)
|
||||
{
|
||||
foreach (var propertyIndex in outputPropertyIndices[outputIndex].array)
|
||||
{
|
||||
propertyIndexSet.Add(propertyIndex);
|
||||
}
|
||||
}
|
||||
var propertyIndices = propertyIndexSet.ToArray();
|
||||
Array.Sort(propertyIndices);
|
||||
var filteredProperties = propertyIndices.Select(i => properties[i]).ToArray();
|
||||
graphCode.properties = filteredProperties;
|
||||
|
||||
return graphCode;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable, GenerationAPI] // TODO: Public
|
||||
internal abstract class SubTarget : JsonObject
|
||||
{
|
||||
internal abstract Type targetType { get; }
|
||||
internal Target target { get; set; }
|
||||
public string displayName { get; set; }
|
||||
public bool isHidden { get; set; }
|
||||
public abstract bool IsActive();
|
||||
public abstract void Setup(ref TargetSetupContext context);
|
||||
public abstract void GetFields(ref TargetFieldContext context);
|
||||
public abstract void GetActiveBlocks(ref TargetActiveBlockContext context);
|
||||
public abstract void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo);
|
||||
|
||||
public virtual void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode) {}
|
||||
public virtual void ProcessPreviewMaterial(Material material) {}
|
||||
public virtual object saveContext => null;
|
||||
}
|
||||
|
||||
[GenerationAPI] // TODO: Public
|
||||
internal abstract class SubTarget<T> : SubTarget where T : Target
|
||||
{
|
||||
internal override Type targetType => typeof(T);
|
||||
|
||||
public new T target
|
||||
{
|
||||
get => base.target as T;
|
||||
set => base.target = value;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable, GenerationAPI] // TODO: Public
|
||||
internal abstract class Target : JsonObject
|
||||
{
|
||||
public string displayName { get; set; }
|
||||
public bool isHidden { get; set; }
|
||||
public abstract bool IsActive();
|
||||
public abstract void Setup(ref TargetSetupContext context);
|
||||
public abstract void GetFields(ref TargetFieldContext context);
|
||||
public abstract void GetActiveBlocks(ref TargetActiveBlockContext context);
|
||||
public abstract void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<string> registerUndo);
|
||||
|
||||
public virtual void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode) {}
|
||||
public virtual void ProcessPreviewMaterial(Material material) {}
|
||||
public virtual object saveContext => null;
|
||||
public virtual bool IsNodeAllowedByTarget(Type nodeType)
|
||||
{
|
||||
NeverAllowedByTargetAttribute never = NodeClassCache.GetAttributeOnNodeType<NeverAllowedByTargetAttribute>(nodeType);
|
||||
return never == null;
|
||||
}
|
||||
|
||||
public abstract bool WorksWithSRP(RenderPipelineAsset scriptableRenderPipeline);
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
internal static class BlockFields
|
||||
{
|
||||
[GenerateBlocks]
|
||||
public struct VertexDescription
|
||||
{
|
||||
public static string name = "VertexDescription";
|
||||
public static BlockFieldDescriptor Position = new BlockFieldDescriptor(VertexDescription.name, "Position", "VERTEXDESCRIPTION_POSITION",
|
||||
new PositionControl(CoordinateSpace.Object), ShaderStage.Vertex);
|
||||
public static BlockFieldDescriptor Normal = new BlockFieldDescriptor(VertexDescription.name, "Normal", "VERTEXDESCRIPTION_NORMAL",
|
||||
new NormalControl(CoordinateSpace.Object), ShaderStage.Vertex);
|
||||
public static BlockFieldDescriptor Tangent = new BlockFieldDescriptor(VertexDescription.name, "Tangent", "VERTEXDESCRIPTION_TANGENT",
|
||||
new TangentControl(CoordinateSpace.Object), ShaderStage.Vertex);
|
||||
}
|
||||
|
||||
[GenerateBlocks]
|
||||
public struct SurfaceDescription
|
||||
{
|
||||
public static string name = "SurfaceDescription";
|
||||
public static BlockFieldDescriptor BaseColor = new BlockFieldDescriptor(SurfaceDescription.name, "BaseColor", "Base Color", "SURFACEDESCRIPTION_BASECOLOR",
|
||||
new ColorControl(UnityEngine.Color.grey, false), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor NormalTS = new BlockFieldDescriptor(SurfaceDescription.name, "NormalTS", "Normal (Tangent Space)", "SURFACEDESCRIPTION_NORMALTS",
|
||||
new NormalControl(CoordinateSpace.Tangent), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor NormalOS = new BlockFieldDescriptor(SurfaceDescription.name, "NormalOS", "Normal (Object Space)", "SURFACEDESCRIPTION_NORMALOS",
|
||||
new NormalControl(CoordinateSpace.Object), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor NormalWS = new BlockFieldDescriptor(SurfaceDescription.name, "NormalWS", "Normal (World Space)", "SURFACEDESCRIPTION_NORMALWS",
|
||||
new NormalControl(CoordinateSpace.World), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor Metallic = new BlockFieldDescriptor(SurfaceDescription.name, "Metallic", "SURFACEDESCRIPTION_METALLIC",
|
||||
new FloatControl(0.0f), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor Specular = new BlockFieldDescriptor(SurfaceDescription.name, "Specular", "Specular Color", "SURFACEDESCRIPTION_SPECULAR",
|
||||
new ColorControl(UnityEngine.Color.grey, false), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor Smoothness = new BlockFieldDescriptor(SurfaceDescription.name, "Smoothness", "SURFACEDESCRIPTION_SMOOTHNESS",
|
||||
new FloatControl(0.5f), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor Occlusion = new BlockFieldDescriptor(SurfaceDescription.name, "Occlusion", "Ambient Occlusion", "SURFACEDESCRIPTION_OCCLUSION",
|
||||
new FloatControl(1.0f), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor Emission = new BlockFieldDescriptor(SurfaceDescription.name, "Emission", "SURFACEDESCRIPTION_EMISSION",
|
||||
new ColorControl(UnityEngine.Color.black, true), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor Alpha = new BlockFieldDescriptor(SurfaceDescription.name, "Alpha", "SURFACEDESCRIPTION_ALPHA",
|
||||
new FloatControl(1.0f), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor AlphaClipThreshold = new BlockFieldDescriptor(SurfaceDescription.name, "AlphaClipThreshold", "Alpha Clip Threshold", "SURFACEDESCRIPTION_ALPHACLIPTHRESHOLD",
|
||||
new FloatControl(0.5f), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor CoatMask = new BlockFieldDescriptor(SurfaceDescription.name, "CoatMask", "Coat Mask", "SURFACEDESCRIPTION_COATMASK",
|
||||
new FloatControl(0.0f), ShaderStage.Fragment);
|
||||
public static BlockFieldDescriptor CoatSmoothness = new BlockFieldDescriptor(SurfaceDescription.name, "CoatSmoothness", "Coat Smoothness", "SURFACEDESCRIPTION_COATSMOOTHNESS",
|
||||
new FloatControl(1.0f), ShaderStage.Fragment);
|
||||
}
|
||||
|
||||
[GenerateBlocks]
|
||||
public struct SurfaceDescriptionLegacy
|
||||
{
|
||||
public static string name = "SurfaceDescription";
|
||||
public static BlockFieldDescriptor SpriteColor = new BlockFieldDescriptor(SurfaceDescription.name, "SpriteColor", "SURFACEDESCRIPTION_SPRITECOLOR",
|
||||
new ColorRGBAControl(UnityEngine.Color.white), ShaderStage.Fragment, isHidden: true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal static class FieldDependencies
|
||||
{
|
||||
public static DependencyCollection Varyings = new DependencyCollection
|
||||
{
|
||||
new FieldDependency(StructFields.Varyings.positionWS, StructFields.Attributes.positionOS),
|
||||
new FieldDependency(StructFields.Varyings.normalWS, StructFields.Attributes.normalOS),
|
||||
new FieldDependency(StructFields.Varyings.tangentWS, StructFields.Attributes.tangentOS),
|
||||
new FieldDependency(StructFields.Varyings.texCoord0, StructFields.Attributes.uv0),
|
||||
new FieldDependency(StructFields.Varyings.texCoord1, StructFields.Attributes.uv1),
|
||||
new FieldDependency(StructFields.Varyings.texCoord2, StructFields.Attributes.uv2),
|
||||
new FieldDependency(StructFields.Varyings.texCoord3, StructFields.Attributes.uv3),
|
||||
new FieldDependency(StructFields.Varyings.color, StructFields.Attributes.color),
|
||||
new FieldDependency(StructFields.Varyings.instanceID, StructFields.Attributes.instanceID),
|
||||
};
|
||||
|
||||
public static DependencyCollection VertexDescription = new DependencyCollection
|
||||
{
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ObjectSpaceNormal, StructFields.Attributes.normalOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.WorldSpaceNormal, StructFields.Attributes.normalOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ViewSpaceNormal, StructFields.VertexDescriptionInputs.WorldSpaceNormal),
|
||||
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ObjectSpaceTangent, StructFields.Attributes.tangentOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.WorldSpaceTangent, StructFields.Attributes.tangentOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ViewSpaceTangent, StructFields.VertexDescriptionInputs.WorldSpaceTangent),
|
||||
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ObjectSpaceBiTangent, StructFields.Attributes.normalOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ObjectSpaceBiTangent, StructFields.Attributes.tangentOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.WorldSpaceBiTangent, StructFields.VertexDescriptionInputs.ObjectSpaceBiTangent),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ViewSpaceBiTangent, StructFields.VertexDescriptionInputs.WorldSpaceBiTangent),
|
||||
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ObjectSpacePosition, StructFields.Attributes.positionOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.WorldSpacePosition, StructFields.Attributes.positionOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.AbsoluteWorldSpacePosition, StructFields.Attributes.positionOS),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ViewSpacePosition, StructFields.VertexDescriptionInputs.WorldSpacePosition),
|
||||
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.WorldSpaceViewDirection, StructFields.VertexDescriptionInputs.WorldSpacePosition),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ObjectSpaceViewDirection, StructFields.VertexDescriptionInputs.WorldSpaceViewDirection),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ViewSpaceViewDirection, StructFields.VertexDescriptionInputs.WorldSpaceViewDirection),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.TangentSpaceViewDirection, StructFields.VertexDescriptionInputs.WorldSpaceViewDirection),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.TangentSpaceViewDirection, StructFields.VertexDescriptionInputs.WorldSpaceTangent),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.TangentSpaceViewDirection, StructFields.VertexDescriptionInputs.WorldSpaceBiTangent),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.TangentSpaceViewDirection, StructFields.VertexDescriptionInputs.WorldSpaceNormal),
|
||||
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.ScreenPosition, StructFields.VertexDescriptionInputs.WorldSpacePosition),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.uv0, StructFields.Attributes.uv0),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.uv1, StructFields.Attributes.uv1),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.uv2, StructFields.Attributes.uv2),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.uv3, StructFields.Attributes.uv3),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.VertexColor, StructFields.Attributes.color),
|
||||
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.BoneWeights, StructFields.Attributes.weights),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.BoneIndices, StructFields.Attributes.indices),
|
||||
new FieldDependency(StructFields.VertexDescriptionInputs.VertexID, StructFields.Attributes.vertexID),
|
||||
};
|
||||
|
||||
public static DependencyCollection SurfaceDescription = new DependencyCollection
|
||||
{
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.WorldSpaceNormal, StructFields.Varyings.normalWS),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ObjectSpaceNormal, StructFields.SurfaceDescriptionInputs.WorldSpaceNormal),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ViewSpaceNormal, StructFields.SurfaceDescriptionInputs.WorldSpaceNormal),
|
||||
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.WorldSpaceTangent, StructFields.Varyings.tangentWS),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.WorldSpaceTangent, StructFields.SurfaceDescriptionInputs.WorldSpaceNormal),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ObjectSpaceTangent, StructFields.SurfaceDescriptionInputs.WorldSpaceTangent),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ViewSpaceTangent, StructFields.SurfaceDescriptionInputs.WorldSpaceTangent),
|
||||
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.WorldSpaceBiTangent, StructFields.SurfaceDescriptionInputs.WorldSpaceNormal),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.WorldSpaceBiTangent, StructFields.SurfaceDescriptionInputs.WorldSpaceTangent),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ObjectSpaceBiTangent, StructFields.SurfaceDescriptionInputs.WorldSpaceBiTangent),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ViewSpaceBiTangent, StructFields.SurfaceDescriptionInputs.WorldSpaceBiTangent),
|
||||
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.WorldSpacePosition, StructFields.Varyings.positionWS),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.AbsoluteWorldSpacePosition, StructFields.Varyings.positionWS),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ObjectSpacePosition, StructFields.Varyings.positionWS),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ViewSpacePosition, StructFields.Varyings.positionWS),
|
||||
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.WorldSpaceViewDirection, StructFields.Varyings.viewDirectionWS),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ObjectSpaceViewDirection, StructFields.SurfaceDescriptionInputs.WorldSpaceViewDirection),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ViewSpaceViewDirection, StructFields.SurfaceDescriptionInputs.WorldSpaceViewDirection),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.TangentSpaceViewDirection, StructFields.SurfaceDescriptionInputs.WorldSpaceViewDirection),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.TangentSpaceViewDirection, StructFields.SurfaceDescriptionInputs.WorldSpaceTangent),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.TangentSpaceViewDirection, StructFields.SurfaceDescriptionInputs.WorldSpaceBiTangent),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.TangentSpaceViewDirection, StructFields.SurfaceDescriptionInputs.WorldSpaceNormal),
|
||||
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.ScreenPosition, StructFields.SurfaceDescriptionInputs.WorldSpacePosition),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.uv0, StructFields.Varyings.texCoord0),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.uv1, StructFields.Varyings.texCoord1),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.uv2, StructFields.Varyings.texCoord2),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.uv3, StructFields.Varyings.texCoord3),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.VertexColor, StructFields.Varyings.color),
|
||||
new FieldDependency(StructFields.SurfaceDescriptionInputs.FaceSign, StructFields.Varyings.cullFace),
|
||||
};
|
||||
|
||||
public static DependencyCollection Default = new DependencyCollection
|
||||
{
|
||||
{ Varyings },
|
||||
{ VertexDescription },
|
||||
{ SurfaceDescription },
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal static class Fields
|
||||
{
|
||||
#region Tags
|
||||
public const string kFeatures = "features";
|
||||
public const string kSurfaceType = "SurfaceType";
|
||||
public const string kBlendMode = "BlendMode";
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
// These are core Fields shared between URP and HDRP etc.
|
||||
public static FieldDescriptor GraphVertex = new FieldDescriptor(kFeatures, "graphVertex", "FEATURES_GRAPH_VERTEX");
|
||||
public static FieldDescriptor GraphPixel = new FieldDescriptor(kFeatures, "graphPixel", "FEATURES_GRAPH_PIXEL");
|
||||
public static FieldDescriptor AlphaClip = new FieldDescriptor(string.Empty, "AlphaClip", "_AlphaClip 1");
|
||||
public static FieldDescriptor AlphaTest = new FieldDescriptor(string.Empty, "AlphaTest", "_ALPHA_TEST 1");
|
||||
public static FieldDescriptor BlendAlpha = new FieldDescriptor(kBlendMode, "Alpha", "_BLENDMODE_ALPHA 1"); // Universal, vfx: HDRP?
|
||||
public static FieldDescriptor DoubleSided = new FieldDescriptor(string.Empty, "DoubleSided", "_DOUBLE_SIDED 1"); // Universal, duplicated in HD
|
||||
public static FieldDescriptor IsPreview = new FieldDescriptor(string.Empty, "isPreview", "SHADERGRAPH_PREVIEW");
|
||||
public static FieldDescriptor LodCrossFade = new FieldDescriptor(string.Empty, "LodCrossFade", "_LODCROSSFADE 1"); // HD only
|
||||
public static FieldDescriptor AlphaToMask = new FieldDescriptor(string.Empty, "AlphaToMask", "_ALPHATOMASK_ON 1"); // HD only
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,214 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal static class StructFields
|
||||
{
|
||||
public struct Attributes
|
||||
{
|
||||
public static string name = "Attributes";
|
||||
public static FieldDescriptor positionOS = new FieldDescriptor(Attributes.name, "positionOS", "", ShaderValueType.Float3, "POSITION");
|
||||
public static FieldDescriptor normalOS = new FieldDescriptor(Attributes.name, "normalOS", "ATTRIBUTES_NEED_NORMAL", ShaderValueType.Float3,
|
||||
"NORMAL", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor tangentOS = new FieldDescriptor(Attributes.name, "tangentOS", "ATTRIBUTES_NEED_TANGENT", ShaderValueType.Float4,
|
||||
"TANGENT", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv0 = new FieldDescriptor(Attributes.name, "uv0", "ATTRIBUTES_NEED_TEXCOORD0", ShaderValueType.Float4,
|
||||
"TEXCOORD0", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv1 = new FieldDescriptor(Attributes.name, "uv1", "ATTRIBUTES_NEED_TEXCOORD1", ShaderValueType.Float4,
|
||||
"TEXCOORD1", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv2 = new FieldDescriptor(Attributes.name, "uv2", "ATTRIBUTES_NEED_TEXCOORD2", ShaderValueType.Float4,
|
||||
"TEXCOORD2", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv3 = new FieldDescriptor(Attributes.name, "uv3", "ATTRIBUTES_NEED_TEXCOORD3", ShaderValueType.Float4,
|
||||
"TEXCOORD3", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor weights = new FieldDescriptor(Attributes.name, "weights", "ATTRIBUTES_NEED_BLENDWEIGHTS", ShaderValueType.Float4,
|
||||
"BLENDWEIGHTS", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor indices = new FieldDescriptor(Attributes.name, "indices", "ATTRIBUTES_NEED_BLENDINDICES", ShaderValueType.Uint4,
|
||||
"BLENDINDICES", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor color = new FieldDescriptor(Attributes.name, "color", "ATTRIBUTES_NEED_COLOR", ShaderValueType.Float4,
|
||||
"COLOR", subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor instanceID = new FieldDescriptor(Attributes.name, "instanceID", "", ShaderValueType.Uint,
|
||||
"INSTANCEID_SEMANTIC", "UNITY_ANY_INSTANCING_ENABLED");
|
||||
public static FieldDescriptor vertexID = new FieldDescriptor(Attributes.name, "vertexID", "ATTRIBUTES_NEED_VERTEXID", ShaderValueType.Uint,
|
||||
"SV_VertexID", subscriptOptions: StructFieldOptions.Optional);
|
||||
}
|
||||
|
||||
public struct Varyings
|
||||
{
|
||||
public static string name = "Varyings";
|
||||
public static FieldDescriptor positionCS = new FieldDescriptor(Varyings.name, "positionCS", "", ShaderValueType.Float4, "SV_POSITION");
|
||||
public static FieldDescriptor positionWS = new FieldDescriptor(Varyings.name, "positionWS", "VARYINGS_NEED_POSITION_WS", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor normalWS = new FieldDescriptor(Varyings.name, "normalWS", "VARYINGS_NEED_NORMAL_WS", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor tangentWS = new FieldDescriptor(Varyings.name, "tangentWS", "VARYINGS_NEED_TANGENT_WS", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor texCoord0 = new FieldDescriptor(Varyings.name, "texCoord0", "VARYINGS_NEED_TEXCOORD0", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor texCoord1 = new FieldDescriptor(Varyings.name, "texCoord1", "VARYINGS_NEED_TEXCOORD1", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor texCoord2 = new FieldDescriptor(Varyings.name, "texCoord2", "VARYINGS_NEED_TEXCOORD2", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor texCoord3 = new FieldDescriptor(Varyings.name, "texCoord3", "VARYINGS_NEED_TEXCOORD3", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor color = new FieldDescriptor(Varyings.name, "color", "VARYINGS_NEED_COLOR", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor viewDirectionWS = new FieldDescriptor(Varyings.name, "viewDirectionWS", "VARYINGS_NEED_VIEWDIRECTION_WS", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor screenPosition = new FieldDescriptor(Varyings.name, "screenPosition", "VARYINGS_NEED_SCREENPOSITION", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor instanceID = new FieldDescriptor(Varyings.name, "instanceID", "", ShaderValueType.Uint,
|
||||
"CUSTOM_INSTANCE_ID", "UNITY_ANY_INSTANCING_ENABLED");
|
||||
public static FieldDescriptor cullFace = new FieldDescriptor(Varyings.name, "cullFace", "VARYINGS_NEED_CULLFACE", "FRONT_FACE_TYPE",
|
||||
"FRONT_FACE_SEMANTIC", "defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)", StructFieldOptions.Generated & StructFieldOptions.Optional);
|
||||
}
|
||||
|
||||
public struct VertexDescriptionInputs
|
||||
{
|
||||
public static string name = "VertexDescriptionInputs";
|
||||
public static FieldDescriptor ObjectSpaceNormal = new FieldDescriptor(VertexDescriptionInputs.name, "ObjectSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceNormal = new FieldDescriptor(VertexDescriptionInputs.name, "ViewSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceNormal = new FieldDescriptor(VertexDescriptionInputs.name, "WorldSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceNormal = new FieldDescriptor(VertexDescriptionInputs.name, "TangentSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpaceTangent = new FieldDescriptor(VertexDescriptionInputs.name, "ObjectSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceTangent = new FieldDescriptor(VertexDescriptionInputs.name, "ViewSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceTangent = new FieldDescriptor(VertexDescriptionInputs.name, "WorldSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceTangent = new FieldDescriptor(VertexDescriptionInputs.name, "TangentSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpaceBiTangent = new FieldDescriptor(VertexDescriptionInputs.name, "ObjectSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceBiTangent = new FieldDescriptor(VertexDescriptionInputs.name, "ViewSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceBiTangent = new FieldDescriptor(VertexDescriptionInputs.name, "WorldSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceBiTangent = new FieldDescriptor(VertexDescriptionInputs.name, "TangentSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpaceViewDirection = new FieldDescriptor(VertexDescriptionInputs.name, "ObjectSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceViewDirection = new FieldDescriptor(VertexDescriptionInputs.name, "ViewSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceViewDirection = new FieldDescriptor(VertexDescriptionInputs.name, "WorldSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceViewDirection = new FieldDescriptor(VertexDescriptionInputs.name, "TangentSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpacePosition = new FieldDescriptor(VertexDescriptionInputs.name, "ObjectSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpacePosition = new FieldDescriptor(VertexDescriptionInputs.name, "ViewSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpacePosition = new FieldDescriptor(VertexDescriptionInputs.name, "WorldSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpacePosition = new FieldDescriptor(VertexDescriptionInputs.name, "TangentSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor AbsoluteWorldSpacePosition = new FieldDescriptor(VertexDescriptionInputs.name, "AbsoluteWorldSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ScreenPosition = new FieldDescriptor(VertexDescriptionInputs.name, "ScreenPosition", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv0 = new FieldDescriptor(VertexDescriptionInputs.name, "uv0", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv1 = new FieldDescriptor(VertexDescriptionInputs.name, "uv1", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv2 = new FieldDescriptor(VertexDescriptionInputs.name, "uv2", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv3 = new FieldDescriptor(VertexDescriptionInputs.name, "uv3", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor VertexColor = new FieldDescriptor(VertexDescriptionInputs.name, "VertexColor", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TimeParameters = new FieldDescriptor(VertexDescriptionInputs.name, "TimeParameters", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor BoneWeights = new FieldDescriptor(VertexDescriptionInputs.name, "BoneWeights", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor BoneIndices = new FieldDescriptor(VertexDescriptionInputs.name, "BoneIndices", "", ShaderValueType.Uint4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor VertexID = new FieldDescriptor(VertexDescriptionInputs.name, "VertexID", "", ShaderValueType.Uint,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
}
|
||||
|
||||
public struct SurfaceDescriptionInputs
|
||||
{
|
||||
public static string name = "SurfaceDescriptionInputs";
|
||||
public static FieldDescriptor ObjectSpaceNormal = new FieldDescriptor(SurfaceDescriptionInputs.name, "ObjectSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceNormal = new FieldDescriptor(SurfaceDescriptionInputs.name, "ViewSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceNormal = new FieldDescriptor(SurfaceDescriptionInputs.name, "WorldSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceNormal = new FieldDescriptor(SurfaceDescriptionInputs.name, "TangentSpaceNormal", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpaceTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "ObjectSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "ViewSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "WorldSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "TangentSpaceTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpaceBiTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "ObjectSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceBiTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "ViewSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceBiTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "WorldSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceBiTangent = new FieldDescriptor(SurfaceDescriptionInputs.name, "TangentSpaceBiTangent", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpaceViewDirection = new FieldDescriptor(SurfaceDescriptionInputs.name, "ObjectSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpaceViewDirection = new FieldDescriptor(SurfaceDescriptionInputs.name, "ViewSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpaceViewDirection = new FieldDescriptor(SurfaceDescriptionInputs.name, "WorldSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpaceViewDirection = new FieldDescriptor(SurfaceDescriptionInputs.name, "TangentSpaceViewDirection", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ObjectSpacePosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "ObjectSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor ViewSpacePosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "ViewSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor WorldSpacePosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "WorldSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TangentSpacePosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "TangentSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor AbsoluteWorldSpacePosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "AbsoluteWorldSpacePosition", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor ScreenPosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "ScreenPosition", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv0 = new FieldDescriptor(SurfaceDescriptionInputs.name, "uv0", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv1 = new FieldDescriptor(SurfaceDescriptionInputs.name, "uv1", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv2 = new FieldDescriptor(SurfaceDescriptionInputs.name, "uv2", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor uv3 = new FieldDescriptor(SurfaceDescriptionInputs.name, "uv3", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor VertexColor = new FieldDescriptor(SurfaceDescriptionInputs.name, "VertexColor", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor TimeParameters = new FieldDescriptor(SurfaceDescriptionInputs.name, "TimeParameters", "", ShaderValueType.Float3,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor FaceSign = new FieldDescriptor(SurfaceDescriptionInputs.name, "FaceSign", "", ShaderValueType.Float,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor BoneWeights = new FieldDescriptor(SurfaceDescriptionInputs.name, "BoneWeights", "", ShaderValueType.Float4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
public static FieldDescriptor BoneIndices = new FieldDescriptor(SurfaceDescriptionInputs.name, "BoneIndices", "", ShaderValueType.Uint4,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
|
||||
public static FieldDescriptor VertexID = new FieldDescriptor(SurfaceDescriptionInputs.name, "VertexID", "", ShaderValueType.Uint,
|
||||
subscriptOptions: StructFieldOptions.Optional);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,118 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
internal static class Structs
|
||||
{
|
||||
public static StructDescriptor Attributes = new StructDescriptor()
|
||||
{
|
||||
name = "Attributes",
|
||||
packFields = false,
|
||||
fields = new FieldDescriptor[]
|
||||
{
|
||||
StructFields.Attributes.positionOS,
|
||||
StructFields.Attributes.normalOS,
|
||||
StructFields.Attributes.tangentOS,
|
||||
StructFields.Attributes.uv0,
|
||||
StructFields.Attributes.uv1,
|
||||
StructFields.Attributes.uv2,
|
||||
StructFields.Attributes.uv3,
|
||||
StructFields.Attributes.color,
|
||||
StructFields.Attributes.instanceID,
|
||||
StructFields.Attributes.weights,
|
||||
StructFields.Attributes.indices,
|
||||
StructFields.Attributes.vertexID,
|
||||
}
|
||||
};
|
||||
|
||||
public static StructDescriptor VertexDescriptionInputs = new StructDescriptor()
|
||||
{
|
||||
name = "VertexDescriptionInputs",
|
||||
packFields = false,
|
||||
fields = new FieldDescriptor[]
|
||||
{
|
||||
StructFields.VertexDescriptionInputs.ObjectSpaceNormal,
|
||||
StructFields.VertexDescriptionInputs.ViewSpaceNormal,
|
||||
StructFields.VertexDescriptionInputs.WorldSpaceNormal,
|
||||
StructFields.VertexDescriptionInputs.TangentSpaceNormal,
|
||||
|
||||
StructFields.VertexDescriptionInputs.ObjectSpaceTangent,
|
||||
StructFields.VertexDescriptionInputs.ViewSpaceTangent,
|
||||
StructFields.VertexDescriptionInputs.WorldSpaceTangent,
|
||||
StructFields.VertexDescriptionInputs.TangentSpaceTangent,
|
||||
|
||||
StructFields.VertexDescriptionInputs.ObjectSpaceBiTangent,
|
||||
StructFields.VertexDescriptionInputs.ViewSpaceBiTangent,
|
||||
StructFields.VertexDescriptionInputs.WorldSpaceBiTangent,
|
||||
StructFields.VertexDescriptionInputs.TangentSpaceBiTangent,
|
||||
|
||||
StructFields.VertexDescriptionInputs.ObjectSpaceViewDirection,
|
||||
StructFields.VertexDescriptionInputs.ViewSpaceViewDirection,
|
||||
StructFields.VertexDescriptionInputs.WorldSpaceViewDirection,
|
||||
StructFields.VertexDescriptionInputs.TangentSpaceViewDirection,
|
||||
|
||||
StructFields.VertexDescriptionInputs.ObjectSpacePosition,
|
||||
StructFields.VertexDescriptionInputs.ViewSpacePosition,
|
||||
StructFields.VertexDescriptionInputs.WorldSpacePosition,
|
||||
StructFields.VertexDescriptionInputs.TangentSpacePosition,
|
||||
StructFields.VertexDescriptionInputs.AbsoluteWorldSpacePosition,
|
||||
|
||||
StructFields.VertexDescriptionInputs.ScreenPosition,
|
||||
StructFields.VertexDescriptionInputs.uv0,
|
||||
StructFields.VertexDescriptionInputs.uv1,
|
||||
StructFields.VertexDescriptionInputs.uv2,
|
||||
StructFields.VertexDescriptionInputs.uv3,
|
||||
StructFields.VertexDescriptionInputs.VertexColor,
|
||||
StructFields.VertexDescriptionInputs.TimeParameters,
|
||||
StructFields.VertexDescriptionInputs.BoneWeights,
|
||||
StructFields.VertexDescriptionInputs.BoneIndices,
|
||||
StructFields.VertexDescriptionInputs.VertexID,
|
||||
}
|
||||
};
|
||||
|
||||
public static StructDescriptor SurfaceDescriptionInputs = new StructDescriptor()
|
||||
{
|
||||
name = "SurfaceDescriptionInputs",
|
||||
packFields = false,
|
||||
fields = new FieldDescriptor[]
|
||||
{
|
||||
StructFields.SurfaceDescriptionInputs.ObjectSpaceNormal,
|
||||
StructFields.SurfaceDescriptionInputs.ViewSpaceNormal,
|
||||
StructFields.SurfaceDescriptionInputs.WorldSpaceNormal,
|
||||
StructFields.SurfaceDescriptionInputs.TangentSpaceNormal,
|
||||
|
||||
StructFields.SurfaceDescriptionInputs.ObjectSpaceTangent,
|
||||
StructFields.SurfaceDescriptionInputs.ViewSpaceTangent,
|
||||
StructFields.SurfaceDescriptionInputs.WorldSpaceTangent,
|
||||
StructFields.SurfaceDescriptionInputs.TangentSpaceTangent,
|
||||
|
||||
StructFields.SurfaceDescriptionInputs.ObjectSpaceBiTangent,
|
||||
StructFields.SurfaceDescriptionInputs.ViewSpaceBiTangent,
|
||||
StructFields.SurfaceDescriptionInputs.WorldSpaceBiTangent,
|
||||
StructFields.SurfaceDescriptionInputs.TangentSpaceBiTangent,
|
||||
|
||||
StructFields.SurfaceDescriptionInputs.ObjectSpaceViewDirection,
|
||||
StructFields.SurfaceDescriptionInputs.ViewSpaceViewDirection,
|
||||
StructFields.SurfaceDescriptionInputs.WorldSpaceViewDirection,
|
||||
StructFields.SurfaceDescriptionInputs.TangentSpaceViewDirection,
|
||||
|
||||
StructFields.SurfaceDescriptionInputs.ObjectSpacePosition,
|
||||
StructFields.SurfaceDescriptionInputs.ViewSpacePosition,
|
||||
StructFields.SurfaceDescriptionInputs.WorldSpacePosition,
|
||||
StructFields.SurfaceDescriptionInputs.TangentSpacePosition,
|
||||
StructFields.SurfaceDescriptionInputs.AbsoluteWorldSpacePosition,
|
||||
|
||||
StructFields.SurfaceDescriptionInputs.ScreenPosition,
|
||||
StructFields.SurfaceDescriptionInputs.uv0,
|
||||
StructFields.SurfaceDescriptionInputs.uv1,
|
||||
StructFields.SurfaceDescriptionInputs.uv2,
|
||||
StructFields.SurfaceDescriptionInputs.uv3,
|
||||
StructFields.SurfaceDescriptionInputs.VertexColor,
|
||||
StructFields.SurfaceDescriptionInputs.TimeParameters,
|
||||
StructFields.SurfaceDescriptionInputs.FaceSign,
|
||||
StructFields.SurfaceDescriptionInputs.BoneWeights,
|
||||
StructFields.SurfaceDescriptionInputs.BoneIndices,
|
||||
StructFields.SurfaceDescriptionInputs.VertexID,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed class PreviewTarget : Target
|
||||
{
|
||||
static readonly GUID kSourceCodeGuid = new GUID("7464b9fcde08e5645a16b9b8ae1e573c"); // PreviewTarget.cs
|
||||
|
||||
public PreviewTarget()
|
||||
{
|
||||
displayName = "Preview";
|
||||
isHidden = true;
|
||||
}
|
||||
|
||||
public override bool IsActive() => false;
|
||||
|
||||
public override void Setup(ref TargetSetupContext context)
|
||||
{
|
||||
context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency);
|
||||
context.AddSubShader(SubShaders.Preview);
|
||||
}
|
||||
|
||||
public override void GetFields(ref TargetFieldContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetActiveBlocks(ref TargetActiveBlockContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool WorksWithSRP(RenderPipelineAsset scriptableRenderPipeline) => true;
|
||||
|
||||
static class SubShaders
|
||||
{
|
||||
public static SubShaderDescriptor Preview = new SubShaderDescriptor()
|
||||
{
|
||||
renderQueue = "Geometry",
|
||||
renderType = "Opaque",
|
||||
generatesPreview = true,
|
||||
passes = new PassCollection { Passes.Preview },
|
||||
};
|
||||
}
|
||||
|
||||
static class Passes
|
||||
{
|
||||
public static PassDescriptor Preview = new PassDescriptor()
|
||||
{
|
||||
// Definition
|
||||
referenceName = "SHADERPASS_PREVIEW",
|
||||
useInPreview = true,
|
||||
|
||||
// Templates
|
||||
passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"),
|
||||
sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(),
|
||||
|
||||
// Collections
|
||||
structs = new StructCollection
|
||||
{
|
||||
{ Structs.Attributes },
|
||||
{ StructDescriptors.PreviewVaryings },
|
||||
{ Structs.SurfaceDescriptionInputs },
|
||||
{ Structs.VertexDescriptionInputs },
|
||||
},
|
||||
fieldDependencies = FieldDependencies.Default,
|
||||
pragmas = new PragmaCollection
|
||||
{
|
||||
{ Pragma.Vertex("vert") },
|
||||
{ Pragma.Fragment("frag") },
|
||||
},
|
||||
defines = new DefineCollection
|
||||
{
|
||||
{ KeywordDescriptors.PreviewKeyword, 1 },
|
||||
},
|
||||
includes = new IncludeCollection
|
||||
{
|
||||
// Pre-graph
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl", IncludeLocation.Pregraph }, // TODO: put this on a conditional
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariables.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl", IncludeLocation.Pregraph },
|
||||
{ "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl", IncludeLocation.Pregraph },
|
||||
|
||||
// Post-graph
|
||||
{ "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewVaryings.hlsl", IncludeLocation.Postgraph },
|
||||
{ "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewPass.hlsl", IncludeLocation.Postgraph },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class StructDescriptors
|
||||
{
|
||||
public static StructDescriptor PreviewVaryings = new StructDescriptor()
|
||||
{
|
||||
name = "Varyings",
|
||||
packFields = true,
|
||||
fields = new[]
|
||||
{
|
||||
StructFields.Varyings.positionCS,
|
||||
StructFields.Varyings.positionWS,
|
||||
StructFields.Varyings.normalWS,
|
||||
StructFields.Varyings.tangentWS,
|
||||
StructFields.Varyings.texCoord0,
|
||||
StructFields.Varyings.texCoord1,
|
||||
StructFields.Varyings.texCoord2,
|
||||
StructFields.Varyings.texCoord3,
|
||||
StructFields.Varyings.color,
|
||||
StructFields.Varyings.viewDirectionWS,
|
||||
StructFields.Varyings.screenPosition,
|
||||
StructFields.Varyings.instanceID,
|
||||
StructFields.Varyings.cullFace,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class KeywordDescriptors
|
||||
{
|
||||
public static KeywordDescriptor PreviewKeyword = new KeywordDescriptor()
|
||||
{
|
||||
displayName = "Preview",
|
||||
referenceName = "SHADERGRAPH_PREVIEW",
|
||||
type = KeywordType.Boolean,
|
||||
definition = KeywordDefinition.MultiCompile,
|
||||
scope = KeywordScope.Global,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,148 @@
|
||||
#if VFX_GRAPH_10_0_0_OR_NEWER
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEditor.ShaderGraph.Drawing;
|
||||
using UnityEditor.Graphing.Util;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Legacy;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed class VFXTarget : Target, ILegacyTarget
|
||||
{
|
||||
[SerializeField]
|
||||
bool m_Lit;
|
||||
|
||||
[SerializeField]
|
||||
bool m_AlphaTest = false;
|
||||
|
||||
public VFXTarget()
|
||||
{
|
||||
displayName = "Visual Effect";
|
||||
}
|
||||
|
||||
public bool lit
|
||||
{
|
||||
get => m_Lit;
|
||||
set => m_Lit = value;
|
||||
}
|
||||
|
||||
public bool alphaTest
|
||||
{
|
||||
get => m_AlphaTest;
|
||||
set => m_AlphaTest = value;
|
||||
}
|
||||
|
||||
public override bool IsActive() => true;
|
||||
|
||||
public override void Setup(ref TargetSetupContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetFields(ref TargetFieldContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsNodeAllowedByTarget(Type nodeType)
|
||||
{
|
||||
return base.IsNodeAllowedByTarget(nodeType);
|
||||
}
|
||||
|
||||
public override void GetActiveBlocks(ref TargetActiveBlockContext context)
|
||||
{
|
||||
context.AddBlock(BlockFields.SurfaceDescription.BaseColor);
|
||||
context.AddBlock(BlockFields.SurfaceDescription.Alpha);
|
||||
context.AddBlock(BlockFields.SurfaceDescription.Metallic, lit);
|
||||
context.AddBlock(BlockFields.SurfaceDescription.Smoothness, lit);
|
||||
context.AddBlock(BlockFields.SurfaceDescription.NormalTS, lit);
|
||||
context.AddBlock(BlockFields.SurfaceDescription.Emission);
|
||||
context.AddBlock(BlockFields.SurfaceDescription.AlphaClipThreshold, alphaTest);
|
||||
}
|
||||
|
||||
enum MaterialMode
|
||||
{
|
||||
Unlit,
|
||||
Lit
|
||||
}
|
||||
|
||||
public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
|
||||
{
|
||||
context.AddProperty("Material", new EnumField(MaterialMode.Unlit) { value = m_Lit ? MaterialMode.Lit : MaterialMode.Unlit }, evt =>
|
||||
{
|
||||
var newLit = (MaterialMode)evt.newValue == MaterialMode.Lit;
|
||||
if (Equals(m_Lit, newLit))
|
||||
return;
|
||||
|
||||
registerUndo("Change Material Lit");
|
||||
m_Lit = newLit;
|
||||
onChange();
|
||||
});
|
||||
|
||||
context.AddProperty("Alpha Clipping", new Toggle() { value = m_AlphaTest }, (evt) =>
|
||||
{
|
||||
if (Equals(m_AlphaTest, evt.newValue))
|
||||
return;
|
||||
|
||||
registerUndo("Change Alpha Test");
|
||||
m_AlphaTest = evt.newValue;
|
||||
onChange();
|
||||
});
|
||||
}
|
||||
|
||||
public static Dictionary<BlockFieldDescriptor, int> s_BlockMap = new Dictionary<BlockFieldDescriptor, int>()
|
||||
{
|
||||
{ BlockFields.SurfaceDescription.BaseColor, ShaderGraphVfxAsset.ColorSlotId },
|
||||
{ BlockFields.SurfaceDescription.Metallic, ShaderGraphVfxAsset.MetallicSlotId },
|
||||
{ BlockFields.SurfaceDescription.Smoothness, ShaderGraphVfxAsset.SmoothnessSlotId },
|
||||
{ BlockFields.SurfaceDescription.NormalTS, ShaderGraphVfxAsset.NormalSlotId },
|
||||
{ BlockFields.SurfaceDescription.Emission, ShaderGraphVfxAsset.EmissiveSlotId },
|
||||
{ BlockFields.SurfaceDescription.Alpha, ShaderGraphVfxAsset.AlphaSlotId },
|
||||
{ BlockFields.SurfaceDescription.AlphaClipThreshold, ShaderGraphVfxAsset.AlphaThresholdSlotId },
|
||||
};
|
||||
|
||||
public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary<BlockFieldDescriptor, int> blockMap)
|
||||
{
|
||||
blockMap = null;
|
||||
if (!(masterNode is VisualEffectMasterNode1 vfxMasterNode))
|
||||
return false;
|
||||
|
||||
lit = vfxMasterNode.m_Lit;
|
||||
alphaTest = vfxMasterNode.m_AlphaTest;
|
||||
|
||||
blockMap = new Dictionary<BlockFieldDescriptor, int>();
|
||||
if (lit)
|
||||
{
|
||||
blockMap.Add(BlockFields.SurfaceDescription.BaseColor, ShaderGraphVfxAsset.BaseColorSlotId);
|
||||
blockMap.Add(BlockFields.SurfaceDescription.Metallic, ShaderGraphVfxAsset.MetallicSlotId);
|
||||
blockMap.Add(BlockFields.SurfaceDescription.Smoothness, ShaderGraphVfxAsset.SmoothnessSlotId);
|
||||
blockMap.Add(BlockFields.SurfaceDescription.NormalTS, ShaderGraphVfxAsset.NormalSlotId);
|
||||
blockMap.Add(BlockFields.SurfaceDescription.Emission, ShaderGraphVfxAsset.EmissiveSlotId);
|
||||
}
|
||||
else
|
||||
{
|
||||
blockMap.Add(BlockFields.SurfaceDescription.BaseColor, ShaderGraphVfxAsset.ColorSlotId);
|
||||
}
|
||||
|
||||
blockMap.Add(BlockFields.SurfaceDescription.Alpha, ShaderGraphVfxAsset.AlphaSlotId);
|
||||
|
||||
if (alphaTest)
|
||||
{
|
||||
blockMap.Add(BlockFields.SurfaceDescription.AlphaClipThreshold, ShaderGraphVfxAsset.AlphaThresholdSlotId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool WorksWithSRP(RenderPipelineAsset scriptableRenderPipeline)
|
||||
{
|
||||
return GraphicsSettings.currentRenderPipeline != null && scriptableRenderPipeline?.GetType() == GraphicsSettings.currentRenderPipeline.GetType();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,57 @@
|
||||
SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input)
|
||||
{
|
||||
SurfaceDescriptionInputs output;
|
||||
ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
|
||||
|
||||
$SurfaceDescriptionInputs.WorldSpaceNormal: // must use interpolated tangent, bitangent and normal before they are normalized in the pixel shader.
|
||||
$SurfaceDescriptionInputs.WorldSpaceNormal: float3 unnormalizedNormalWS = input.normalWS;
|
||||
$SurfaceDescriptionInputs.WorldSpaceNormal: const float renormFactor = 1.0 / length(unnormalizedNormalWS);
|
||||
|
||||
$SurfaceDescriptionInputs.WorldSpaceBiTangent: // use bitangent on the fly like in hdrp
|
||||
$SurfaceDescriptionInputs.WorldSpaceBiTangent: // IMPORTANT! If we ever support Flip on double sided materials ensure bitangent and tangent are NOT flipped.
|
||||
$SurfaceDescriptionInputs.WorldSpaceBiTangent: float crossSign = (input.tangentWS.w > 0.0 ? 1.0 : -1.0) * GetOddNegativeScale();
|
||||
$SurfaceDescriptionInputs.WorldSpaceBiTangent: float3 bitang = crossSign * cross(input.normalWS.xyz, input.tangentWS.xyz);
|
||||
|
||||
$SurfaceDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = renormFactor*input.normalWS.xyz; // we want a unit length Normal Vector node in shader graph
|
||||
$SurfaceDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = normalize(mul(output.WorldSpaceNormal, (float3x3) UNITY_MATRIX_M)); // transposed multiplication by inverse matrix to handle normal scale
|
||||
$SurfaceDescriptionInputs.ViewSpaceNormal: output.ViewSpaceNormal = mul(output.WorldSpaceNormal, (float3x3) UNITY_MATRIX_I_V); // transposed multiplication by inverse matrix to handle normal scale
|
||||
$SurfaceDescriptionInputs.TangentSpaceNormal: output.TangentSpaceNormal = float3(0.0f, 0.0f, 1.0f);
|
||||
|
||||
$SurfaceDescriptionInputs.WorldSpaceTangent: // to preserve mikktspace compliance we use same scale renormFactor as was used on the normal.
|
||||
$SurfaceDescriptionInputs.WorldSpaceTangent: // This is explained in section 2.2 in "surface gradient based bump mapping framework"
|
||||
$SurfaceDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = renormFactor*input.tangentWS.xyz;
|
||||
$SurfaceDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = renormFactor*bitang;
|
||||
|
||||
$SurfaceDescriptionInputs.ObjectSpaceTangent: output.ObjectSpaceTangent = TransformWorldToObjectDir(output.WorldSpaceTangent);
|
||||
$SurfaceDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
|
||||
$SurfaceDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
|
||||
$SurfaceDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = TransformWorldToObjectDir(output.WorldSpaceBiTangent);
|
||||
$SurfaceDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
|
||||
$SurfaceDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
|
||||
$SurfaceDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = input.viewDirectionWS; //TODO: by default normalized in HD, but not in universal
|
||||
$SurfaceDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = TransformWorldToObjectDir(output.WorldSpaceViewDirection);
|
||||
$SurfaceDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = TransformWorldToViewDir(output.WorldSpaceViewDirection);
|
||||
$SurfaceDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
|
||||
$SurfaceDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = length(output.WorldSpaceViewDirection) * TransformWorldToTangent(output.WorldSpaceViewDirection, tangentSpaceTransform);
|
||||
$SurfaceDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = input.positionWS;
|
||||
$SurfaceDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = TransformWorldToObject(input.positionWS);
|
||||
$SurfaceDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = TransformWorldToView(input.positionWS);
|
||||
$SurfaceDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
|
||||
$SurfaceDescriptionInputs.AbsoluteWorldSpacePosition:output.AbsoluteWorldSpacePosition = GetAbsolutePositionWS(input.positionWS);
|
||||
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(input.positionWS), _ProjectionParams.x);
|
||||
$SurfaceDescriptionInputs.uv0: output.uv0 = input.texCoord0;
|
||||
$SurfaceDescriptionInputs.uv1: output.uv1 = input.texCoord1;
|
||||
$SurfaceDescriptionInputs.uv2: output.uv2 = input.texCoord2;
|
||||
$SurfaceDescriptionInputs.uv3: output.uv3 = input.texCoord3;
|
||||
$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
|
||||
$SurfaceDescriptionInputs.TimeParameters: output.TimeParameters = _TimeParameters.xyz; // This is mainly for LW as HD overwrite this value
|
||||
#if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
|
||||
#define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN output.FaceSign = IS_FRONT_VFACE(input.cullFace, true, false);
|
||||
#else
|
||||
#define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
|
||||
#endif
|
||||
$SurfaceDescriptionInputs.FaceSign: BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
|
||||
#undef BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
|
||||
|
||||
return output;
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
VertexDescriptionInputs BuildVertexDescriptionInputs(Attributes input)
|
||||
{
|
||||
VertexDescriptionInputs output;
|
||||
ZERO_INITIALIZE(VertexDescriptionInputs, output);
|
||||
|
||||
$VertexDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = input.normalOS;
|
||||
$VertexDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = TransformObjectToWorldNormal(input.normalOS);
|
||||
$VertexDescriptionInputs.ViewSpaceNormal: output.ViewSpaceNormal = TransformWorldToViewDir(output.WorldSpaceNormal);
|
||||
$VertexDescriptionInputs.TangentSpaceNormal: output.TangentSpaceNormal = float3(0.0f, 0.0f, 1.0f);
|
||||
$VertexDescriptionInputs.ObjectSpaceTangent: output.ObjectSpaceTangent = input.tangentOS.xyz;
|
||||
$VertexDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = TransformObjectToWorldDir(input.tangentOS.xyz);
|
||||
$VertexDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
|
||||
$VertexDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
|
||||
$VertexDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = normalize(cross(input.normalOS, input.tangentOS) * (input.tangentOS.w > 0.0f ? 1.0f : -1.0f) * GetOddNegativeScale());
|
||||
$VertexDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = TransformObjectToWorldDir(output.ObjectSpaceBiTangent);
|
||||
$VertexDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
|
||||
$VertexDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
|
||||
$VertexDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = input.positionOS;
|
||||
$VertexDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = TransformObjectToWorld(input.positionOS);
|
||||
$VertexDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = TransformWorldToView(output.WorldSpacePosition);
|
||||
$VertexDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
|
||||
$VertexDescriptionInputs.AbsoluteWorldSpacePosition:output.AbsoluteWorldSpacePosition = GetAbsolutePositionWS(TransformObjectToWorld(input.positionOS));
|
||||
$VertexDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = GetWorldSpaceNormalizeViewDir(output.WorldSpacePosition);
|
||||
$VertexDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = TransformWorldToObjectDir(output.WorldSpaceViewDirection);
|
||||
$VertexDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = length(output.WorldSpaceViewDirection) * TransformWorldToViewDir(output.WorldSpaceViewDirection);
|
||||
$VertexDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
|
||||
$VertexDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = TransformWorldToTangent(output.WorldSpaceViewDirection, tangentSpaceTransform);
|
||||
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(output.WorldSpacePosition), _ProjectionParams.x);
|
||||
$VertexDescriptionInputs.uv0: output.uv0 = input.uv0;
|
||||
$VertexDescriptionInputs.uv1: output.uv1 = input.uv1;
|
||||
$VertexDescriptionInputs.uv2: output.uv2 = input.uv2;
|
||||
$VertexDescriptionInputs.uv3: output.uv3 = input.uv3;
|
||||
$VertexDescriptionInputs.VertexColor: output.VertexColor = input.color;
|
||||
$VertexDescriptionInputs.TimeParameters: output.TimeParameters = _TimeParameters.xyz;
|
||||
$VertexDescriptionInputs.BoneWeights: output.BoneWeights = input.weights;
|
||||
$VertexDescriptionInputs.BoneIndices: output.BoneIndices = input.indices;
|
||||
$VertexDescriptionInputs.VertexID: output.VertexID = input.vertexID;
|
||||
|
||||
return output;
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
Pass
|
||||
{
|
||||
$splice(PassName)
|
||||
Tags
|
||||
{
|
||||
$splice(LightMode)
|
||||
}
|
||||
|
||||
// Render State
|
||||
$splice(RenderState)
|
||||
|
||||
// Debug
|
||||
$splice(Debug)
|
||||
|
||||
// --------------------------------------------------
|
||||
// Pass
|
||||
|
||||
HLSLPROGRAM
|
||||
|
||||
// Pragmas
|
||||
$splice(PassPragmas)
|
||||
|
||||
$splice(DotsInstancingOptions)
|
||||
$splice(HybridV1InjectedBuiltinProperties)
|
||||
|
||||
// Keywords
|
||||
$splice(PassKeywords)
|
||||
$splice(GraphKeywords)
|
||||
|
||||
// Defines
|
||||
$SurfaceType.Transparent: #define _SURFACE_TYPE_TRANSPARENT 1
|
||||
$AlphaClip: #define _AlphaClip 1
|
||||
$Normal: #define _NORMALMAP 1
|
||||
$SpecularSetup: #define _SPECULAR_SETUP
|
||||
$BlendMode.Add: #define _BLENDMODE_ADD 1
|
||||
$BlendMode.Premultiply: #define _ALPHAPREMULTIPLY_ON 1
|
||||
$NormalDropOffTS: #define _NORMAL_DROPOFF_TS 1
|
||||
$NormalDropOffOS: #define _NORMAL_DROPOFF_OS 1
|
||||
$NormalDropOffWS: #define _NORMAL_DROPOFF_WS 1
|
||||
$Attributes.normalOS: #define ATTRIBUTES_NEED_NORMAL
|
||||
$Attributes.tangentOS: #define ATTRIBUTES_NEED_TANGENT
|
||||
$Attributes.uv0: #define ATTRIBUTES_NEED_TEXCOORD0
|
||||
$Attributes.uv1: #define ATTRIBUTES_NEED_TEXCOORD1
|
||||
$Attributes.uv2: #define ATTRIBUTES_NEED_TEXCOORD2
|
||||
$Attributes.uv3: #define ATTRIBUTES_NEED_TEXCOORD3
|
||||
$Attributes.color: #define ATTRIBUTES_NEED_COLOR
|
||||
$Varyings.positionWS: #define VARYINGS_NEED_POSITION_WS
|
||||
$Varyings.normalWS: #define VARYINGS_NEED_NORMAL_WS
|
||||
$Varyings.tangentWS: #define VARYINGS_NEED_TANGENT_WS
|
||||
$Varyings.texCoord0: #define VARYINGS_NEED_TEXCOORD0
|
||||
$Varyings.texCoord1: #define VARYINGS_NEED_TEXCOORD1
|
||||
$Varyings.texCoord2: #define VARYINGS_NEED_TEXCOORD2
|
||||
$Varyings.texCoord3: #define VARYINGS_NEED_TEXCOORD3
|
||||
$Varyings.color: #define VARYINGS_NEED_COLOR
|
||||
$Varyings.viewDirectionWS: #define VARYINGS_NEED_VIEWDIRECTION_WS
|
||||
$Varyings.bitangentWS: #define VARYINGS_NEED_BITANGENT_WS
|
||||
$Varyings.screenPosition: #define VARYINGS_NEED_SCREENPOSITION
|
||||
$Varyings.fogFactorAndVertexLight: #define VARYINGS_NEED_FOG_AND_VERTEX_LIGHT
|
||||
$Varyings.cullFace: #define VARYINGS_NEED_CULLFACE
|
||||
$features.graphVertex: #define FEATURES_GRAPH_VERTEX
|
||||
$Universal.UseLegacySpriteBlocks: #define UNIVERSAL_USELEGACYSPRITEBLOCKS
|
||||
$splice(PassInstancing)
|
||||
$splice(GraphDefines)
|
||||
$splice(DotsInstancingVars)
|
||||
|
||||
// Includes
|
||||
$splice(PreGraphIncludes)
|
||||
|
||||
// --------------------------------------------------
|
||||
// Structs and Packing
|
||||
|
||||
$splice(PassStructs)
|
||||
|
||||
$splice(InterpolatorPack)
|
||||
|
||||
// --------------------------------------------------
|
||||
// Graph
|
||||
|
||||
// Graph Properties
|
||||
$splice(GraphProperties)
|
||||
|
||||
// Graph Functions
|
||||
$splice(GraphFunctions)
|
||||
|
||||
// Graph Vertex
|
||||
$splice(GraphVertex)
|
||||
|
||||
// Graph Pixel
|
||||
$splice(GraphPixel)
|
||||
|
||||
// --------------------------------------------------
|
||||
// Build Graph Inputs
|
||||
|
||||
$features.graphVertex: $include("BuildVertexDescriptionInputs.template.hlsl")
|
||||
$features.graphPixel: $include("BuildSurfaceDescriptionInputs.template.hlsl")
|
||||
|
||||
// --------------------------------------------------
|
||||
// Main
|
||||
|
||||
$splice(PostGraphIncludes)
|
||||
|
||||
ENDHLSL
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class TargetUtils
|
||||
{
|
||||
public static void ProcessSubTargetList(ref JsonData<SubTarget> activeSubTarget, ref List<SubTarget> subTargets)
|
||||
{
|
||||
if (subTargets == null || subTargets.Count == 0)
|
||||
return;
|
||||
|
||||
// assign the initial sub-target, if none is assigned yet
|
||||
if (activeSubTarget.value == null)
|
||||
{
|
||||
// this is a bit of a hack: prefer subtargets named "Lit" if they exist, otherwise default to the first one
|
||||
// in the future, we should make the default sub-target user configurable
|
||||
var litSubTarget = subTargets.FirstOrDefault(x => x.displayName == "Lit");
|
||||
if (litSubTarget != null)
|
||||
activeSubTarget = litSubTarget;
|
||||
else
|
||||
activeSubTarget = subTargets[0];
|
||||
return;
|
||||
}
|
||||
|
||||
// Update SubTarget list with active SubTarget
|
||||
var activeSubTargetType = activeSubTarget.value.GetType();
|
||||
var activeSubTargetCurrent = subTargets.FirstOrDefault(x => x.GetType() == activeSubTargetType);
|
||||
var index = subTargets.IndexOf(activeSubTargetCurrent);
|
||||
subTargets[index] = activeSubTarget;
|
||||
}
|
||||
|
||||
public static List<SubTarget> GetSubTargets<T>(T target) where T : Target
|
||||
{
|
||||
// Get Variants
|
||||
var subTargets = ListPool<SubTarget>.Get();
|
||||
var typeCollection = TypeCache.GetTypesDerivedFrom<SubTarget>();
|
||||
foreach (var type in typeCollection)
|
||||
{
|
||||
if (type.IsAbstract || !type.IsClass)
|
||||
continue;
|
||||
|
||||
var subTarget = (SubTarget)Activator.CreateInstance(type);
|
||||
if (!subTarget.isHidden && subTarget.targetType.Equals(typeof(T)))
|
||||
{
|
||||
subTarget.target = target;
|
||||
subTargets.Add(subTarget);
|
||||
}
|
||||
}
|
||||
|
||||
return subTargets;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user