initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,120 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
using UnityEditor.ShaderGraph.Drawing.Controls;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Calculate Level Of Detail Texture 2D")]
class CalculateLevelOfDetailTexture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
[SerializeField]
bool m_Clamp = true;
[ToggleControl]
public ToggleData clamp
{
get => new ToggleData(m_Clamp);
set
{
m_Clamp = value.isOn;
Dirty(ModificationScope.Node);
}
}
public const int OutputSlotLODId = 0;
public const int TextureInputId = 1;
public const int UVInput = 2;
public const int SamplerInput = 3;
const string kOutputSlotLODName = "LOD";
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
public override bool hasPreview { get { return true; } }
public CalculateLevelOfDetailTexture2DNode()
{
name = "Calculate Level Of Detail Texture 2D";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector1MaterialSlot(OutputSlotLODId, kOutputSlotLODName, kOutputSlotLODName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0));
AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
RemoveSlotsNameNotMatching(new[] { OutputSlotLODId, TextureInputId, UVInput, SamplerInput });
}
public override void Setup()
{
base.Setup();
var textureSlot = FindInputSlot<Texture2DInputMaterialSlot>(TextureInputId);
textureSlot.defaultType = Texture2DShaderProperty.DefaultType.White;
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
var uvName = GetSlotValue(UVInput, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var id = GetSlotValue(TextureInputId, generationMode);
sb.AppendLine("#if (SHADER_TARGET >= 41)");
{
var func = m_Clamp ? "CalculateLevelOfDetail" : "CalculateLevelOfDetailUnclamped";
sb.AppendLine(string.Format("$precision {0} = {1}.tex.{2}({3}.samplerstate, {4});"
, GetVariableNameForSlot(OutputSlotLODId)
, id
, func
, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id
, uvName));
}
sb.AppendLine("#else");
{
var dUVdx = string.Format("ddx({0} * {1}.texelSize.zw)", uvName, id);
var dUVdy = string.Format("ddy({0} * {1}.texelSize.zw)", uvName, id);
var delta_max_sqr = string.Format("max(dot({0}, {0}), dot({1}, {1}))", dUVdx, dUVdy);
sb.AppendLine(string.Format("$precision {0};", GetVariableNameForSlot(OutputSlotLODId)));
sb.AppendLine(string.Format("{0} = 0.5f*log2({1});", GetVariableNameForSlot(OutputSlotLODId), delta_max_sqr));
sb.AppendLine(string.Format("{0} = max({0}, 0);", GetVariableNameForSlot(OutputSlotLODId)));
if (m_Clamp)
{
sb.AppendLine("#if defined(MIP_COUNT_SUPPORTED)");
sb.AppendLine(string.Format("{0} = min({0}, GetMipCount(TEXTURE2D_ARGS({1}.tex, {2}.samplerstate))-1);", GetVariableNameForSlot(OutputSlotLODId), id, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id));
sb.AppendLine("#endif");
}
}
sb.AppendLine("#endif");
}
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
{
using (var tempSlots = PooledList<MaterialSlot>.Get())
{
GetInputSlots(tempSlots);
var result = false;
foreach (var slot in tempSlots)
{
if (slot.RequiresMeshUV(channel))
{
result = true;
break;
}
}
tempSlots.Clear();
return result;
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 03cdc5d395730c74ebabff3988c5110d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,100 @@
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Cubemap Asset")]
[HasDependencies(typeof(MinimalCubemapAssetNode))]
class CubemapAssetNode : AbstractMaterialNode, IPropertyFromNode
{
public const int OutputSlotId = 0;
const string kOutputSlotName = "Out";
public CubemapAssetNode()
{
name = "Cubemap Asset";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new CubemapMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
[SerializeField]
private SerializableCubemap m_Cubemap = new SerializableCubemap();
[CubemapControl("")]
public Cubemap cubemap
{
get { return m_Cubemap.cubemap; }
set
{
if (m_Cubemap.cubemap == value)
return;
m_Cubemap.cubemap = value;
Dirty(ModificationScope.Node);
}
}
string GetTexturePropertyName()
{
return base.GetVariableNameForSlot(OutputSlotId);
}
public override string GetVariableNameForSlot(int slotId)
{
return $"UnityBuildTextureCubeStruct({GetTexturePropertyName()})";
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new CubemapShaderProperty()
{
overrideReferenceName = GetTexturePropertyName(),
generatePropertyBlock = true,
value = m_Cubemap,
modifiable = false
});
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty(PropertyType.Cubemap)
{
name = GetTexturePropertyName(),
cubemapValue = cubemap
});
}
public AbstractShaderProperty AsShaderProperty()
{
var prop = new CubemapShaderProperty { value = m_Cubemap };
if (cubemap != null)
prop.displayName = cubemap.name;
return prop;
}
public int outputSlotId { get { return OutputSlotId; } }
}
class MinimalCubemapAssetNode : IHasDependencies
{
[SerializeField]
private SerializableCubemap m_Cubemap = null;
public void GetSourceAssetDependencies(AssetCollection assetCollection)
{
var guidString = m_Cubemap.guid;
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
{
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 968ed0a541658844486b1ac5ab57ee2d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,131 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Gather Texture 2D")]
class GatherTexture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotRGBAId = 0;
public const int OutputSlotRId = 5;
public const int OutputSlotGId = 6;
public const int OutputSlotBId = 7;
public const int OutputSlotAId = 8;
public const int TextureInputId = 1;
public const int UVInput = 2;
public const int SamplerInput = 3;
public const int OffsetInput = 4;
const string kOutputSlotRGBAName = "RGBA";
const string kOutputSlotRName = "R";
const string kOutputSlotGName = "G";
const string kOutputSlotBName = "B";
const string kOutputSlotAName = "A";
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
const string kOffsetInputName = "Offset";
public override bool hasPreview { get { return true; } }
public GatherTexture2DNode()
{
name = "Gather Texture 2D";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, Vector4.zero, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0));
AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
AddSlot(new Vector2MaterialSlot(OffsetInput, kOffsetInputName, kOffsetInputName, SlotType.Input, Vector2.zero, ShaderStageCapability.All, null, null, false, true));
RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, UVInput, SamplerInput, OffsetInput });
}
public override void Setup()
{
base.Setup();
var textureSlot = FindInputSlot<Texture2DInputMaterialSlot>(TextureInputId);
textureSlot.defaultType = Texture2DShaderProperty.DefaultType.White;
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
var uvName = GetSlotValue(UVInput, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var id = GetSlotValue(TextureInputId, generationMode);
var offset = GetSlotValue(OffsetInput, generationMode);
sb.AppendLine("#if (SHADER_TARGET >= 41)");
{
sb.AppendLine(string.Format("$precision4 {0} = {1}.tex.Gather({2}.samplerstate, {3}, {4});"
, GetVariableNameForSlot(OutputSlotRGBAId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id
, uvName
, offset));
sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)));
}
sb.AppendLine("#else");
{
// Gather offsets defined in this order:
// (-,+),(+,+),(+,-),(-,-)
var uvR = string.Format("(floor({0} * {1}.texelSize.zw + $precision2(-0.5, 0.5)) + trunc({2}) + $precision2(0.5, 0.5)) * {1}.texelSize.xy", uvName, id, offset);
var uvG = string.Format("(floor({0} * {1}.texelSize.zw + $precision2(0.5, 0.5)) + trunc({2}) + $precision2(0.5, 0.5)) * {1}.texelSize.xy", uvName, id, offset);
var uvB = string.Format("(floor({0} * {1}.texelSize.zw + $precision2(0.5, -0.5)) + trunc({2}) + $precision2(0.5, 0.5)) * {1}.texelSize.xy", uvName, id, offset);
var uvA = string.Format("(floor({0} * {1}.texelSize.zw + $precision2(-0.5, -0.5)) + trunc({2}) + $precision2(0.5, 0.5)) * {1}.texelSize.xy", uvName, id, offset);
sb.AppendLine(string.Format("$precision {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {3}, 0).r;", GetVariableNameForSlot(OutputSlotRId), id, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id, uvR));
sb.AppendLine(string.Format("$precision {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {3}, 0).r;", GetVariableNameForSlot(OutputSlotGId), id, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id, uvG));
sb.AppendLine(string.Format("$precision {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {3}, 0).r;", GetVariableNameForSlot(OutputSlotBId), id, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id, uvB));
sb.AppendLine(string.Format("$precision {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {3}, 0).r;", GetVariableNameForSlot(OutputSlotAId), id, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id, uvA));
sb.AppendLine(string.Format("$precision4 {0} = $precision4({1},{2},{3},{4});"
, GetVariableNameForSlot(OutputSlotRGBAId)
, GetVariableNameForSlot(OutputSlotRId)
, GetVariableNameForSlot(OutputSlotGId)
, GetVariableNameForSlot(OutputSlotBId)
, GetVariableNameForSlot(OutputSlotAId)));
}
sb.AppendLine("#endif");
}
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
{
using (var tempSlots = PooledList<MaterialSlot>.Get())
{
GetInputSlots(tempSlots);
var result = false;
foreach (var slot in tempSlots)
{
if (slot.RequiresMeshUV(channel))
{
result = true;
break;
}
}
tempSlots.Clear();
return result;
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e52355d9fc877154b9403531b2837081
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,136 @@
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
#if PROCEDURAL_VT_IN_GRAPH
[Title("Input", "Texture", "Procedural Virtual Texture")]
class ProceduralVirtualTextureNode : AbstractMaterialNode
{
public const int OutputSlotId = 0;
const string kOutputSlotName = "Out";
public ProceduralVirtualTextureNode()
{
UpdateNodeAfterDeserialization();
SetLayerCount(2);
vtProperty.displayName = "ProceduralVirtualTexture";
vtProperty.overrideReferenceName = "MyPVT";
vtProperty.value.procedural = true;
vtProperty.value.shaderDeclaration = HLSLDeclaration.UnityPerMaterial;
UpdateName();
}
void UpdateName()
{
name = "Procedural Virtual Texture: " + vtProperty.overrideReferenceName;
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new VirtualTextureMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
SetLayerCount(layers);
vtProperty.generatePropertyBlock = true;
vtProperty.hidden = true;
}
public override int latestVersion => 1;
public override void OnAfterMultiDeserialize(string json)
{
if (sgVersion == 0)
{
// version 0 was implicitly declaring PVT stacks as Global shader properties
shaderDeclaration = HLSLDeclaration.Global;
ChangeVersion(1);
}
}
[SerializeField]
private VirtualTextureShaderProperty vtProperty = new VirtualTextureShaderProperty();
void SetLayerCount(int layers)
{
var uniqueName = objectId;
vtProperty.value.layers.Clear();
layers = System.Math.Max(System.Math.Min(layers, SampleVirtualTextureNode.kMaxLayers), SampleVirtualTextureNode.kMinLayers);
for (int x = 0; x < layers; x++)
{
vtProperty.value.layers.Add(new SerializableVirtualTextureLayer("Layer" + x + "_" + uniqueName, "Layer" + x + "_" + uniqueName, null));
}
}
[IdentifierControl("Name")]
public string vtName
{
get { return vtProperty.overrideReferenceName; }
set
{
if (vtProperty.overrideReferenceName == value)
return;
vtProperty.overrideReferenceName = value;
UpdateName();
Dirty(ModificationScope.Graph);
}
}
[IntegerControl("Layers")]
public int layers
{
get { return vtProperty.value.layers.Count; }
set
{
if (vtProperty.value.layers.Count == value)
return;
SetLayerCount(value);
Dirty(ModificationScope.Topological);
//Hack to handle downstream SampleVirtualTextureNodes
owner.ValidateGraph();
}
}
internal HLSLDeclaration shaderDeclaration
{
get { return vtProperty.value.shaderDeclaration; }
set
{
if (vtProperty.value.shaderDeclaration == value)
return;
vtProperty.value.shaderDeclaration = value;
Dirty(ModificationScope.Graph);
}
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(vtProperty);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty(PropertyType.VirtualTexture)
{
name = GetVariableNameForSlot(OutputSlotId),
vtProperty = vtProperty
});
}
public AbstractShaderProperty AsShaderProperty()
{
return vtProperty;
}
// to show Shader Declaration in the node settings, as if this node was itself a real AbstractShaderProperty
internal bool AllowHLSLDeclaration(HLSLDeclaration decl) =>
(decl == HLSLDeclaration.Global || decl == HLSLDeclaration.UnityPerMaterial);
}
#endif // PROCEDURAL_VT_IN_GRAPH
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 49a3a90a50f5fbf4ba608b8e4afe373a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,91 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[FormerName("UnityEditor.ShaderGraph.CubemapNode")]
[Title("Input", "Texture", "Sample Reflected Cubemap")]
class SampleCubemapNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireViewDirection, IMayRequireNormal
{
public const int OutputSlotId = 0;
public const int CubemapInputId = 1;
public const int ViewDirInputId = 2;
public const int NormalInputId = 3;
public const int SamplerInputId = 5;
public const int LODInputId = 4;
const string kOutputSlotName = "Out";
const string kCubemapInputName = "Cube";
const string kViewDirInputName = "ViewDir";
const string kNormalInputName = "Normal";
const string kSamplerInputName = "Sampler";
const string kLODInputName = "LOD";
public override bool hasPreview { get { return true; } }
public SampleCubemapNode()
{
name = "Sample Reflected Cubemap";
m_PreviewMode = PreviewMode.Preview3D;
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new CubemapInputMaterialSlot(CubemapInputId, kCubemapInputName, kCubemapInputName));
AddSlot(new ViewDirectionMaterialSlot(ViewDirInputId, kViewDirInputName, kViewDirInputName, CoordinateSpace.Object));
AddSlot(new NormalMaterialSlot(NormalInputId, kNormalInputName, kNormalInputName, CoordinateSpace.Object));
AddSlot(new SamplerStateMaterialSlot(SamplerInputId, kSamplerInputName, kSamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(LODInputId, kLODInputName, kLODInputName, SlotType.Input, 0));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, CubemapInputId, ViewDirInputId, NormalInputId, SamplerInputId, LODInputId });
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInputId);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var id = GetSlotValue(CubemapInputId, generationMode);
string result = string.Format("$precision4 {0} = SAMPLE_TEXTURECUBE_LOD({1}.tex, {2}.samplerstate, reflect(-{3}, {4}), {5});"
, GetVariableNameForSlot(OutputSlotId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : id
, GetSlotValue(ViewDirInputId, generationMode)
, GetSlotValue(NormalInputId, generationMode)
, GetSlotValue(LODInputId, generationMode));
sb.AppendLine(result);
}
public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCapability)
{
var viewDirSlot = FindInputSlot<MaterialSlot>(ViewDirInputId);
var edgesViewDir = owner.GetEdges(viewDirSlot.slotReference);
if (!edgesViewDir.Any())
return CoordinateSpace.Object.ToNeededCoordinateSpace();
else
return NeededCoordinateSpace.None;
}
public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability)
{
var normalSlot = FindInputSlot<MaterialSlot>(NormalInputId);
var edgesNormal = owner.GetEdges(normalSlot.slotReference);
if (!edgesNormal.Any())
return CoordinateSpace.Object.ToNeededCoordinateSpace();
else
return NeededCoordinateSpace.None;
}
public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();
name = "Sample Reflected Cubemap";
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6eaeb9c846408f74daeadcc3314810e4
timeCreated: 1495637741
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,76 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Sample Cubemap")]
class SampleRawCubemapNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireNormal
{
public const int OutputSlotId = 0;
public const int CubemapInputId = 1;
public const int NormalInputId = 2;
public const int SamplerInputId = 3;
public const int LODInputId = 4;
const string kOutputSlotName = "Out";
const string kCubemapInputName = "Cube";
const string kNormalInputName = "Dir";
const string kSamplerInputName = "Sampler";
const string kLODInputName = "LOD";
public override bool hasPreview { get { return true; } }
public SampleRawCubemapNode()
{
name = "Sample Cubemap";
m_PreviewMode = PreviewMode.Preview3D;
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new CubemapInputMaterialSlot(CubemapInputId, kCubemapInputName, kCubemapInputName));
AddSlot(new NormalMaterialSlot(NormalInputId, kNormalInputName, kNormalInputName, CoordinateSpace.World));
AddSlot(new SamplerStateMaterialSlot(SamplerInputId, kSamplerInputName, kSamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(LODInputId, kLODInputName, kLODInputName, SlotType.Input, 0));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, CubemapInputId, NormalInputId, SamplerInputId, LODInputId });
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInputId);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var id = GetSlotValue(CubemapInputId, generationMode);
string result = string.Format("$precision4 {0} = SAMPLE_TEXTURECUBE_LOD({1}.tex, {2}.samplerstate, {3}, {4});"
, GetVariableNameForSlot(OutputSlotId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : id
, GetSlotValue(NormalInputId, generationMode)
, GetSlotValue(LODInputId, generationMode));
sb.AppendLine(result);
}
public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability)
{
var normalSlot = FindInputSlot<MaterialSlot>(NormalInputId);
var edgesNormal = owner.GetEdges(normalSlot.slotReference);
if (!edgesNormal.Any())
return CoordinateSpace.World.ToNeededCoordinateSpace();
else
return NeededCoordinateSpace.None;
}
public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();
name = "Sample Cubemap";
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1790cabd561426148b5f93f010b5b046
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,112 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Sample Texture 2D Array")]
class SampleTexture2DArrayNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotRGBAId = 0;
public const int OutputSlotRId = 4;
public const int OutputSlotGId = 5;
public const int OutputSlotBId = 6;
public const int OutputSlotAId = 7;
public const int TextureInputId = 1;
public const int UVInput = 2;
public const int SamplerInput = 3;
public const int IndexInputId = 8;
const string kOutputSlotRGBAName = "RGBA";
const string kOutputSlotRName = "R";
const string kOutputSlotGName = "G";
const string kOutputSlotBName = "B";
const string kOutputSlotAName = "A";
const string kTextureInputName = "Texture Array";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
const string kIndexInputName = "Index";
const string kDefaultSampleMacro = "SAMPLE_TEXTURE2D_ARRAY";
const string kSampleMacroNoBias = "PLATFORM_SAMPLE_TEXTURE2D_ARRAY";
public override bool hasPreview { get { return true; } }
public SampleTexture2DArrayNode()
{
name = "Sample Texture 2D Array";
synonyms = new string[] { "stack", "pile" };
UpdateNodeAfterDeserialization();
}
[SerializeField]
private bool m_EnableGlobalMipBias = false;
internal bool enableGlobalMipBias
{
set { m_EnableGlobalMipBias = value; }
get { return m_EnableGlobalMipBias; }
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, Vector4.zero, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Texture2DArrayInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new Vector1MaterialSlot(IndexInputId, kIndexInputName, kIndexInputName, SlotType.Input, 0));
AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0));
AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, IndexInputId, UVInput, SamplerInput });
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
var uvName = GetSlotValue(UVInput, generationMode);
var indexName = GetSlotValue(IndexInputId, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var id = GetSlotValue(TextureInputId, generationMode);
var result = string.Format("$precision4 {0} = {1}({2}.tex, {3}.samplerstate, {4}, {5});"
, GetVariableNameForSlot(OutputSlotRGBAId)
, m_EnableGlobalMipBias ? kDefaultSampleMacro : kSampleMacroNoBias
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id
, uvName
, indexName);
sb.AppendLine(result);
sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)));
}
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
{
using (var tempSlots = PooledList<MaterialSlot>.Get())
{
GetInputSlots(tempSlots);
var result = false;
foreach (var slot in tempSlots)
{
if (slot.RequiresMeshUV(channel))
{
result = true;
break;
}
}
tempSlots.Clear();
return result;
}
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0789ef77e28f0406dbb0970c5a8e7a2c
timeCreated: 1495637741
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,167 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Sample Texture 2D LOD")]
class SampleTexture2DLODNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotRGBAId = 0;
public const int OutputSlotRId = 5;
public const int OutputSlotGId = 6;
public const int OutputSlotBId = 7;
public const int OutputSlotAId = 8;
public const int TextureInputId = 1;
public const int UVInputId = 2;
public const int SamplerInputId = 3;
public const int LODInputId = 4;
const string kOutputSlotRGBAName = "RGBA";
const string kOutputSlotRName = "R";
const string kOutputSlotGName = "G";
const string kOutputSlotBName = "B";
const string kOutputSlotAName = "A";
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
const string kLODInputName = "LOD";
public override bool hasPreview { get { return true; } }
public SampleTexture2DLODNode()
{
name = "Sample Texture 2D LOD";
UpdateNodeAfterDeserialization();
}
[SerializeField]
private TextureType m_TextureType = TextureType.Default;
[EnumControl("Type")]
public TextureType textureType
{
get { return m_TextureType; }
set
{
if (m_TextureType == value)
return;
m_TextureType = value;
Dirty(ModificationScope.Graph);
ValidateNode();
}
}
[SerializeField]
private NormalMapSpace m_NormalMapSpace = NormalMapSpace.Tangent;
[EnumControl("Space")]
public NormalMapSpace normalMapSpace
{
get { return m_NormalMapSpace; }
set
{
if (m_NormalMapSpace == value)
return;
m_NormalMapSpace = value;
Dirty(ModificationScope.Graph);
}
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, Vector4.zero, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInputId, kUVInputName, kUVInputName, UVChannel.UV0));
AddSlot(new SamplerStateMaterialSlot(SamplerInputId, kSamplerInputName, kSamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(LODInputId, kLODInputName, kLODInputName, SlotType.Input, 0));
RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, UVInputId, SamplerInputId, LODInputId });
}
public override void Setup()
{
base.Setup();
var textureSlot = FindInputSlot<Texture2DInputMaterialSlot>(TextureInputId);
textureSlot.defaultType = (textureType == TextureType.Normal ? Texture2DShaderProperty.DefaultType.NormalMap : Texture2DShaderProperty.DefaultType.White);
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
var uvName = GetSlotValue(UVInputId, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInputId);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var lodSlot = GetSlotValue(LODInputId, generationMode);
var id = GetSlotValue(TextureInputId, generationMode);
// GLES2 does not always support LOD sampling
sb.AppendLine("#if defined(SHADER_API_GLES) && (SHADER_TARGET < 30)");
{
sb.AppendLine(" $precision4 {0} = $precision4(0.0f, 0.0f, 0.0f, 1.0f);", GetVariableNameForSlot(OutputSlotRGBAId));
}
sb.AppendLine("#else");
{
var result = string.Format(" $precision4 {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {1}.GetTransformedUV({3}), {4});"
, GetVariableNameForSlot(OutputSlotRGBAId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : id
, uvName
, lodSlot);
sb.AppendLine(result);
}
sb.AppendLine("#endif");
if (textureType == TextureType.Normal)
{
if (normalMapSpace == NormalMapSpace.Tangent)
{
sb.AppendLine(string.Format("{0}.rgb = UnpackNormal({0});", GetVariableNameForSlot(OutputSlotRGBAId)));
}
else
{
sb.AppendLine(string.Format("{0}.rgb = UnpackNormalRGB({0});", GetVariableNameForSlot(OutputSlotRGBAId)));
}
}
sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)));
}
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
{
var result = false;
using (var tempSlots = PooledList<MaterialSlot>.Get())
{
GetInputSlots(tempSlots);
foreach (var slot in tempSlots)
{
if (slot.RequiresMeshUV(channel))
{
result = true;
break;
}
}
}
return result;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 64b637768540cce4f83b9b10cdcacd23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,171 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
enum TextureType
{
Default,
Normal
};
[FormerName("UnityEditor.ShaderGraph.Texture2DNode")]
[Title("Input", "Texture", "Sample Texture 2D")]
class SampleTexture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotRGBAId = 0;
public const int OutputSlotRId = 4;
public const int OutputSlotGId = 5;
public const int OutputSlotBId = 6;
public const int OutputSlotAId = 7;
public const int TextureInputId = 1;
public const int UVInput = 2;
public const int SamplerInput = 3;
const string kOutputSlotRGBAName = "RGBA";
const string kOutputSlotRName = "R";
const string kOutputSlotGName = "G";
const string kOutputSlotBName = "B";
const string kOutputSlotAName = "A";
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
const string kDefaultSampleMacro = "SAMPLE_TEXTURE2D";
const string kSampleMacroNoBias = "PLATFORM_SAMPLE_TEXTURE2D";
public override bool hasPreview { get { return true; } }
public SampleTexture2DNode()
{
name = "Sample Texture 2D";
UpdateNodeAfterDeserialization();
}
[SerializeField]
private TextureType m_TextureType = TextureType.Default;
[EnumControl("Type")]
public TextureType textureType
{
get { return m_TextureType; }
set
{
if (m_TextureType == value)
return;
m_TextureType = value;
Dirty(ModificationScope.Graph);
ValidateNode();
}
}
[SerializeField]
private NormalMapSpace m_NormalMapSpace = NormalMapSpace.Tangent;
[EnumControl("Space")]
public NormalMapSpace normalMapSpace
{
get { return m_NormalMapSpace; }
set
{
if (m_NormalMapSpace == value)
return;
m_NormalMapSpace = value;
Dirty(ModificationScope.Graph);
}
}
[SerializeField]
private bool m_EnableGlobalMipBias = true;
internal bool enableGlobalMipBias
{
set { m_EnableGlobalMipBias = value; }
get { return m_EnableGlobalMipBias; }
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, Vector4.zero, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0, ShaderStageCapability.Fragment));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0));
AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, UVInput, SamplerInput });
}
public override void Setup()
{
base.Setup();
var textureSlot = FindInputSlot<Texture2DInputMaterialSlot>(TextureInputId);
textureSlot.defaultType = (textureType == TextureType.Normal ? Texture2DShaderProperty.DefaultType.NormalMap : Texture2DShaderProperty.DefaultType.White);
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
var uvName = GetSlotValue(UVInput, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var id = GetSlotValue(TextureInputId, generationMode);
var result = string.Format("$precision4 {0} = {1}({2}.tex, {3}.samplerstate, {2}.GetTransformedUV({4}));"
, GetVariableNameForSlot(OutputSlotRGBAId)
, m_EnableGlobalMipBias ? kDefaultSampleMacro : kSampleMacroNoBias
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id
, uvName);
sb.AppendLine(result);
if (textureType == TextureType.Normal)
{
if (normalMapSpace == NormalMapSpace.Tangent)
{
sb.AppendLine(string.Format("{0}.rgb = UnpackNormal({0});", GetVariableNameForSlot(OutputSlotRGBAId)));
}
else
{
sb.AppendLine(string.Format("{0}.rgb = UnpackNormalRGB({0});", GetVariableNameForSlot(OutputSlotRGBAId)));
}
}
sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)));
}
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
{
using (var tempSlots = PooledList<MaterialSlot>.Get())
{
GetInputSlots(tempSlots);
var result = false;
foreach (var slot in tempSlots)
{
if (slot.RequiresMeshUV(channel))
{
result = true;
break;
}
}
tempSlots.Clear();
return result;
}
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5ca9d434229e11f44888abcbf66062a5
timeCreated: 1495637741
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,58 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Sample Texture 3D")]
class SampleTexture3DNode : AbstractMaterialNode, IGeneratesBodyCode
{
public const int OutputSlotId = 0;
public const int TextureInputId = 1;
public const int UVInput = 2;
public const int SamplerInput = 3;
const string kOutputSlotName = "Out";
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
public override bool hasPreview { get { return true; } }
public SampleTexture3DNode()
{
name = "Sample Texture 3D";
synonyms = new string[] { "volume" };
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero, ShaderStageCapability.Fragment));
AddSlot(new Texture3DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new Vector3MaterialSlot(UVInput, kUVInputName, kUVInputName, SlotType.Input, Vector3.zero));
AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, TextureInputId, UVInput, SamplerInput });
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
var uvName = GetSlotValue(UVInput, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var id = GetSlotValue(TextureInputId, generationMode);
var result = string.Format("$precision4 {0} = SAMPLE_TEXTURE3D({1}.tex, {2}.samplerstate, {3});"
, GetVariableNameForSlot(OutputSlotId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id
, uvName);
sb.AppendLine(result);
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0c9bd58ae163e49acb187db417dbfd95
timeCreated: 1495637741
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,567 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Util;
using UnityEditor.Rendering;
using UnityEditor.ShaderGraph.Drawing;
using UnityEditor.ShaderGraph.Internal;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", SampleVirtualTextureNode.DefaultNodeTitle)]
class SampleVirtualTextureNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireTime, IMayRequireScreenPosition
{
public const string DefaultNodeTitle = "Sample Virtual Texture";
public const int kMinLayers = 1;
public const int kMaxLayers = 4;
// input slots
public const int UVInputId = 0;
public const int VirtualTextureInputId = 1;
public const int LODInputId = 2;
public const int BiasInputId = 3;
public const int DxInputId = 4;
public const int DyInputId = 5;
// output slots
[NonSerialized]
public readonly int[] OutputSlotIds = { 11, 12, 13, 14 };
const string UVInputName = "UV";
const string VirtualTextureInputName = "VT";
const string LODSlotName = "Lod";
const string BiasSlotName = "Bias";
const string DxSlotName = "Dx";
const string DySlotName = "Dy";
static string[] OutputSlotNames = { "Out", "Out2", "Out3", "Out4" };
public override bool hasPreview { get { return false; } }
// Keep these in sync with "VirtualTexturing.hlsl"
public enum LodCalculation
{
[InspectorName("Automatic")]
VtLevel_Automatic = 0,
[InspectorName("Lod Level")]
VtLevel_Lod = 1,
[InspectorName("Lod Bias")]
VtLevel_Bias = 2,
[InspectorName("Derivatives")]
VtLevel_Derivatives = 3
}
public enum AddressMode
{
[InspectorName("Wrap")]
VtAddressMode_Wrap = 0,
[InspectorName("Clamp")]
VtAddressMode_Clamp = 1,
}
public enum FilterMode
{
[InspectorName("Anisotropic")]
VtFilter_Anisotropic = 0
}
public enum UvSpace
{
[InspectorName("Regular")]
VtUvSpace_Regular = 0,
[InspectorName("Pre Transformed")]
VtUvSpace_PreTransformed = 1
}
public enum QualityMode
{
[InspectorName("Low")]
VtSampleQuality_Low = 0,
[InspectorName("High")]
VtSampleQuality_High = 1
}
[SerializeField]
AddressMode m_AddressMode = AddressMode.VtAddressMode_Wrap;
public AddressMode addressMode
{
get
{
return m_AddressMode;
}
set
{
if (m_AddressMode == value)
return;
m_AddressMode = value;
Dirty(ModificationScope.Graph);
}
}
[SerializeField]
LodCalculation m_LodCalculation = LodCalculation.VtLevel_Automatic;
public LodCalculation lodCalculation
{
get
{
return m_LodCalculation;
}
set
{
if (m_LodCalculation == value)
return;
m_LodCalculation = value;
RebuildAllSlots(true); // LOD calculation may have associated slots that need to be updated
Dirty(ModificationScope.Topological); // slots ShaderStageCapability could have changed, so trigger Topo change
}
}
[SerializeField]
QualityMode m_SampleQuality = QualityMode.VtSampleQuality_High;
public QualityMode sampleQuality
{
get
{
return m_SampleQuality;
}
set
{
if (m_SampleQuality == value)
return;
m_SampleQuality = value;
Dirty(ModificationScope.Graph);
}
}
[SerializeField]
private bool m_EnableGlobalMipBias = true;
public bool enableGlobalMipBias
{
get
{
return m_EnableGlobalMipBias;
}
set
{
if (m_EnableGlobalMipBias == value)
return;
m_EnableGlobalMipBias = value;
Dirty(ModificationScope.Graph);
}
}
[SerializeField]
bool m_NoFeedback; // aka !AutomaticStreaming
public bool noFeedback
{
get
{
return m_NoFeedback;
}
set
{
if (m_NoFeedback == value)
return;
m_NoFeedback = value;
RebuildAllSlots(true);
Dirty(ModificationScope.Topological); // slots ShaderStageCapability could have changed, so trigger Topo change
}
}
public SampleVirtualTextureNode() : this(false, false)
{ }
public SampleVirtualTextureNode(bool isLod = false, bool noResolve = false)
{
name = "Sample Virtual Texture";
synonyms = new string[] { "buffer" };
UpdateNodeAfterDeserialization();
}
public override void Setup()
{
UpdateLayerOutputSlots(true);
}
// rebuilds the number of output slots, and also updates their ShaderStageCapability
private int outputLayerSlotCount = 0;
void UpdateLayerOutputSlots(bool inspectProperty, List<int> usedSlots = null)
{
// the default is to show all 4 slots, so we don't lose any existing connections
int layerCount = kMaxLayers;
if (inspectProperty)
{
var vtProperty = GetSlotProperty(VirtualTextureInputId) as VirtualTextureShaderProperty;
if (vtProperty != null)
{
layerCount = vtProperty?.value?.layers?.Count ?? kMaxLayers;
}
if (outputLayerSlotCount == layerCount)
{
if (usedSlots != null)
for (int i = 0; i < layerCount; i++)
usedSlots.Add(OutputSlotIds[i]);
return;
}
}
for (int i = 0; i < kMaxLayers; i++)
{
int outputID = OutputSlotIds[i];
Vector4MaterialSlot outputSlot = FindSlot<Vector4MaterialSlot>(outputID);
if (i < layerCount)
{
// add or update it
if (outputSlot == null)
{
string outputName = OutputSlotNames[i];
outputSlot = new Vector4MaterialSlot(outputID, outputName, outputName, SlotType.Output, Vector4.zero, (noFeedback && m_LodCalculation == LodCalculation.VtLevel_Lod) ? ShaderStageCapability.All : ShaderStageCapability.Fragment);
AddSlot(outputSlot);
}
else
{
outputSlot.stageCapability = (noFeedback && m_LodCalculation == LodCalculation.VtLevel_Lod) ? ShaderStageCapability.All : ShaderStageCapability.Fragment;
}
if (usedSlots != null)
usedSlots.Add(outputID);
}
else
{
// remove it
if (outputSlot != null)
RemoveSlot(OutputSlotIds[i]);
}
}
outputLayerSlotCount = layerCount;
}
public void RebuildAllSlots(bool inspectProperty)
{
List<int> usedSlots = new List<int>();
AddSlot(new UVMaterialSlot(UVInputId, UVInputName, UVInputName, UVChannel.UV0));
usedSlots.Add(UVInputId);
AddSlot(new VirtualTextureInputMaterialSlot(VirtualTextureInputId, VirtualTextureInputName, VirtualTextureInputName));
usedSlots.Add(VirtualTextureInputId);
// at this point we can't tell how many output slots we will have (because we can't find the VT property yet)
// so, we create all of the possible output slots, so any edges created will connect properly
// then we can trim down the set of slots later..
UpdateLayerOutputSlots(inspectProperty, usedSlots);
// Create slots
if (m_LodCalculation == LodCalculation.VtLevel_Lod)
{
var slot = new Vector1MaterialSlot(LODInputId, LODSlotName, LODSlotName, SlotType.Input, 0.0f, ShaderStageCapability.All, LODSlotName);
AddSlot(slot);
usedSlots.Add(LODInputId);
}
if (m_LodCalculation == LodCalculation.VtLevel_Bias)
{
var slot = new Vector1MaterialSlot(BiasInputId, BiasSlotName, BiasSlotName, SlotType.Input, 0.0f, ShaderStageCapability.Fragment, BiasSlotName);
AddSlot(slot);
usedSlots.Add(BiasInputId);
}
if (m_LodCalculation == LodCalculation.VtLevel_Derivatives)
{
var slot1 = new Vector2MaterialSlot(DxInputId, DxSlotName, DxSlotName, SlotType.Input, Vector2.one, ShaderStageCapability.All, DxSlotName);
var slot2 = new Vector2MaterialSlot(DyInputId, DySlotName, DySlotName, SlotType.Input, Vector2.one, ShaderStageCapability.All, DySlotName);
AddSlot(slot1);
AddSlot(slot2);
usedSlots.Add(DxInputId);
usedSlots.Add(DyInputId);
}
RemoveSlotsNameNotMatching(usedSlots, true);
}
public override void UpdateNodeAfterDeserialization()
{
RebuildAllSlots(false);
}
const string k_NoPropertyConnected = "A VirtualTexture property must be connected to the VT slot";
public override void ValidateNode()
{
base.ValidateNode();
if (!IsSlotConnected(VirtualTextureInputId))
{
owner.AddValidationError(objectId, k_NoPropertyConnected);
}
else
{
var vtProp = GetSlotProperty(VirtualTextureInputId) as VirtualTextureShaderProperty;
if (vtProp == null)
{
owner.AddValidationError(objectId, $"VT slot is not connected to a valid VirtualTexture property");
}
}
}
public string GetFeedbackVariableName()
{
return GetVariableNameForNode() + "_fb";
}
void AppendVtParameters(ShaderStringBuilder sb, string uvExpr, string lodExpr, string dxExpr, string dyExpr, AddressMode address, FilterMode filter, LodCalculation lod, UvSpace space, QualityMode quality, bool enableGlobalMipBias)
{
sb.AppendLine("VtInputParameters vtParams;");
sb.AppendLine("vtParams.uv = " + uvExpr + ";");
sb.AppendLine("vtParams.lodOrOffset = " + lodExpr + ";");
sb.AppendLine("vtParams.dx = " + dxExpr + ";");
sb.AppendLine("vtParams.dy = " + dyExpr + ";");
sb.AppendLine("vtParams.addressMode = " + address + ";");
sb.AppendLine("vtParams.filterMode = " + filter + ";");
sb.AppendLine("vtParams.levelMode = " + lod + ";");
sb.AppendLine("vtParams.uvMode = " + space + ";");
sb.AppendLine("vtParams.sampleQuality = " + quality + ";");
sb.AppendLine("vtParams.enableGlobalMipBias = " + (enableGlobalMipBias ? "1" : "0") + ";");
sb.AppendLine("#if defined(SHADER_STAGE_RAY_TRACING)");
sb.AppendLine("if (vtParams.levelMode == VtLevel_Automatic || vtParams.levelMode == VtLevel_Bias)");
using (sb.BlockScope())
{
sb.AppendLine("vtParams.levelMode = VtLevel_Lod;");
sb.AppendLine("vtParams.lodOrOffset = 0.0f;");
}
sb.AppendLine("#endif");
}
void AppendVtSample(ShaderStringBuilder sb, string propertiesName, string vtInputVariable, string infoVariable, int layerIndex, string outputVariableName)
{
sb.TryAppendIndentation();
sb.Append(outputVariableName); sb.Append(" = ");
sb.Append("SampleVTLayerWithTextureType(");
sb.Append(propertiesName); sb.Append(", ");
sb.Append(vtInputVariable); sb.Append(", ");
sb.Append(infoVariable); sb.Append(", ");
sb.Append(layerIndex.ToString()); sb.Append(");");
sb.AppendNewLine();
}
// Node generations
string GetFunctionName(out List<int> layerIndices)
{
string name = "SampleVirtualTexture_" + addressMode + "_" + lodCalculation + "_" + m_SampleQuality;
layerIndices = new List<int>();
if (IsSlotConnected(VirtualTextureInputId))
{
var vtProperty = GetSlotProperty(VirtualTextureInputId) as VirtualTextureShaderProperty;
if (vtProperty != null)
{
int layerCount = vtProperty.value.layers.Count;
for (int layer = 0; layer < layerCount; layer++)
{
if (IsSlotConnected(OutputSlotIds[layer]))
{
layerIndices.Add(layer);
name = name + "_" + layer;
}
}
}
}
return name;
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
string functionName = GetFunctionName(out var layerOutputLayerIndex);
if (layerOutputLayerIndex.Count <= 0)
return;
registry.ProvideFunction(functionName, s =>
{
string lodExpr = "0.0f";
string dxExpr = "0.0f";
string dyExpr = "0.0f";
// function header
s.TryAppendIndentation();
s.Append("float4 ");
s.Append(functionName);
s.Append("(float2 uv");
switch (lodCalculation)
{
case LodCalculation.VtLevel_Lod:
s.Append(", float lod");
lodExpr = "lod";
break;
case LodCalculation.VtLevel_Bias:
s.Append(", float bias");
lodExpr = "bias";
break;
case LodCalculation.VtLevel_Derivatives:
s.Append(", float2 dx, float2 dy");
dxExpr = "dx";
dyExpr = "dy";
break;
}
s.Append(", VTPropertyWithTextureType vtProperty");
for (int i = 0; i < layerOutputLayerIndex.Count; i++)
{
s.Append(", out float4 Layer" + layerOutputLayerIndex[i]);
}
s.Append(")");
s.AppendNewLine();
// function body
using (s.BlockScope())
{
AppendVtParameters(
s,
"uv",
lodExpr,
dxExpr,
dyExpr,
m_AddressMode,
FilterMode.VtFilter_Anisotropic,
m_LodCalculation,
UvSpace.VtUvSpace_Regular,
m_SampleQuality,
m_EnableGlobalMipBias);
s.AppendLine("StackInfo info = PrepareVT(vtProperty.vtProperty, vtParams);");
for (int i = 0; i < layerOutputLayerIndex.Count; i++)
{
// sample virtual texture layer
int layer = layerOutputLayerIndex[i];
AppendVtSample(s, "vtProperty", "vtParams", "info", layer, "Layer" + layer);
}
s.AppendLine("return GetResolveOutput(info);");
}
});
}
public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
bool success = false;
if (IsSlotConnected(VirtualTextureInputId))
{
var vtProperty = GetSlotProperty(VirtualTextureInputId) as VirtualTextureShaderProperty;
if (vtProperty != null)
{
var layerOutputVariables = new List<string>();
int layerCount = vtProperty.value.layers.Count;
for (int i = 0; i < layerCount; i++)
{
if (IsSlotConnected(OutputSlotIds[i]))
{
// declare output variables up front
string layerOutputVariable = GetVariableNameForSlot(OutputSlotIds[i]);
sb.AppendLine("$precision4 " + layerOutputVariable + ";");
layerOutputVariables.Add(layerOutputVariable);
}
}
if (layerOutputVariables.Count > 0)
{
// assign feedback variable
sb.TryAppendIndentation();
if (!noFeedback)
{
sb.Append("float4 ");
sb.Append(GetFeedbackVariableName());
sb.Append(" = ");
}
sb.Append(GetFunctionName(out var unused));
sb.Append("(");
sb.Append(GetSlotValue(UVInputId, generationMode));
switch (lodCalculation)
{
case LodCalculation.VtLevel_Lod:
case LodCalculation.VtLevel_Bias:
sb.Append(", ");
sb.Append((lodCalculation == LodCalculation.VtLevel_Lod) ? GetSlotValue(LODInputId, generationMode) : GetSlotValue(BiasInputId, generationMode));
break;
case LodCalculation.VtLevel_Derivatives:
sb.Append(", ");
sb.Append(GetSlotValue(DxInputId, generationMode));
sb.Append(", ");
sb.Append(GetSlotValue(DyInputId, generationMode));
break;
}
sb.Append(", ");
sb.Append(vtProperty.referenceName);
foreach (string layerOutputVariable in layerOutputVariables)
{
sb.Append(", ");
sb.Append(layerOutputVariable);
}
sb.Append(");");
sb.AppendNewLine();
success = true;
}
}
}
if (!success)
{
// set all outputs to zero
for (int i = 0; i < kMaxLayers; i++)
{
if (IsSlotConnected(OutputSlotIds[i]))
{
// declare output variables up front
string layerOutputVariable = GetVariableNameForSlot(OutputSlotIds[i]);
sb.AppendLine("$precision4 " + layerOutputVariable + " = 0;");
}
}
// TODO: should really just disable feedback in this case (need different feedback interface to do this)
sb.AppendLine("$precision4 " + GetFeedbackVariableName() + " = 1;");
}
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
// this adds default properties for all of our unconnected inputs
base.CollectShaderProperties(properties, generationMode);
}
public bool RequiresMeshUV(Internal.UVChannel channel, ShaderStageCapability stageCapability)
{
using (var tempSlots = PooledList<MaterialSlot>.Get())
{
GetInputSlots(tempSlots);
foreach (var slot in tempSlots)
{
if (slot.RequiresMeshUV(channel))
return true;
}
return false;
}
}
public bool RequiresTime()
{
// HACK: This ensures we repaint in shadergraph so data that gets streamed in also becomes visible.
return true;
}
public bool RequiresScreenPosition(ShaderStageCapability stageCapability = ShaderStageCapability.All)
{
// Feedback dithering requires screen position (and only works in Pixel Shader currently)
return stageCapability.HasFlag(ShaderStageCapability.Fragment) && !noFeedback;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29b42276bd0679743bb3386305aa7691
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,130 @@
using System;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Sampler State")]
class SamplerStateNode : AbstractMaterialNode, IPropertyFromNode
{
[SerializeField]
private TextureSamplerState.FilterMode m_filter = TextureSamplerState.FilterMode.Linear;
[EnumControl]
public TextureSamplerState.FilterMode filter
{
get { return m_filter; }
set
{
if (m_filter == value)
return;
m_filter = value;
Dirty(ModificationScope.Graph);
}
}
[SerializeField]
private TextureSamplerState.WrapMode m_wrap = TextureSamplerState.WrapMode.Repeat;
[EnumControl]
public TextureSamplerState.WrapMode wrap
{
get { return m_wrap; }
set
{
if (m_wrap == value)
return;
m_wrap = value;
Dirty(ModificationScope.Graph);
}
}
[SerializeField]
private TextureSamplerState.Anisotropic m_aniso = TextureSamplerState.Anisotropic.None;
public TextureSamplerState.Anisotropic anisotropic
{
get { return m_aniso; }
set
{
if (m_aniso == value)
return;
m_aniso = value;
Dirty(ModificationScope.Graph);
}
}
public SamplerStateNode()
{
name = "Sampler State";
UpdateNodeAfterDeserialization();
}
public override bool hasPreview { get { return false; } }
private const int kOutputSlotId = 0;
private const string kOutputSlotName = "Out";
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new SamplerStateMaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
string GetSamplerStatePropertyName()
{
return GetVariableNameForNode();
}
string GetSamplerStateVariableName()
{
return $"UnityBuildSamplerStateStruct({GetSamplerStatePropertyName()})";
}
public override string GetVariableNameForSlot(int slotId)
{
return GetSamplerStateVariableName();
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new SamplerStateShaderProperty()
{
overrideReferenceName = GetSamplerStatePropertyName(),
generatePropertyBlock = false,
value = new TextureSamplerState()
{
filter = m_filter,
wrap = m_wrap,
anisotropic = m_aniso
}
});
}
public override string GetVariableNameForNode()
{
return TextureSamplerState.BuildSamplerStateName(filter, wrap, anisotropic);
}
public AbstractShaderProperty AsShaderProperty()
{
return new SamplerStateShaderProperty
{
value = new TextureSamplerState()
{
filter = this.filter,
wrap = this.wrap,
anisotropic = this.anisotropic
}
};
}
public int outputSlotId { get { return kOutputSlotId; } }
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5fe2c333e043511478cc507ee61a8c21
timeCreated: 1495658099
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,48 @@
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Texel Size")]
class Texture2DPropertiesNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotWId = 0;
public const int OutputSlotHId = 2;
public const int TextureInputId = 1;
const string kOutputSlotWName = "Width";
const string kOutputSlotHName = "Height";
const string kTextureInputName = "Texture";
public override bool hasPreview { get { return false; } }
public Texture2DPropertiesNode()
{
name = "Texel Size";
synonyms = new string[] { "texture size" };
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector1MaterialSlot(OutputSlotWId, kOutputSlotWName, kOutputSlotWName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotHId, kOutputSlotHName, kOutputSlotHName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
RemoveSlotsNameNotMatching(new[] { OutputSlotWId, OutputSlotHId, TextureInputId });
}
// Node generations
public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
{
sb.AppendLine(string.Format("$precision {0} = {1}.texelSize.z;", GetVariableNameForSlot(OutputSlotWId), GetSlotValue(TextureInputId, generationMode)));
sb.AppendLine(string.Format("$precision {0} = {1}.texelSize.w;", GetVariableNameForSlot(OutputSlotHId), GetSlotValue(TextureInputId, generationMode)));
}
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
{
return true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab454fbbbc9f31d4083c178cf885c672
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,101 @@
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Texture 2D Array Asset")]
[HasDependencies(typeof(Minimal2dArrayTextureAssetNode))]
class Texture2DArrayAssetNode : AbstractMaterialNode, IPropertyFromNode
{
public const int OutputSlotId = 0;
const string kOutputSlotName = "Out";
public Texture2DArrayAssetNode()
{
name = "Texture 2D Array Asset";
synonyms = new string[] { "stack", "pile" };
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Texture2DArrayMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
[SerializeField]
private SerializableTextureArray m_Texture = new SerializableTextureArray();
[TextureArrayControl("")]
public Texture2DArray texture
{
get { return m_Texture.textureArray; }
set
{
if (m_Texture.textureArray == value)
return;
m_Texture.textureArray = value;
Dirty(ModificationScope.Node);
}
}
string GetTexturePropertyName()
{
return base.GetVariableNameForSlot(OutputSlotId);
}
public override string GetVariableNameForSlot(int slotId)
{
return $"UnityBuildTexture2DArrayStruct({GetTexturePropertyName()})";
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new Texture2DArrayShaderProperty()
{
overrideReferenceName = GetTexturePropertyName(),
generatePropertyBlock = true,
value = m_Texture,
modifiable = false
});
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty(PropertyType.Texture2DArray)
{
name = GetTexturePropertyName(),
textureValue = texture
});
}
public AbstractShaderProperty AsShaderProperty()
{
var prop = new Texture2DArrayShaderProperty { value = m_Texture };
if (texture != null)
prop.displayName = texture.name;
return prop;
}
public int outputSlotId { get { return OutputSlotId; } }
}
class Minimal2dArrayTextureAssetNode : IHasDependencies
{
[SerializeField]
private SerializableTextureArray m_Texture = null;
public void GetSourceAssetDependencies(AssetCollection assetCollection)
{
var guidString = m_Texture.guid;
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
{
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 34c0298d9fb6e4bc9aedbeeeeb8b8054
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,102 @@
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Texture 2D Asset")]
[HasDependencies(typeof(Minimal2d3dTextureAssetNode))]
class Texture2DAssetNode : AbstractMaterialNode, IPropertyFromNode
{
public const int OutputSlotId = 0;
const string kOutputSlotName = "Out";
public Texture2DAssetNode()
{
name = "Texture 2D Asset";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Texture2DMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
[SerializeField]
private SerializableTexture m_Texture = new SerializableTexture();
[TextureControl("")]
public Texture texture
{
get { return m_Texture.texture; }
set
{
if (m_Texture.texture == value)
return;
m_Texture.texture = value;
Dirty(ModificationScope.Node);
}
}
string GetTexturePropertyName()
{
return base.GetVariableNameForSlot(OutputSlotId);
}
public override string GetVariableNameForSlot(int slotId)
{
return $"UnityBuildTexture2DStructNoScale({GetTexturePropertyName()})";
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new Texture2DShaderProperty()
{
overrideReferenceName = GetTexturePropertyName(),
generatePropertyBlock = true,
value = m_Texture,
modifiable = false
});
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty(PropertyType.Texture2D)
{
name = GetTexturePropertyName(),
textureValue = texture,
texture2DDefaultType = Texture2DShaderProperty.DefaultType.White
});
}
public AbstractShaderProperty AsShaderProperty()
{
var prop = new Texture2DShaderProperty { value = m_Texture };
if (texture != null)
prop.displayName = texture.name;
return prop;
}
public int outputSlotId { get { return OutputSlotId; } }
}
// this is used for Texture2D AND Texture3D
class Minimal2d3dTextureAssetNode : IHasDependencies
{
[SerializeField]
private SerializableTexture m_Texture = null;
public void GetSourceAssetDependencies(AssetCollection assetCollection)
{
var guidString = m_Texture.guid;
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
{
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c629b78a2ec57749ab4f76f4f42f423
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,86 @@
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Texture 3D Asset")]
[HasDependencies(typeof(Minimal2d3dTextureAssetNode))]
class Texture3DAssetNode : AbstractMaterialNode, IPropertyFromNode
{
public const int OutputSlotId = 0;
const string kOutputSlotName = "Out";
public Texture3DAssetNode()
{
name = "Texture 3D Asset";
synonyms = new string[] { "volume" };
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Texture3DMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
[SerializeField]
private SerializableTexture m_Texture = new SerializableTexture();
[Texture3DControl("")]
public Texture3D texture
{
get { return m_Texture.texture as Texture3D; }
set
{
if (m_Texture.texture == value)
return;
m_Texture.texture = value;
Dirty(ModificationScope.Node);
}
}
string GetTexturePropertyName()
{
return base.GetVariableNameForSlot(OutputSlotId);
}
public override string GetVariableNameForSlot(int slotId)
{
return $"UnityBuildTexture3DStruct({GetTexturePropertyName()})";
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new Texture3DShaderProperty()
{
overrideReferenceName = GetTexturePropertyName(),
generatePropertyBlock = true,
value = m_Texture,
modifiable = false
});
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty(PropertyType.Texture3D)
{
name = GetTexturePropertyName(),
textureValue = texture
});
}
public AbstractShaderProperty AsShaderProperty()
{
var prop = new Texture3DShaderProperty { value = m_Texture };
if (texture != null)
prop.displayName = texture.name;
return prop;
}
public int outputSlotId { get { return OutputSlotId; } }
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0b009ba9b523742a0ad6530e14a063a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Util;
using UnityEditor.Rendering;
using UnityEditor.ShaderGraph.Drawing;
using UnityEditor.ShaderGraph.Internal;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
namespace UnityEditor.ShaderGraph
{
// TODO: rename this file to VirtualTexturingFeedbackUtils
static class VirtualTexturingFeedbackUtils
{
// TODO: could get rid of this if we could run a codegen prepass (with proper keyword #ifdef)
public static void GenerateVirtualTextureFeedback(
List<AbstractMaterialNode> downstreamNodesIncludingRoot,
List<int>[] keywordPermutationsPerNode,
ShaderStringBuilder surfaceDescriptionFunction,
KeywordCollector shaderKeywords)
{
// A note on how we handle vt feedback in combination with keywords:
// We essentially generate a fully separate feedback path for each permutation of keywords
// so per permutation we gather variables contribution to feedback and we generate
// feedback gathering for each permutation individually.
var feedbackVariablesPerPermutation = PooledList<PooledList<string>>.Get();
try
{
if (shaderKeywords.permutations.Count >= 1)
{
for (int i = 0; i < shaderKeywords.permutations.Count; i++)
{
feedbackVariablesPerPermutation.Add(PooledList<string>.Get());
}
}
else
{
// Create a dummy single permutation
feedbackVariablesPerPermutation.Add(PooledList<string>.Get());
}
int index = 0; //for keywordPermutationsPerNode
foreach (var node in downstreamNodesIncludingRoot)
{
if (node is SampleVirtualTextureNode vtNode)
{
if (vtNode.noFeedback) continue;
if (keywordPermutationsPerNode[index] == null)
{
Debug.Assert(shaderKeywords.permutations.Count == 0, $"Shader has {shaderKeywords.permutations.Count} permutations but keywordPermutationsPerNode of some nodes are null.");
feedbackVariablesPerPermutation[0].Add(vtNode.GetFeedbackVariableName());
}
else
{
foreach (int perm in keywordPermutationsPerNode[index])
{
feedbackVariablesPerPermutation[perm].Add(vtNode.GetFeedbackVariableName());
}
}
}
if (node is SubGraphNode sgNode)
{
if (sgNode.asset == null) continue;
if (keywordPermutationsPerNode[index] == null)
{
Debug.Assert(shaderKeywords.permutations.Count == 0, $"Shader has {shaderKeywords.permutations.Count} permutations but keywordPermutationsPerNode of some nodes are null.");
foreach (var feedbackSlot in sgNode.asset.vtFeedbackVariables)
{
feedbackVariablesPerPermutation[0].Add(node.GetVariableNameForNode() + "_" + feedbackSlot);
}
}
else
{
foreach (var feedbackSlot in sgNode.asset.vtFeedbackVariables)
{
foreach (int perm in keywordPermutationsPerNode[index])
{
feedbackVariablesPerPermutation[perm].Add(node.GetVariableNameForNode() + "_" + feedbackSlot);
}
}
}
}
index++;
}
index = 0;
foreach (var feedbackVariables in feedbackVariablesPerPermutation)
{
// If it's a dummy single always-on permutation don't put an ifdef around the code
if (shaderKeywords.permutations.Count >= 1)
{
surfaceDescriptionFunction.AppendLine(KeywordUtil.GetKeywordPermutationConditional(index));
}
using (surfaceDescriptionFunction.BlockScope())
{
if (feedbackVariables.Count == 0)
{
string feedBackCode = "surface.VTPackedFeedback = float4(1.0f,1.0f,1.0f,1.0f);";
surfaceDescriptionFunction.AppendLine(feedBackCode);
}
else if (feedbackVariables.Count == 1)
{
string feedBackCode = "surface.VTPackedFeedback = GetPackedVTFeedback(" + feedbackVariables[0] + ");";
surfaceDescriptionFunction.AppendLine(feedBackCode);
}
else if (feedbackVariables.Count > 1)
{
surfaceDescriptionFunction.AppendLine("float4 VTFeedback_array[" + feedbackVariables.Count + "];");
int arrayIndex = 0;
foreach (var variable in feedbackVariables)
{
surfaceDescriptionFunction.AppendLine("VTFeedback_array[" + arrayIndex + "] = " + variable + ";");
arrayIndex++;
}
surfaceDescriptionFunction.AppendLine("uint pixelColumn = (IN.ScreenPosition.x / IN.ScreenPosition.w) * _ScreenParams.x;");
surfaceDescriptionFunction.AppendLine(
"surface.VTPackedFeedback = GetPackedVTFeedback(VTFeedback_array[(pixelColumn + _FrameCount) % (uint)" + feedbackVariables.Count + "]);");
}
}
if (shaderKeywords.permutations.Count >= 1)
{
surfaceDescriptionFunction.AppendLine("#endif");
}
index++;
}
}
finally
{
foreach (var list in feedbackVariablesPerPermutation)
{
list.Dispose();
}
feedbackVariablesPerPermutation.Dispose();
}
}
// Automatically add a streaming feedback node and correctly connect it to stack samples are connected to it and it is connected to the master node output
public static List<string> GetFeedbackVariables(SubGraphOutputNode masterNode)
{
// TODO: make use a generic interface instead of hard-coding the node types that we need to look at here
var VTNodes = GraphUtil.FindDownStreamNodesOfType<SampleVirtualTextureNode>(masterNode);
var subGraphNodes = GraphUtil.FindDownStreamNodesOfType<SubGraphNode>(masterNode);
List<string> result = new List<string>();
// Early out if there are no nodes we care about in the graph
if (subGraphNodes.Count <= 0 && VTNodes.Count <= 0)
{
return result;
}
// Add inputs to feedback node
foreach (var node in VTNodes)
{
if (node.noFeedback) continue;
result.Add(node.GetFeedbackVariableName());
}
foreach (var node in subGraphNodes)
{
if (node.asset == null) continue;
// TODO: subgraph.GetFeedbackVariableNames(...)
foreach (var feedbackSlot in node.asset.vtFeedbackVariables)
{
result.Add(node.GetVariableNameForNode() + "_" + feedbackSlot);
}
}
return result;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e2db046575851ad4c806c1fb14f28290
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: