您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

208 行
8.7 KiB

using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Serializable]
public struct CoordinateSpaceConversion : IEnumConversion
{
public CoordinateSpace from;
public CoordinateSpace to;
public CoordinateSpaceConversion(CoordinateSpace from, CoordinateSpace to)
{
this.from = from;
this.to = to;
}
Enum IEnumConversion.from
{
get { return from; }
set { from = (CoordinateSpace)value; }
}
Enum IEnumConversion.to
{
get { return to; }
set { to = (CoordinateSpace)value; }
}
}
[Title("Math", "Vector", "Transform")]
public class TransformNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireTangent, IMayRequireBitangent, IMayRequireNormal
{
private const int InputSlotId = 0;
private const int OutputSlotId = 1;
private const string kInputSlotName = "In";
private const string kOutputSlotName = "Out";
public TransformNode()
{
name = "Transform";
UpdateNodeAfterDeserialization();
}
[SerializeField]
CoordinateSpaceConversion m_Conversion = new CoordinateSpaceConversion(CoordinateSpace.Object, CoordinateSpace.World);
[EnumConversionControl]
public CoordinateSpaceConversion conversion
{
get { return m_Conversion; }
set
{
if (Equals(m_Conversion, value))
return;
m_Conversion = value;
Dirty(ModificationScope.Graph);
}
}
public override bool hasPreview
{
get { return true; }
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlotId }, new[] { OutputSlotId });
string inputValue = string.Format("{0}.xyz", GetSlotValue(InputSlotId, generationMode));
string targetTransformString = "tangentTransform_" + conversion.from.ToString();
string transposeTargetTransformString = "transposeTangent";
string transformString = "";
string tangentTransformSpace = conversion.from.ToString();
bool requiresTangentTransform = false;
bool requiresTransposeTangentTransform = false;
if (conversion.from == CoordinateSpace.World)
{
if (conversion.to == CoordinateSpace.World)
{
transformString = inputValue;
}
else if (conversion.to == CoordinateSpace.Object)
{
transformString = string.Format("TransformWorldToObject({0})", inputValue);
}
else if (conversion.to == CoordinateSpace.Tangent)
{
requiresTangentTransform = true;
transformString = string.Format("TransformWorldToTangent({0}, {1})", inputValue, targetTransformString);
}
else if (conversion.to == CoordinateSpace.View)
{
transformString = string.Format("TransformWorldToView({0})", inputValue);
}
}
else if (conversion.from == CoordinateSpace.Object)
{
if (conversion.to == CoordinateSpace.World)
{
transformString = string.Format("TransformObjectToWorld({0})", inputValue);
}
else if (conversion.to == CoordinateSpace.Object)
{
transformString = inputValue;
}
else if (conversion.to == CoordinateSpace.Tangent)
{
requiresTangentTransform = true;
transformString = string.Format("TransformWorldToTangent(TransformObjectToWorld({0}), {1})", inputValue, targetTransformString);
}
else if (conversion.to == CoordinateSpace.View)
{
transformString = string.Format("TransformWorldToView(TransformObjectToWorld({0}))", inputValue);
}
}
else if (conversion.from == CoordinateSpace.Tangent)
{
if (conversion.to == CoordinateSpace.World)
{
requiresTransposeTangentTransform = true;
transformString = string.Format("mul({0}, {1}).xyz", inputValue, transposeTargetTransformString);
}
else if (conversion.to == CoordinateSpace.Object)
{
requiresTransposeTangentTransform = true;
transformString = string.Format("TransformWorldToObject(mul({0}, {1}).xyz)", inputValue, transposeTargetTransformString);
}
else if (conversion.to == CoordinateSpace.Tangent)
{
transformString = inputValue;
}
else if (conversion.to == CoordinateSpace.View)
{
requiresTransposeTangentTransform = true;
transformString = string.Format("TransformWorldToView(mul({0}, {1}).xyz)", inputValue, transposeTargetTransformString);
}
}
else if (conversion.from == CoordinateSpace.View)
{
if (conversion.to == CoordinateSpace.World)
{
transformString = string.Format("mul(UNITY_MATRIX_I_V, float4({0}, 1)).xyz", inputValue);
}
else if (conversion.to == CoordinateSpace.Object)
{
transformString = string.Format("TransformWorldToObject(mul(UNITY_MATRIX_I_V, float4({0}, 1) ).xyz)", inputValue);
}
else if (conversion.to == CoordinateSpace.Tangent)
{
requiresTangentTransform = true;
tangentTransformSpace = CoordinateSpace.World.ToString();
transformString = string.Format("TransformWorldToTangent(mul(UNITY_MATRIX_I_V, float4({0}, 1) ).xyz, {1})", inputValue, targetTransformString);
}
else if (conversion.to == CoordinateSpace.View)
{
transformString = inputValue;
}
}
if (requiresTransposeTangentTransform)
visitor.AddShaderChunk(string.Format("float3x3 {0} = transpose(float3x3(IN.{1}SpaceTangent, IN.{1}SpaceBiTangent, IN.{1}SpaceNormal));", transposeTargetTransformString, CoordinateSpace.World.ToString()), true);
else if (requiresTangentTransform)
visitor.AddShaderChunk(string.Format("float3x3 {0} = float3x3(IN.{1}SpaceTangent, IN.{1}SpaceBiTangent, IN.{1}SpaceNormal);", targetTransformString, tangentTransformSpace), true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
GetVariableNameForSlot(OutputSlotId),
transformString), true);
}
bool RequiresWorldSpaceTangentTransform()
{
if (conversion.from == CoordinateSpace.View && conversion.to == CoordinateSpace.Tangent
|| conversion.from == CoordinateSpace.Tangent)
return true;
else
return false;
}
public NeededCoordinateSpace RequiresTangent()
{
if(RequiresWorldSpaceTangentTransform())
return NeededCoordinateSpace.World;
return conversion.from.ToNeededCoordinateSpace();
}
public NeededCoordinateSpace RequiresBitangent()
{
if (RequiresWorldSpaceTangentTransform())
return NeededCoordinateSpace.World;
return conversion.from.ToNeededCoordinateSpace();
}
public NeededCoordinateSpace RequiresNormal()
{
if (RequiresWorldSpaceTangentTransform())
return NeededCoordinateSpace.World;
return conversion.from.ToNeededCoordinateSpace();
}
}
}