您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
88 行
4.1 KiB
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;
|
|
}
|
|
}
|
|
}
|