您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
213 行
9.0 KiB
213 行
9.0 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();
|
|
}
|
|
|
|
public override string documentationURL
|
|
{
|
|
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Transform-Node"; }
|
|
}
|
|
|
|
[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(ShaderStageCapability stageCapability)
|
|
{
|
|
if (RequiresWorldSpaceTangentTransform())
|
|
return NeededCoordinateSpace.World;
|
|
return conversion.from.ToNeededCoordinateSpace();
|
|
}
|
|
|
|
public NeededCoordinateSpace RequiresBitangent(ShaderStageCapability stageCapability)
|
|
{
|
|
if (RequiresWorldSpaceTangentTransform())
|
|
return NeededCoordinateSpace.World;
|
|
return conversion.from.ToNeededCoordinateSpace();
|
|
}
|
|
|
|
public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability)
|
|
{
|
|
if (RequiresWorldSpaceTangentTransform())
|
|
return NeededCoordinateSpace.World;
|
|
return conversion.from.ToNeededCoordinateSpace();
|
|
}
|
|
}
|
|
}
|