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

88 行
4.1 KiB

using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{
[Title("Utility/Heightmap To Normalmap")]
public class HeightToNormalNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int TextureInput = 0;
public const int TexCoordInput = 1;
public const int TexOffsetInput = 2;
public const int StrengthInput = 3;
public const int NormalOutput = 4;
const string TextureInputName = "Texture";
const string TexCoordInputName = "UV";
const string TexOffsetInputName = "Offset";
const string StrengthInputName = "Strength";
const string NormalOutputName = "Normal";
public HeightToNormalNode()
{
name = "HeightToNormal";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Texture2DMaterialSlot(TextureInput, TextureInputName, TextureInputName, SlotType.Input));
AddSlot(new Vector2MaterialSlot(TexCoordInput, TexCoordInputName, TexCoordInputName, SlotType.Input, Vector2.zero));
AddSlot(new Vector1MaterialSlot(TexOffsetInput, TexOffsetInputName, TexOffsetInputName, SlotType.Input, 0.005f));
AddSlot(new Vector1MaterialSlot(StrengthInput, StrengthInputName, StrengthInputName, SlotType.Input, 8f));
AddSlot(new Vector3MaterialSlot(NormalOutput, NormalOutputName, NormalOutputName, SlotType.Output, Vector3.zero));
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var textureInput = GetSlotValue(TextureInput, generationMode);
var texCoordInput = RequiresMeshUV(UVChannel.uv0)
? string.Format("{0}.xy", UVChannel.uv0.GetUVName())
: GetSlotValue(TexCoordInput, generationMode);
var texOffsetInput = GetSlotValue(TexOffsetInput, generationMode);
var strengthInput = GetSlotValue(StrengthInput, generationMode);
var normalOutput = GetVariableNameForSlot(NormalOutput);
visitor.AddShaderChunk(string.Format("{0}3 {1};", precision, normalOutput), true);
visitor.AddShaderChunk("{", false);
visitor.Indent();
{
visitor.AddShaderChunk(string.Format("{0}2 offsetU = float2({1}.x + {2}, {1}.y);", precision, texCoordInput, texOffsetInput), true);
visitor.AddShaderChunk(string.Format("{0}2 offsetV = float2({1}.x, {1}.y + {2});", precision, texCoordInput, texOffsetInput), true);
visitor.AddShaderChunk(string.Format("{0} normalSample = UNITY_SAMPLE_TEX2D({1}, {2});", precision, textureInput, texCoordInput), true);
visitor.AddShaderChunk(string.Format("{0} uSample = UNITY_SAMPLE_TEX2D({1}, offsetU);", precision, textureInput), true);
visitor.AddShaderChunk(string.Format("{0} vSample = UNITY_SAMPLE_TEX2D({1}, offsetV);", precision, textureInput), true);
visitor.AddShaderChunk(string.Format("{0}3 va = float3(1, 0, (uSample - normalSample) * {1});", precision, strengthInput), true);
visitor.AddShaderChunk(string.Format("{0}3 vb = float3(0, 1, (vSample - normalSample) * {1});", precision, strengthInput), true);
visitor.AddShaderChunk(string.Format("{0} = cross(va, vb);", normalOutput), true);
}
visitor.Deindent();
visitor.AddShaderChunk("}", false);
}
public override bool hasPreview
{
get { return true; }
}
public bool RequiresMeshUV(UVChannel channel)
{
if (channel != UVChannel.uv0)
{
return false;
}
var uvSlot = FindInputSlot<MaterialSlot>(TexCoordInput);
if (uvSlot == null)
return true;
var edges = owner.GetEdges(uvSlot.slotReference).ToList();
return edges.Count == 0;
}
}
}