您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
250 行
9.2 KiB
250 行
9.2 KiB
using UnityEngine.Graphing;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace UnityEngine.MaterialGraph
|
|
{
|
|
[Title("UV/Tri-Planar Mapping")]
|
|
public class UVTriPlanar : FunctionNInNOut, IGeneratesFunction, IMayRequireNormal, IMayRequireWorldPosition
|
|
{
|
|
private int slot0, slot1, slot2, slot3, slot4, slot5, slot6 = 0;
|
|
|
|
private string slot0Name = "texRef";
|
|
private string slot1Name = "tileFactor";
|
|
private string slot2Name = "blendFactor";
|
|
private string slot4Name = "normalRef";
|
|
private string slot5Name = "posRef";
|
|
private string slot6Name = "outputRef";
|
|
|
|
protected override string GetFunctionName()
|
|
{
|
|
return "unity_triplanar_" + precision;
|
|
}
|
|
|
|
public UVTriPlanar()
|
|
{
|
|
name = "UVTriPlanar";
|
|
|
|
slot0 = AddSlot("Texture", slot0Name, Graphing.SlotType.Input, SlotValueType.Sampler2D, Vector4.zero);
|
|
slot1 = AddSlot("Tile", slot1Name, Graphing.SlotType.Input, SlotValueType.Vector1, Vector4.zero);
|
|
slot2 = AddSlot("Blend", slot2Name, Graphing.SlotType.Input, SlotValueType.Vector1, Vector4.zero);
|
|
slot4 = AddSlot("Normals", slot4Name, Graphing.SlotType.Input, SlotValueType.Vector3, Vector3.one);
|
|
slot5 = AddSlot("Position", slot5Name, Graphing.SlotType.Input, SlotValueType.Vector3, Vector3.one);
|
|
slot6 = AddSlot("RGBA ", slot6Name, Graphing.SlotType.Output, SlotValueType.Vector4, Vector4.zero);
|
|
|
|
UpdateNodeAfterDeserialization();
|
|
}
|
|
|
|
public override bool hasPreview
|
|
{
|
|
get { return true; }
|
|
}
|
|
|
|
public override PreviewMode previewMode
|
|
{
|
|
get
|
|
{
|
|
return PreviewMode.Preview3D;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//TODO:Externalize
|
|
//Reference code from:http://www.chilliant.com/rgb2hsv.html
|
|
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
|
|
{
|
|
var outputString = new ShaderGenerator();
|
|
|
|
// outputString.AddShaderChunk(GetFunctionPrototype("arg1", "arg2", "arg3", samplerName), false);
|
|
outputString.AddShaderChunk(GetFunctionPrototype(), false);
|
|
outputString.Indent();
|
|
outputString.AddShaderChunk("{", false);
|
|
// create UVs from position
|
|
outputString.AddShaderChunk("float3 uvs = " + slot5Name + "*" + slot1Name + ";", false);
|
|
|
|
// use absolute value of normal as texture weights
|
|
outputString.AddShaderChunk("half3 blend = pow(abs(" + slot4Name + ")," + slot2Name + ");", false);
|
|
|
|
// make sure the weights sum up to 1 (divide by sum of x+y+z)
|
|
outputString.AddShaderChunk("blend /= dot(blend, 1.0);", false);
|
|
|
|
// read the three texture projections, for x,y,z axes
|
|
outputString.AddShaderChunk("float4 cx = " + "tex2D(" + slot0Name + ", uvs.yz);", false);
|
|
outputString.AddShaderChunk("float4 cy = " + "tex2D(" + slot0Name + ", uvs.xz);", false);
|
|
outputString.AddShaderChunk("float4 cz = " + "tex2D(" + slot0Name + ", uvs.xy);", false);
|
|
|
|
// blend the textures based on weights
|
|
outputString.AddShaderChunk(slot6Name + " = cx * blend.x + cy * blend.y + cz * blend.z;", false);
|
|
|
|
outputString.Deindent();
|
|
outputString.AddShaderChunk("}", false);
|
|
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
|
|
}
|
|
|
|
|
|
|
|
|
|
//prevent validation errors when a sampler2D input is missing
|
|
//use on any input requiring a TextureAssetNode
|
|
public override void ValidateNode()
|
|
{
|
|
base.ValidateNode();
|
|
var slot = FindInputSlot<MaterialSlot>(0);
|
|
if (slot == null)
|
|
return;
|
|
|
|
var edges = owner.GetEdges(slot.slotReference).ToList();
|
|
hasError |= edges.Count == 0;
|
|
}
|
|
|
|
public bool RequiresNormal()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public bool RequiresWorldPosition()
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////// TEXTURE2D version below. Works fine, but the master nodes don't jive with it //////////////////////////
|
|
|
|
|
|
/*
|
|
|
|
namespace UnityEngine.MaterialGraph
|
|
{
|
|
[Title("UV/Tri-Planar Mapping")]
|
|
public class UVTriPlanar : FunctionNInNOut, IGeneratesFunction, IMayRequireNormal, IMayRequireWorldPosition
|
|
{
|
|
private int slot0, slot1, slot2, slot3, slot4, slot5, slot6 = 0;
|
|
|
|
private string slot0Name = "texRef";
|
|
private string slot1Name = "tileFactor";
|
|
private string slot2Name = "blendFactor";
|
|
private string slot3Name = "samplerRef";
|
|
private string slot4Name = "normalRef";
|
|
private string slot5Name = "posRef";
|
|
private string slot6Name = "outputRef";
|
|
|
|
protected override string GetFunctionName()
|
|
{
|
|
return "unity_triplanar_" + precision;
|
|
}
|
|
|
|
public UVTriPlanar()
|
|
{
|
|
name = "UVTriPlanar";
|
|
|
|
slot0 = AddSlot("Texture", slot0Name, Graphing.SlotType.Input, SlotValueType.Texture2D, Vector4.zero);
|
|
slot1 = AddSlot("Tile", slot1Name, Graphing.SlotType.Input, SlotValueType.Vector1, Vector4.zero);
|
|
slot2 = AddSlot("Blend", slot2Name, Graphing.SlotType.Input, SlotValueType.Vector1, Vector4.zero);
|
|
slot3 = AddSlot("Sampler", slot3Name, Graphing.SlotType.Input, SlotValueType.SamplerState, Vector4.zero);
|
|
slot4 = AddSlot("Normals", slot4Name, Graphing.SlotType.Input, SlotValueType.Vector3, Vector3.one);
|
|
slot5 = AddSlot("Position", slot5Name, Graphing.SlotType.Input, SlotValueType.Vector3, Vector3.one);
|
|
slot6 = AddSlot("RGBA ", slot6Name, Graphing.SlotType.Output, SlotValueType.Vector4, Vector4.zero);
|
|
|
|
UpdateNodeAfterDeserialization();
|
|
}
|
|
|
|
public override bool hasPreview
|
|
{
|
|
get { return true; }
|
|
}
|
|
|
|
public override PreviewMode previewMode
|
|
{
|
|
get
|
|
{
|
|
return PreviewMode.Preview3D;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//TODO:Externalize
|
|
//Reference code from:http://www.chilliant.com/rgb2hsv.html
|
|
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
|
|
{
|
|
var outputString = new ShaderGenerator();
|
|
//Sampler input
|
|
var samplerName = GetSamplerInput(3);
|
|
outputString.AddShaderChunk("#ifdef UNITY_COMPILER_HLSL", false);
|
|
|
|
// outputString.AddShaderChunk(GetFunctionPrototype("arg1", "arg2", "arg3", samplerName), false);
|
|
outputString.AddShaderChunk(GetFunctionPrototype(), false);
|
|
outputString.Indent();
|
|
outputString.AddShaderChunk("{", false);
|
|
// create UVs from position
|
|
outputString.AddShaderChunk("float3 uvs = " + slot5Name + "*" + slot1Name + ";", false);
|
|
|
|
// use absolute value of normal as texture weights
|
|
outputString.AddShaderChunk("half3 blend = pow(abs(" + slot4Name + ")," + slot2Name + ");", false);
|
|
|
|
// make sure the weights sum up to 1 (divide by sum of x+y+z)
|
|
outputString.AddShaderChunk("blend /= dot(blend, 1.0);", false);
|
|
|
|
// read the three texture projections, for x,y,z axes
|
|
outputString.AddShaderChunk("float4 cx = " + slot0Name + ".Sample(" + slot3Name + ", uvs.yz);", false);
|
|
outputString.AddShaderChunk("float4 cy = " + slot0Name + ".Sample(" + slot3Name + ", uvs.xz);", false);
|
|
outputString.AddShaderChunk("float4 cz = " + slot0Name + ".Sample(" + slot3Name + ", uvs.xy);", false);
|
|
|
|
|
|
// blend the textures based on weights
|
|
outputString.AddShaderChunk(slot6Name + " = cx * blend.x + cy * blend.y + cz * blend.z;", false);
|
|
|
|
//outputString.AddShaderChunk("return " + "c;", false);
|
|
outputString.Deindent();
|
|
outputString.AddShaderChunk("}", false);
|
|
outputString.AddShaderChunk("#endif", true);
|
|
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
|
|
}
|
|
|
|
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
|
|
{
|
|
|
|
//Sampler input slot
|
|
|
|
base.GeneratePropertyUsages(visitor, generationMode);
|
|
var samplerSlot = FindInputSlot<MaterialSlot>(slot3);
|
|
|
|
if (samplerSlot != null)
|
|
{
|
|
var samplerName = GetSamplerInput(slot3);
|
|
|
|
visitor.AddShaderChunk("#ifdef UNITY_COMPILER_HLSL", false);
|
|
visitor.AddShaderChunk("SamplerState " + samplerName + ";", true);
|
|
visitor.AddShaderChunk("#endif", false);
|
|
}
|
|
}
|
|
|
|
|
|
//prevent validation errors when a sampler2D input is missing
|
|
//use on any input requiring a TextureAssetNode
|
|
public override void ValidateNode()
|
|
{
|
|
base.ValidateNode();
|
|
var slot = FindInputSlot<MaterialSlot>(0);
|
|
if (slot == null)
|
|
return;
|
|
|
|
var edges = owner.GetEdges(slot.slotReference).ToList();
|
|
hasError |= edges.Count == 0;
|
|
}
|
|
|
|
public bool RequiresNormal()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public bool RequiresWorldPosition()
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
*/
|