浏览代码

Adding support for IMayRequireViewDirectionTangentSpace, and a simple Parallax node to use it. Node seems to have the correct behavior, but not fully tested.

/main
ChrisTchou 7 年前
当前提交
9ac0408c
共有 7 个文件被更改,包括 223 次插入18 次删除
  1. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  2. 50
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SurfaceModel/AbstractSurfaceMasterNode.cs
  3. 48
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs
  4. 122
      MaterialGraphProject/Assets/NewNodes/WIP/ParallaxNode.cs
  5. 12
      MaterialGraphProject/Assets/NewNodes/WIP/ParallaxNode.cs.meta

9
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs


, IMayRequireViewDirection
, IMayRequireWorldPosition
, IMayRequireVertexColor
, IMayRequireViewDirectionTangentSpace
{
[SerializeField]
private string m_SerializedSubGraph = string.Empty;

return false;
return subGraph.activeNodes.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
}
public bool RequiresViewDirectionTangentSpace()
{
if (subGraph == null)
return false;
return subGraph.activeNodes.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
}
public bool RequiresWorldPosition()

50
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SurfaceModel/AbstractSurfaceMasterNode.cs


// always add color because why not.
shaderInputVisitor.AddShaderChunk("float4 color : COLOR;", true);
bool requiresBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
bool requiresTangent = activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent());
bool requiresViewDirTangentSpace = activeNodeList.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
bool requiresViewDir = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
bool requiresWorldPos = activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition());
bool requiresNormal = activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal());
bool requiresScreenPosition = activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = activeNodeList.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
{
var channel = (UVChannel)uvIndex;

}
}
if (activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection()))
if (requiresViewDir || requiresViewDirTangentSpace)
if (activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition()))
if (requiresWorldPos)
if (activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition()))
if (requiresScreenPosition)
bool needBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
if (needBitangent || activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent()))
if (requiresBitangent || requiresTangent || requiresViewDirTangentSpace)
{
shaderInputVisitor.AddShaderChunk("float4 worldTangent;", true);
vertexShaderBlock.AddShaderChunk("o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);", true);

if (needBitangent || activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal()))
if (requiresBitangent || requiresNormal || requiresViewDirTangentSpace)
{
// is the normal connected?
var normalSlot = FindInputSlot<MaterialSlot>(NormalSlotId);

shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceNormal + " = normalize(IN.worldNormal);", true);
}
if (needBitangent)
if (requiresBitangent || requiresViewDirTangentSpace)
if (activeNodeList.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor()))
if (requiresViewDirTangentSpace)
{
// shaderInputVisitor.AddShaderChunk("float3 tangentViewDir;", true);
// shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.TangentSpaceViewDirection + " = IN.tangentViewDir;", true);
shaderBody.AddShaderChunk(
"float3 " + ShaderGeneratorNames.TangentSpaceViewDirection + ";", true);
shaderBody.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".x = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceTangent + ");", true);
shaderBody.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".y = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceBitangent + ");", true);
shaderBody.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".z = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceNormal + ");", true);
}
if (requiresVertexColor)
{
shaderBody.AddShaderChunk("float4 " + ShaderGeneratorNames.VertexColor + " = IN.color;", true);
}

48
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs


public const string WorldSpaceTangent = "worldSpaceTangent";
public const string WorldSpacePosition = "worldPosition";
public const string WorldSpaceViewDirection = "worldSpaceViewDirection";
public const string TangentSpaceViewDirection = "tangentSpaceViewDirection";
public const string ScreenPosition = "screenPosition";
public const string VertexColor = "vertexColor";

vertexShaderBlock.AddShaderChunk("float4 screenPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));", true);
vertexShaderBlock.AddShaderChunk("float3 worldNormal = UnityObjectToWorldNormal(v.normal);", true);
bool needBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
bool needsWorldPos = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
if (needsWorldPos || activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition()))
bool requiresBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
bool requiresTangent = activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent());
bool requiresViewDirTangentSpace = activeNodeList.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
bool requiresViewDir = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
bool requiresWorldPos = activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition());
bool requiresNormal = activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal());
bool requiresScreenPosition = activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = activeNodeList.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
// view directions calculated from world position
if (requiresWorldPos || requiresViewDir || requiresViewDirTangentSpace)
{
shaderInputVisitor.AddShaderChunk("float3 worldPos : TEXCOORD0;", true);
vertexShaderBlock.AddShaderChunk("o.worldPos = worldPos;", true);

if (needBitangent || activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal()))
if (requiresBitangent || requiresNormal || requiresViewDirTangentSpace)
{
shaderInputVisitor.AddShaderChunk("float3 worldNormal : TEXCOORD1;", true);
vertexShaderBlock.AddShaderChunk("o.worldNormal = worldNormal;", true);

}
}
if (activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection()))
if (requiresViewDir || requiresViewDirTangentSpace)
{
shaderBodyVisitor.AddShaderChunk(
"float3 "

+ "));", true);
}
if (activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition()))
if (requiresScreenPosition)
{
shaderInputVisitor.AddShaderChunk("float4 screenPos : TEXCOORD3;", true);
vertexShaderBlock.AddShaderChunk("o.screenPos = screenPos;", true);

if (needBitangent || activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent()))
if (requiresBitangent || requiresViewDirTangentSpace || requiresTangent)
{
shaderInputVisitor.AddShaderChunk("float4 worldTangent : TEXCOORD4;", true);
vertexShaderBlock.AddShaderChunk("o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);", true);

if (needBitangent)
if (requiresBitangent || requiresViewDirTangentSpace)
if (activeNodeList.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor()))
if (requiresViewDirTangentSpace)
{
shaderBodyVisitor.AddShaderChunk(
"float3 " + ShaderGeneratorNames.TangentSpaceViewDirection + ";", true);
shaderBodyVisitor.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".x = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceTangent + ");", true);
shaderBodyVisitor.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".y = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceBitangent + ");", true);
shaderBodyVisitor.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".z = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceNormal + ");", true);
}
if (requiresVertexColor)
{
vertexShaderBlock.AddShaderChunk("o.color = v.color;", true);
shaderBodyVisitor.AddShaderChunk("float4 " + ShaderGeneratorNames.VertexColor + " = IN.color;", true);

122
MaterialGraphProject/Assets/NewNodes/WIP/ParallaxNode.cs


using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
interface IMayRequireViewDirectionTangentSpace
{
bool RequiresViewDirectionTangentSpace();
}
[Title("UV/Parallax")]
public class ParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirectionTangentSpace
{
protected const string kInputSlot1ShaderName = "Depth";
protected const string kOutputSlotShaderName = "UV";
public const int InputSlot1Id = 0;
public const int OutputSlotId = 1;
public override bool hasPreview
{
get { return true; }
}
public override PreviewMode previewMode
{
get
{
return PreviewMode.Preview3D;
}
}
public ParallaxNode()
{
name = "Parallax";
UpdateNodeAfterDeserialization();
}
public string GetFunctionName()
{
return "unity_parallax_" + precision;
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(GetInputSlot1());
AddSlot(GetOutputSlot());
RemoveSlotsNameNotMatching(validSlots);
}
protected int[] validSlots
{
get { return new[] { InputSlot1Id, OutputSlotId }; }
}
protected virtual MaterialSlot GetInputSlot1()
{
return new MaterialSlot(InputSlot1Id, GetInputSlot1Name(), kInputSlot1ShaderName, SlotType.Input, SlotValueType.Vector1, Vector4.zero);
}
protected virtual MaterialSlot GetOutputSlot()
{
return new MaterialSlot(OutputSlotId, GetOutputSlotName(), kOutputSlotShaderName, SlotType.Output, SlotValueType.Vector2, Vector4.zero);
}
protected virtual string GetInputSlot1Name()
{
return kInputSlot1ShaderName;
}
protected virtual string GetOutputSlotName()
{
return kOutputSlotShaderName;
}
protected virtual string GetFunctionPrototype(string arg1Name, string arg2Name, string arg3Name)
{
return "inline " + precision + "2 " + GetFunctionName() + " (" +
precision + " " + arg1Name + ", " +
precision + "2 " + arg2Name + ", " +
precision + "3 " + arg3Name + ")";
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlot1Id }, new[] { OutputSlotId });
string input1Value = GetSlotValue(InputSlot1Id, generationMode);
visitor.AddShaderChunk(precision + "2 " + GetVariableNameForSlot(OutputSlotId) + " = " + GetFunctionCallBody(input1Value) + ";", true);
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("depth", "UVs", "viewTangentSpace"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return UVs + depth * viewTangentSpace.xy / viewTangentSpace.z;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
protected virtual string GetFunctionCallBody(string inputValue1)
{
var channel = UVChannel.uv0;
return GetFunctionName() + " (" +
inputValue1 + ", " +
channel.GetUVName() + ", " +
ShaderGeneratorNames.TangentSpaceViewDirection + ")";
}
public bool RequiresMeshUV(UVChannel channel)
{
return channel == UVChannel.uv0;
}
public bool RequiresViewDirectionTangentSpace()
{
return true;
}
}
}

12
MaterialGraphProject/Assets/NewNodes/WIP/ParallaxNode.cs.meta


fileFormatVersion: 2
guid: 5f290ce984a59bb46a1c34491b3b8b98
timeCreated: 1495488490
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存